Definicja „downstream” i „upstream”

901

Zacząłem grać z Git i spotkałem się z terminami „upstream” i „downstream”. Widziałem je wcześniej, ale nigdy nie zrozumiałem ich w pełni. Co oznaczają te terminy w kontekście SCM ( narzędzia do zarządzania konfiguracją oprogramowania ) i kodu źródłowego?

brendan
źródło
13
Istnieją dwa różne konteksty dla upstream / downstream w git: piloty i czas / historia. Upstream / downstream w odniesieniu do pilotów jest taki, że repozytorium downstream będzie pobierać z repozytorium upstream (zmiany będą przebiegać naturalnie downstream). Upstream / downstream w odniesieniu do czasu / historii może być mylące, ponieważ upstream w czasie oznacza downstream w historii i odwrotnie (terminologia genealogiczna działa tutaj znacznie lepiej - rodzic / przodek / dziecko / potomek).
charlesreid1
6
Powiązane: Co oznacza „upstream”? w OS
kenorb

Odpowiedzi:

703

Pod względem kontroli źródła, jesteś „ za ” przy kopiowaniu (klon, kasę, etc) z repozytorium. Informacje płynęły do ​​Ciebie „poniżej”.

Kiedy wprowadzasz zmiany, zwykle chcesz odesłać je z powrotem „w górę ”, aby trafiły do ​​tego repozytorium, aby wszyscy pobierający z tego samego źródła pracowali z tymi samymi zmianami. Jest to głównie kwestia społeczna dotycząca tego, jak każdy może koordynować swoją pracę, a nie techniczny wymóg kontroli źródła. Chcesz wprowadzić zmiany do głównego projektu, aby nie śledzić rozbieżnych linii rozwoju.

Czasami przeczytasz o menedżerach pakietów lub wydaniach (ludzie, nie narzędzie) mówiące o przesyłaniu zmian do „upstream”. Zazwyczaj oznacza to, że musieli dostosować oryginalne źródła, aby mogli stworzyć pakiet dla swojego systemu. Nie chcą ciągle wprowadzać tych zmian, więc jeśli wyślą je „w górę” do oryginalnego źródła, nie powinni mieć do czynienia z tym samym problemem w następnej wersji.

Brian D. Foy
źródło
115
„Pobieranie” i „przesyłanie” są czasownikami. „Upstream” i „downstream” opisują pozycję względną.
brian d foy,
2
Powiedziałbym, że upstream i downstream są przymiotnikami
Crt
8
Są przymiotnikami, gdy są używane jako modyfikatory, ale te terminy są często używane jako rzeczowniki.
brian d foy,
2
Słowa @MycrofD mogą być używane jako przymiotniki i rzeczowniki w zależności od kontekstu
reggaeguitar
1
Jest to głównie kwestia społeczna, a nie wymóg techniczny . Więc dlaczego nie jest to opcja -ujak git push --set-upstream origin masterjeśli nie jest to wymóg techniczny ? Możemy push -u originlub nie push origin, więc jest to wymóg techniczny. Ale jaka jest różnica?
Zielony
249

Kiedy czytasz na git tagstronie podręcznika :

Jednym ważnym aspektem git jest to, że jest dystrybuowany, a jego dystrybucja w dużej mierze oznacza, że ​​w systemie nie ma nieodłącznego „upstream” lub „downstream”.

, oznacza to po prostu, że nie ma absolutnego repozytorium upstream ani repozytorium downstream.
Te pojęcia są zawsze względne między dwoma repozytoriami i zależą od przepływu danych:

Jeśli „twojeRepo” zadeklarowało „inneRepo” jako zdalne, to :

  • jesteś wyciągając z upstream „otherRepo” ( „otherRepo” jest „upstream z wami”, i jesteś „downstream dla otherRepo”).
  • jesteś pchanie się do początkowych ( „otherRepo” jest nadal „pod prąd”, gdzie informacja teraz sięga).

Zwróć uwagę na „od” i „dla”: nie jesteś tylko „downstream”, jesteś „downstream z / for ”, stąd względny aspekt.


