Close

Git Forks und Upstreams: Anleitung und ein cooler Tipp

Porträtfoto von Nicola Paolucci
NICOLA PAOLUCCI

Developer Advocate


Wenn du Projekte forkst, um eigene Änderungen vorzunehmen, kannst du ganz einfach deine eigenen Beiträge integrieren. Wenn du diese Änderungen jedoch nicht upstream – also an das übergeordnete Repository – zurücksendest, besteht die Gefahr, dass du den Überblick verlierst, was zu abweichenden Zeilen in deinem Repository führen kann. Um sicherzustellen, dass alle Beitragenden vom selben Ort schöpfen, musst du einige Prinzipien kennen, wie git forking mit git upstream interagiert. In diesem Blog stelle ich dir die Grundlagen und die Fallstricke vor und gebe dir auch einen coolen Tipp, um dir einen Vorsprung zu verschaffen.

Git upstream: Auf dem Laufenden bleiben und Beiträge leisten


Zunächst wird ein allgemeiner Set-up und der grundlegende Workflow zur Interaktion mit upstream-Repositorys vorgestellt.

Üblicherweise richtet man ein origin- und ein upstream-Remote-Repository ein. Letzteres ist das Tor zu deinem Projekt und die Quelle der Wahrheit, nämlich der Ort für deine Codebeiträge.

Zunächst solltest du dich vergewissern, dass du ein Remote-Repository für das upstream-Repository eingerichtet und den origin auch nicht vergessen hast:

git remote -v

origin  git@bitbucket.org:my-user/some-project.git (fetch)
origin  git@bitbucket.org:my-user/some-project.git (push)

Wenn du keinen upstream hast, kannst du ihn einfach mit dem remote-Befehl hinzufügen:

git remote add upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git
Datenbanken
Zugehöriges Material

Verschieben eines vollständigen Git-Repositorys

Bitbucket-Logo
Lösung anzeigen

Git kennenlernen mit Bitbucket Cloud

Überprüfe, ob das Remote-Repository korrekt hinzugefügt wurde:

git remote -v

origin    git@bitbucket.org:my-user/some-project.git (fetch)
origin    git@bitbucket.org:my-user/some-project.git (push)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (fetch)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (push)

Jetzt kannst du die neuesten Änderungen des upstream-Repositorys mit fetch abrufen. Wiederhole diesen Vorgang für jedes Update:

(Wenn das Projekt über Tags verfügt, die nicht in den Main-Branch gemergt sind, solltest du außerdem Folgendes eingeben: git fetch upstream --tags)

git fetch upstream

Im Allgemeinen möchte man, dass der lokale main-Branch ein möglichst identisches Spiegelbild des upstream-main-Branches ist, und verlagert daher die Code-Arbeit (für Pull-Anfragen) auf den Feature-Branch.

An diesem Punkt ist es unwichtig, ob du merge oder rebase verwendet hast. Das Ergebnis ist normalerweise dasselbe. Nehmen wir hier merge:

git checkout main
git merge upstream/main

Wenn du deine Arbeit für die upstream-Maintainer freigeben willst, von denen du den main branchst, erstellst du einen Feature-Branch und pushst deinen Code, sobald du zufrieden damit bist, in dein Remote-Repository.

Du kannst stattdessen auch rebase verwenden. Stelle dann mit merge sicher, dass die Commits des Upstream sauber sind (und im Idealfall als eine Reihe von Commits vorliegen):

git checkout -b feature-x

#some work and some commits happen
#some time passes

git fetch upstream
git rebase upstream/main

Mit git fork veröffentlichen


Veröffentliche deinen Code anschließend in deinem Remote-Fork. Das geht mit einem einfachen push-Befehl:

git push origin feature-x
git push -f origin feature-x

Ich persönlich versuche meinen Verlauf möglichst sauber zu halten und bevorzuge daher die dritte Option. Aber verschiedene Teams haben natürlich verschiedene Workflows. Hinweis: Du solltest das nur mit deinem eigenen Fork tun. Verläufe gemeinsam genutzter Repositorys und Branches solltest du AUF KEINEN FALL umarbeiten.

Tipp des Tages: Anzeige der Anzahl voraus-/dahinterliegender Commits


Nach dem Ausführen von fetch zeigt git status an, wie viele Commits du vor oder hinter dem synchronisierten remote-Branch liegst. Wäre es nicht toll, wenn du diese Informationen zusammen bei der Befehlseingabe sehen würdest? Das dachte ich mir auch. Also habe ich mit bash herumhantiert und eine neue Lösung entwickelt.

So wird dies nach der Konfiguration in deiner Eingabeaufforderung aussehen:

nick-macbook-air:~/dev/projects/stash[1|94]$

Und mit nur einer Funktion kannst du dein .bashrc oder etwas Ähnliches hinzufügen:

function ahead_behind {
    curr_branch=$(git rev-parse --abbrev-ref HEAD);
    curr_remote=$(git config branch.$curr_branch.remote);
    curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
    git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
}
export PS1="\h:\w[\$(ahead_behind)]$"

Funktionsweise im Detail

Die folgende Beschreibung ist für alle, die gerne eine detailliertere Erklärung hätten.

Wir erhalten den symbolischen Namen für den aktuellen HEAD (also den aktuellen Branch):

curr_branch=$(git rev-parse --abbrev-ref HEAD);

Wir erhalten den Remote Branch, auf den der aktuelle Branch verweist:

curr_remote=$(git config branch.$curr_branch.remote);

Wir erhalten den Branch, in den dieses Remote gemergt werden soll (mit einem billigen Unix-Trick zum Verwerfen von allem bis inklusive dem letzten Vorwärtsschrägstrich /):

curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);

Nun haben wir alles, was wir benötigen, um die Commits zu zählen, die wir in der Synchronisierung voraus sind oder zurückliegen:

git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';

Mit dem uralten Unix-Befehl tr konvertieren wir TAB zu einem Trennzeichen |.

Erste Schritte mit git upstream


Dies ist ein grundlegender Überblick zu git upstream – das Einrichten von git upstream, das Erstellen eines neuen Branches, das Erfassen von Änderungen, das Veröffentlichen mit git fork und ein netter Tipp, wie du siehst, wie viele Commits du vor oder hinter dem Remote-Branch liegst.

Zur Erleichterung aller Entwickler bietet Bitbucket Data Center außerdem die Fork-Synchronisierung, sodass die Aktualisierung von Forks hinfällig wird. Und Bitbucket Cloud ermöglicht die Synchronisierung in nur einem Schritt – probiere es aus!

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Diesen Artikel teilen
Nächstes Thema

Lesenswert

Füge diese Ressourcen deinen Lesezeichen hinzu, um mehr über DevOps-Teams und fortlaufende Updates zu DevOps bei Atlassian zu erfahren.

Mitarbeiter arbeiten mit unzähligen Tools zusammen

Bitbucket-Blog

Abbildung: DevOps

DevOps-Lernpfad

Demo Den: Feature-Demos mit Atlassian-Experten

So funktioniert Bitbucket Cloud mit Atlassian Open DevOps

Melde dich für unseren DevOps-Newsletter an

Thank you for signing up