Ich habe angefangen, mit Git zu arbeiten und bin dabei auf die Begriffe "Upstream" und "Downstream" gestoßen. Ich habe diese Begriffe schon einmal gesehen, aber nie ganz verstanden. Was bedeuten diese Begriffe im Zusammenhang mit SCMs ( Software-Konfigurationsmanagement Tools) und Quellcode?
Antworten
Zu viele Anzeigen?In Bezug auf die Versionskontrolle sind Sie nachgelagert, wenn Sie aus einem Repository kopieren (klonen, auschecken usw.). Die Informationen fließen "stromabwärts" zu Ihnen.
Wenn man Änderungen vornimmt, möchte man sie normalerweise "upstream" zurückschicken, damit sie in das Repository gelangen, so dass jeder, der aus derselben Quelle schöpft, mit denselben Änderungen arbeitet. Dies ist eher eine soziale Frage, wie jeder seine Arbeit koordinieren kann, als eine technische Anforderung der Versionsverwaltung. Sie wollen Ihre Änderungen in das Hauptprojekt einfließen lassen, damit Sie keine abweichenden Entwicklungslinien verfolgen müssen.
Manchmal liest man von Paket- oder Versionsverwaltern (die Leute, nicht das Tool), die davon sprechen, dass sie Änderungen an "Upstream" weitergeben. Das bedeutet in der Regel, dass sie die ursprünglichen Quellen anpassen mussten, damit sie ein Paket für ihr System erstellen konnten. Sie wollen diese Änderungen nicht immer wieder machen, wenn sie sie also "upstream" an die Originalquelle schicken, sollten sie sich in der nächsten Version nicht mit dem gleichen Problem auseinandersetzen müssen.
Wenn Sie lesen in git tag
Manpage :
Ein wichtiger Aspekt von Git ist, dass es verteilt ist, und verteilt zu sein bedeutet, dass es kein inhärentes "Upstream" oder "Downstream" im System gibt.
das einfach bedeutet, es gibt keine absolut Upstream-Repo oder Downstream-Repo.
Diese Begriffe sind immer relativ zwischen zwei Repos und hängen von der Art des Datenflusses ab:
Wenn "deinRepo" "anderesRepo" als ein entferntes deklariert hat, dann :
- Sie sind Ziehen von stromaufwärts "otherRepo" ("otherRepo" ist "vorgelagert から Sie", und Sie sind "stromabwärts für otherRepo").
- Sie sind stromaufwärts schieben ("otherRepo" ist immer noch "upstream", wohin die Informationen jetzt zurückgehen).
Beachten Sie das "von" und "für": Sie sind nicht nur "stromabwärts", Sie sind "stromaufwärts". von/für ", daher der relative Aspekt.
Der Haken an DVCS (Distributed Version Control System) ist, dass man keine Ahnung hat, was Downstream eigentlich ist, außer dem eigenen Repository im Verhältnis zu den deklarierten Remote-Repos.
- Sie wissen, was Upstream ist (die Repos, von denen Sie abrufen oder in die Sie pushen)
- Sie wissen nicht, woraus der Downstream besteht (die anderen Repos ziehen von oder schieben zu Ihr Repo ).
Im Grunde genommen:
Im Sinne von " Datenfluss ", befindet sich Ihr Projektarchiv am Ende ("downstream") eines Flusses, der von vorgelagerten Projektarchiven kommt ("pull from") und zurück zu (demselben oder anderen) vorgelagerten Projektarchiven geht ("push to").
Eine Illustration finden Sie in der git-rebase
Manpage mit dem Absatz "WIEDERHERSTELLUNG VON UPSTREAM REBASE":
Das heißt, Sie sind von einem "Upstream"-Repositorium ziehen, in dem ein Rebase stattgefunden hat und Sie (das "Downstream"-Repositorium) haben die Folgen zu tragen (viele doppelte Commits, weil der Zweig, der upstream rebased wurde, die Commits des gleichen Zweigs, den Sie lokal haben, neu erstellt hat).
Das ist schlecht, denn für ein "Upstream"-Repositorium kann es viele Downstream-Repos (d.h. Repos, die vom Upstream-Repos mit dem rebased Branch ziehen), die alle potentiell mit den doppelten Commits umgehen müssen.
Wiederum in Analogie zum "Datenfluss" kann in einem DVCS ein fehlerhafter Befehl "stromaufwärts" eine " sich ausbreitende Wirkung " stromabwärts.
Hinweis: Dies ist nicht auf Daten beschränkt.
Sie gilt auch für Parameter da Git-Befehle (wie die "Porzellan"-Befehle) oft intern andere Git-Befehle (die "Klempner"-Befehle) aufrufen. Siehe rev-parse
Manpage :
Viele git porcelainish Befehle nehmen eine Mischung aus Flags (d.h. Parametern, die mit einem Bindestrich beginnen '
-
') und Parameter, die für die zugrunde liegendegit rev-list
Befehl, den sie intern verwenden, und Flaggen und Parameter für die anderen Befehle, die sie im Anschluss an diegit rev-list
. Dieser Befehl wird verwendet, um zwischen ihnen zu unterscheiden.
Upstream (in Bezug auf) Tracking
Der Begriff stromaufwärts hat auch eine eindeutige Bedeutung in Bezug auf die GIT-Werkzeuge, insbesondere im Vergleich zu Verfolgung
Zum Beispiel:
$git rev-list --count --left-right "@{upstream}"...HEAD >4 12
gibt (den letzten zwischengespeicherten Wert) die Anzahl der Commits hinter (links) und vor (rechts) Ihrem aktuellen Arbeitszweig aus, relativ zum ( wenn überhaupt ) derzeitige Verfolgung der entfernten Niederlassung für diese Zweigstelle. Andernfalls wird eine Fehlermeldung ausgegeben:
>error: No upstream branch found for ''
- Wie bereits erwähnt, können Sie eine beliebige Anzahl von Remotes für ein lokales Repository haben, z.B. wenn Sie ein Repository von github forken und dann einen "Pull Request" erstellen, haben Sie mit Sicherheit mindestens zwei:
origin
(Ihr forked repo auf github) undupstream
(das Repo auf Github, von dem Sie sich abgespalten haben). Diese Namen sind einfach austauschbar, nur die "git@..."-URL identifiziert sie.
Ihr
.git/config
liest:[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = git@github.com:myusername/reponame.git [remote "upstream"] fetch = +refs/heads/*:refs/remotes/upstream/* url = git@github.com:authorname/reponame.git
- Andererseits, @{upstream} Die Bedeutung des Begriffs "GIT" ist einzigartig:
es ist der Zweig (falls vorhanden) am besagte Fernbedienung". die die Entwicklung der 'aktueller Zweig' zu Ihrem 'Lokales Repository' .
Es ist der Zweig, den Sie abrufen/aus dem Sie ziehen, wenn Sie eine einfache
git fetch
/git pull
, ohne Argumente.
Nehmen wir an, Sie wollen den entfernten Zweig origin/master als Tracking-Zweig für den lokalen Master-Zweig, den Sie ausgecheckt haben, festlegen. Geben Sie einfach :
$ git branch --set-upstream master origin/master > Branch master set up to track remote branch master from origin.
Dies fügt 2 Parameter in
.git/config
:[branch "master"] remote = origin merge = refs/heads/master
Versuchen Sie es jetzt (vorausgesetzt, der 'upstream'-Zweig hat einen 'dev'-Zweig)
$ git branch --set-upstream master upstream/dev > Branch master set up to track remote branch dev from upstream.
.git/config
lautet jetzt:[branch "master"] remote = upstream merge = refs/heads/dev
-u --set-upstream
Fügen Sie für jeden Zweig, der auf dem neuesten Stand ist oder erfolgreich gepusht wurde vorgelagert (Verfolgung) Referenz, die von dem argumentlosen git-pull(1) und anderen Befehlen verwendet wird. Für weitere Informationen, siehe
branch.<name>.merge
in git-config(1).
git-config(1)
Handbuch Seite :branch.<name>.merge
Definiert, zusammen mit
branch.<name>.remote
die stromaufwärts Zweig für den angegebenen Zweig. Sie teilt git fetch/git pull/git rebase mit, welcher Zweig zusammengeführt werden soll und kann auch git push beeinflussen (siehe push.default). \ (...)branch.<name>.remote
In der Verzweigung < Name > wird git fetch und git push mitgeteilt, von welchem entfernten Standort geholt bzw. wohin gepusht werden soll. Standardmäßig wird origin verwendet, wenn kein Remote konfiguriert ist. origin wird auch verwendet, wenn Sie sich in keinem Branch befinden.
Upstream und Push (Gotcha)
einen Blick auf git-config(1)
Handbuch Seite
git config --global push.default upstream git config --global push.default tracking (deprecated)
Dies soll verhindern, dass Sie versehentlich Zweige verschieben, die Sie noch nicht verschieben wollen.
Das ist ein wenig informelle Terminologie.
Für Git ist jedes andere Repository nur ein Remote-Repository.
Im Allgemeinen ist der Upstream der Ort, von dem aus Sie geklont haben (der Ursprung). Downstream ist jedes Projekt, das Ihre Arbeit mit anderen Arbeiten integriert.
Die Begriffe sind nicht auf Git-Repositories beschränkt.
Ubuntu ist zum Beispiel ein Debian-Derivat, also ist Debian der Upstream für Ubuntu.
Upstream als schädlich bezeichnet
Es gibt leider noch eine andere Verwendung von "upstream", die in den anderen Antworten nicht angesprochen wird, nämlich die Eltern-Kind-Beziehung von Commits innerhalb eines Repo. Scott Chacon in der Pro Git Buch ist dafür besonders anfällig, und die Ergebnisse sind bedauerlich. Ahmen Sie diese Art zu sprechen nicht nach.
Zum Beispiel sagt er über eine Verschmelzung, die zu einem schnellen Vorlauf führt, dass dies geschieht, weil
die Übergabe, auf die der Zweig verweist, in den Sie eingebunden haben, direkt vor dem Commit, an dem Sie gerade arbeiten
Er will sagen, dass Commit B das einzige Kind des einzigen Kindes von ... des einzigen Kindes von Commit A ist. Um B mit A zu verschmelzen, genügt es also, die Referenz A so zu verschieben, dass sie auf Commit B zeigt. Warum diese Richtung "stromaufwärts" und nicht "stromabwärts" genannt werden sollte, oder warum die Geometrie eines solchen reinen Geradengraphen "direkt stromaufwärts" beschrieben werden sollte, ist völlig unklar und wahrscheinlich willkürlich. (Die Manpage für git-merge
erklärt diese Beziehung viel besser, wenn es heißt, dass "der aktuelle Zweigkopf ein Vorfahre der benannten Übergabe ist." Das ist genau das, was Chacon hätte sagen sollen.)
Tatsächlich scheint Chacon selbst später "downstream" zu verwenden, um genau das Gleiche zu meinen, wenn er davon spricht, alle Child-Commits eines gelöschten Commits neu zu schreiben:
Sie müssen alle Commits nach 6df76 neu schreiben, um die diese Datei aus Ihrem Git-Verlauf zu entfernen
Im Grunde genommen scheint er keine klare Vorstellung davon zu haben, was er mit "Upstream" und "Downstream" meint, wenn er sich auf die Geschichte der Übertragungen im Laufe der Zeit bezieht. Diese Verwendung ist also informell und sollte nicht gefördert werden, da sie einfach verwirrend ist.
Es ist völlig klar, dass jeder Commit (außer einem) mindestens einen Elternteil hat und dass die Eltern von Eltern somit Vorfahren sind; und in der anderen Richtung haben Commits Kinder und Nachkommen. Das ist akzeptierte Terminologie und beschreibt die Richtung des Graphen eindeutig, also ist das die richtige Art zu sprechen, wenn Sie beschreiben wollen, wie Commits innerhalb der Graphengeometrie eines Repos miteinander in Beziehung stehen. Verwenden Sie "Upstream" oder "Downstream" in dieser Situation nicht zu locker.
[Zusätzliche Anmerkung: Ich habe über die Beziehung zwischen dem ersten Chacon-Satz, den ich oben zitiert habe, und dem git-merge
Manpage, und mir kommt der Gedanke, dass ersteres auf einem Missverständnis des letzteren beruhen könnte. Die Handbuchseite beschreibt eine Situation, in der die Verwendung von "Upstream" legitim ist: Schnelles Vorspulen geschieht oft, wenn "Sie ein Upstream-Repository verfolgen, keine lokalen Änderungen vorgenommen haben und nun auf eine neuere Upstream-Revision aktualisieren wollen." Vielleicht hat Chacon also "upstream" benutzt, weil er es hier in der Manpage gesehen hat. Aber in der Handbuchseite gibt es ein entferntes Repository; in Chacons zitiertem Beispiel für Fast-Forwarding gibt es kein entferntes Repository, nur ein paar lokal erstellte Zweige].
- See previous answers
- Weitere Antworten anzeigen