Twórczość DVCS (Distributed Version Control System) polega na tym, że nie masz pojęcia, czym właściwie jest downstream, oprócz własnego repozytorium w stosunku do zadeklarowanych repozytoriów zdalnych.

  • wiesz, czym jest upstream (repozytoria, z których pobierasz lub do których dążysz)
  • nie wiesz, z czego składa się downstream (inne repozytoria wyciągają lub popychają do twojego repozytorium ).

Gruntownie:

Jeśli chodzi o „ przepływ danych ”, Twoje repozytorium znajduje się na dole („downstream”) przepływu pochodzącego z repozytoriów upstream („pull from”) i wraca do (tego samego lub innych) repozytoriów upstream („push to” ).


Możesz zobaczyć ilustrację na git-rebasestronie podręcznika z akapitem „ODZYSKIWANIE Z REBASE UPSTREAM”:

Oznacza to, że wyciągasz z repozytorium „upstream”, w którym miał miejsce rebase , a ty (repozytorium „downstream”) utkniesz z konsekwencją (wiele duplikatów zatwierdzeń, ponieważ gałąź rebased upstream odtworzyła zatwierdzenia tej samej gałęzi, którą ty lokalnie).

Jest to złe, ponieważ dla jednego repozytorium „upstream” może istnieć wiele repozytoriów downstream (tj. Repozytoria ściągające z repozytorium upstream, z rebased gałąź), z których wszystkie potencjalnie mają do czynienia z duplikatami commits.

Ponownie, z analogią „przepływu danych” w DVCS, jedno złe polecenie „w górę” może mieć „ efekt tętnienia ” w dół.


Uwaga: nie ogranicza się to do danych.
Dotyczy to również parametrów , ponieważ polecenia git (takie jak „porcelanowe”) często wywołują wewnętrznie inne polecenia git („hydrauliczne”). Zobacz rev-parsestronę podręcznika :

Wiele porcelanowych poleceń git przyjmuje mieszaninę flag (tj. Parametry zaczynające się od myślnika -) i parametry przeznaczone dla podstawowego git rev-listpolecenia, z którego korzystają wewnętrznie, oraz flagi i parametry dla innych poleceń, z których korzystają dalejgit rev-list . To polecenie służy do rozróżnienia między nimi.

VonC
źródło
15
Ci wyciągnąć z Upstream, i naciskać na prąd. przepychanie do downstream brzmi dla mnie bardzo źle
knittl
1
@knittl: masz rację. Przeredagowałem swoją odpowiedź, aby lepiej zilustrować rolę repozytorium „upstream” w stosunku do twojego repozytorium lokalnego (i „downstream”).
VonC
85

Śledzenie w górę (w powiązaniu z)

Termin „ upstream” ma również pewne jednoznaczne znaczenie, jeśli chodzi o zestaw narzędzi GIT, szczególnie w odniesieniu do śledzenia

Na przykład :

   $git rev-list --count --left-right "@{upstream}"...HEAD
   >4   12

wypisze (ostatnią wartość z pamięci podręcznej) liczbę zatwierdzeń za (po lewej) i przed (po prawej) bieżącej działającej gałęzi, w stosunku do ( jeśli w ogóle ) aktualnie śledzącej gałęzi zdalnej dla tej gałęzi lokalnej. W przeciwnym razie wydrukuje komunikat o błędzie:

    >error: No upstream branch found for ''
  • Jak już powiedziano, możesz mieć dowolną liczbę pilotów dla jednego lokalnego repozytorium, na przykład, jeśli rozwidlisz repozytorium z github, a następnie wydasz „żądanie ściągnięcia”, z pewnością masz co najmniej dwa: origin(twoje rozwidlone repo na github) i upstream(repo na github, z którego rozwidliłeś się). To tylko wymienne nazwy, tylko adres URL „git @ ...” je identyfikuje.

Twoje .git/configczyta:

   [remote "origin"]
       fetch = +refs/heads/*:refs/remotes/origin/*
       url = [email protected]:myusername/reponame.git
   [remote "upstream"]
       fetch = +refs/heads/*:refs/remotes/upstream/*
       url = [email protected]:authorname/reponame.git
  • Z drugiej strony, @ {upstream} znaczenie dla GIT jest unikalne:

jest to „gałąź” (jeśli istnieje) na „wspomnianym zdalnym” , która śledzi „bieżącą gałąź” w „lokalnym repozytorium” .

Jest to gałąź, z której pobierasz / pobierasz za każdym razem, gdy wydajesz zwykły git fetch/ git pull, bez argumentów.

Powiedzmy, że chcesz ustawić źródło / gałąź zdalnej gałęzi jako gałąź śledzenia dla lokalnej gałęzi głównej, którą sprawdziłeś. Wystarczy wydać:

   $ git branch --set-upstream  master origin/master
   > Branch master set up to track remote branch master from origin.

Dodaje to 2 parametry w .git/config:

   [branch "master"]
       remote = origin
       merge = refs/heads/master

teraz spróbuj (pod warunkiem, że pilot „upstream” ma gałąź „dev”)

   $ git branch --set-upstream  master upstream/dev
   > Branch master set up to track remote branch dev from upstream.

.git/config teraz czyta:

   [branch "master"]
       remote = upstream
       merge = refs/heads/dev

git-push(1)Strona podręcznika :

   -u
   --set-upstream

Do każdej gałęzi, która jest aktualna lub została pomyślnie wysłana, dodaj referencję upstream (śledzenia) , używaną przez bez argumentów git-pull (1) i inne polecenia. Aby uzyskać więcej informacji, zobacz branch.<name>.mergew git-config (1).

git-config(1)Strona podręcznika :

   branch.<name>.merge

Definiuje razem z branch.<name>.remoteThe upstream oddział dla danego oddziału. Mówi git fetch / git pull / git rebase, która gałąź ma się scalić, a także może wpływać na git push (patrz push.default). \ (...)

   branch.<name>.remote

Znajdując się w gałęzi <name>, mówi git fetch i git push, którego pilota należy pobrać z / push do. Domyślnie jest inicjowane, jeśli nie skonfigurowano pilota. pochodzenie jest również używane, jeśli nie należysz do żadnej gałęzi.

Upstream and Push (Gotcha)

spójrz na git-config(1)stronę podręcznika

   git config --global push.default upstream
   git config --global push.default tracking  (deprecated)

Ma to na celu zapobieganie przypadkowym popchnięciom do gałęzi, których jeszcze nie jesteś gotowy do pchnięcia.

Peter Host
źródło
4
Fragment stanu git branch --helpna 2018 r .:As this option had confusing syntax, it is no longer supported. Please use --track or --set-upstream-to instead.
zezollo,
59

To trochę nieformalna terminologia.

Jeśli chodzi o Git, każde inne repozytorium jest tylko zdalne.

Ogólnie rzecz biorąc, w górę rzeki jest miejsce, z którego sklonowałeś (pochodzenie). Downstream to każdy projekt, który integruje twoją pracę z innymi pracami.

Warunki nie są ograniczone do repozytoriów Git.

Na przykład Ubuntu jest pochodną Debiana, więc Debian jest wcześniejszy dla Ubuntu.

hasen
źródło
51

Upstream nazywany szkodliwym

Istnieje, niestety, inne zastosowanie „upstream”, do którego inne odpowiedzi tutaj nie docierają, a mianowicie odniesienie się do relacji między rodzicami a dziećmi w ramach repo. Scott Chacon w książce Pro Git jest na to szczególnie podatny, a wyniki są niefortunne. Nie naśladuj tego sposobu mówienia.

Na przykład, mówi o fuzji powodującej szybkie przewijanie do przodu, że tak się dzieje, ponieważ

zatwierdzenie wskazane przez gałąź, w której się połączyłeś, było bezpośrednio przed zatwierdzeniem, w którym się znajdujesz

Chce powiedzieć, że zatwierdzenie B jest jedynym dzieckiem jedynego dziecka ... jedynego dziecka popełnienia A, więc aby połączyć B w A, wystarczy przesunąć odnośnik A, aby wskazał zatwierdzenie B. Dlaczego ten kierunek należy nazwać „upstream”, a nie „downstream”, lub dlaczego geometria takiego czysto prostego wykresu powinna być opisana jako „bezpośrednio upstream”, jest całkowicie niejasna i prawdopodobnie dowolna. (Strona man dla git-mergeo wiele lepiej wyjaśnia wyjaśnienie tego związku, gdy mówi, że „obecny szef oddziału jest przodkiem nazwanego zatwierdzenia.” To jest coś, co Chacon powinien powiedzieć.)

Rzeczywiście, sam Chacon wydaje się używać później słowa „downstream”, co znaczy dokładnie to samo, kiedy mówi o przepisaniu wszystkich potomnych zatwierdzeń usuniętego zatwierdzenia:

Musisz całkowicie przepisać wszystkie zatwierdzenia poniżej wersji 6df76, aby całkowicie usunąć ten plik z historii Git

Zasadniczo wydaje się, że nie ma żadnego jasnego pojęcia, co rozumie przez „upstream” i „downstream”, odnosząc się do historii zmian w czasie. Takie użycie jest zatem nieformalne i nie należy do niego zachęcać, ponieważ jest po prostu mylące.

Jest zupełnie jasne, że każde zatwierdzenie (oprócz jednego) ma co najmniej jednego rodzica, a zatem rodzice rodziców są przodkami; a w przeciwnym kierunku, zobowiązania mają dzieci i potomków. Jest to przyjęta terminologia i jednoznacznie opisuje kierunkowość wykresu, więc jest to sposób na rozmowę, gdy chcesz opisać, w jaki sposób zatwierdzenia odnoszą się do siebie w ramach geometrii wykresu repo. W tej sytuacji nie używaj luźno „upstream” lub „downstream”.

[Dodatkowa uwaga: zastanawiałem się nad związkiem między pierwszym cytowanym git-mergeprzeze mnie zdaniem Chacon a stroną podręcznika użytkownika i przychodzi mi do głowy, że to pierwsze może wynikać z nieporozumienia drugiego. Strona man opisuje dalej sytuację, w której użycie „upstream” jest uzasadnione: szybkie przewijanie często ma miejsce, gdy „śledzisz repozytorium upstream, nie dokonałeś żadnych lokalnych zmian, a teraz chcesz zaktualizować do nowszej weryfikacja wstępna. ” Być może więc Chacon użył „upstream”, ponieważ zobaczył to tutaj na stronie podręcznika. Ale na stronie podręcznika znajduje się zdalne repozytorium; w przytoczonym przykładzie Chakona szybkiego przewijania nie ma zdalnego repozytorium, tylko kilka lokalnie utworzonych gałęzi.]

matowy
źródło
14
Strona man git-rebase również cierpi z powodu tego przeładowania: zatwierdzenie, które jest sprawdzane przed zmianą bazy, nazywane jest „upstream”. To także mogło mieć wpływ na użycie Chakona.
poza
@outis dziwne - w dokumentacji git html gałąź wyewidencjonowana przed zmianą bazy jest określana jako <branch>.
Jesper Matthiesen
Słuszna uwaga. Przydałaby się gdzieś wspólna „git-terminologia”. Zwłaszcza dla początkujących (lub ppl przyczyniających się do git). Oszczędziłoby mi to czasu na przyzwyczajenie się do treści stron git man.
SebNag
@SebNag coś takiego? linuxacademy.com/blog/linux/git-terms-explained
reggaeguitar
1
Przybyłem tutaj z git-rebasedokumentacji, ponieważ byłem całkowicie zdezorientowany, dlaczego sędzia zatwierdzający miałby nazywać się tam „w górę” (w rzeczywistości wątpiłem w siebie, ponieważ nie znałem tej terminologii wcześniej). Dzięki @outis i @matt za uporządkowanie sprawy!
Borek Bernard