Stworzyłem lokalny oddział do testowania Solaris i Sun Studio. Następnie pchnąłem gałąź w górę. Po zatwierdzeniu zmiany i próbie wprowadzenia zmian:
$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin solaris
Dlaczego muszę w tym celu zrobić coś specjalnego?
Czy istnieje jakiś rozsądny przypadek użycia, w którym ktoś mógłby utworzyć <branch>
, przekazać <branch>
do pilota, a następnie twierdzić, że zatwierdzenie <branch>
nie powinno być przeznaczone <branch>
?
Podążyłem za tym pytaniem i odpowiedzią na Stack Overflow: Wypchnij nowy lokalny oddział do zdalnego repozytorium Git i śledź go . Domyślam się, że to kolejny przypadek niekompletnej lub błędnie zaakceptowanej odpowiedzi. Lub jest to kolejny przypadek, w którym Git wykonuje proste zadanie i utrudnia to.
Oto widok na innym komputerze. Gałąź wyraźnie istnieje, więc została utworzona i wypchnięta:
$ git branch -a
alignas
* master
remotes/origin/HEAD -> origin/master
remotes/origin/alignas
remotes/origin/arm-neon
remotes/origin/det-sig
remotes/origin/master
remotes/origin/solaris
git config --add push.default current
, git push automatycznie utworzy gałąź w zdalnym repozytorium, jeśli to konieczne.Odpowiedzi:
TL; DR:
git branch --set-upstream-to origin/solaris
Odpowiedź na pytanie, które zadałeś - które przeredaguję trochę jako „czy muszę ustawić nadrzędny kanał” - brzmi: nie, w ogóle nie musisz ustawiać nadrzędnego.
Jeśli jednak nie masz programu nadrzędnego dla bieżącej gałęzi, Git zmieni swoje zachowanie na
git push
, a także na inne polecenia.Cała historia wypychania tutaj jest długa i nudna i sięga do historii sprzed wersji Git 1.5. Aby go bardzo skrócić,
git push
został źle wdrożony. 1 Począwszy od wersji 2.0 Git, Git ma teraz pokrętło konfiguracji zapisanepush.default
domyślnie nasimple
. W przypadku kilku wersji Gita przed i po 2.0, za każdym razem, gdy byłeś uruchamianygit push
, Git wyrzucał dużo hałasu, próbując przekonać Cię do ustawieniapush.default
tylko po to, aby sięgit push
zamknąć.Nie wspominasz, z której wersji Gita korzystasz, ani czy skonfigurowałeś
push.default
, więc musimy zgadnąć. Domyślam się, że używasz wersji Git 2-punktowy coś, a które zostały ustawionepush.default
, abysimple
dostać to, żeby się zamknął. Dokładnie to, którą wersję Gita masz i co jeśli cokolwiekpush.default
ustawiłeś, ma znaczenie ze względu na tę długą i nudną historię, ale ostatecznie fakt, że otrzymujesz kolejną skargę od Gita, wskazuje, że Twój Git jest skonfigurowany tak, aby uniknąć jednego z błędów z przeszłości.Co to jest upstream?
Upstream to po prostu inna nazwa oddziału, zwykle zdalnego śledzenia gałąź, wiąże się z regularnym (lokalnych) oddział.
Każda gałąź ma opcję posiadania jednego (1) zestawu upstream. Oznacza to, że każda gałąź albo ma upstream, albo nie ma upstream. Żadna gałąź nie może mieć więcej niż jednego upstream.
Upstream powinien , ale nie musi, być prawidłową gałęzią (czy to zdalne śledzenie, czy lokalne ). Oznacza to, że jeśli bieżąca gałąź B ma upstream U , powinna działać. Jeśli to nie zadziała - jeśli narzeka, że U nie istnieje - to większość Gita działa tak, jakby nadrzędny strumień w ogóle nie był ustawiony. Kilka poleceń, takich jak , pokaże ustawienia nadrzędne, ale oznaczy je jako „nie ma”.
origin/B
master
git rev-parse U
git branch -vv
Po co jest upstream?
Jeśli twój
push.default
jest ustawiony nasimple
lubupstream
, ustawienie nadrzędne sprawigit push
, że użyte bez dodatkowych argumentów po prostu zadziała.To wszystko - po to wszystko
git push
. Ale to dość znaczące, ponieważgit push
jest to jedno z miejsc, w których zwykła literówka powoduje poważne bóle głowy.Jeśli twój
push.default
jest ustawiony nanothing
,matching
lubcurrent
, ustawienie nadrzędnego strumienia nic nie robigit push
.(Wszystko to przy założeniu, że Twoja wersja Git to co najmniej 2.0).
Upstream wpływa
git fetch
Jeśli uruchomisz
git fetch
bez dodatkowych argumentów, Git ustali, z którego pilota pobrać, konsultując się z nadrzędnym gałąź bieżącej gałęzi. Jeśli upstream jest gałęzią ze zdalnym śledzeniem, Git pobiera z tego zdalnego. (Jeśli upstream nie jest ustawiony lub jest gałęzią lokalną, Git próbuje pobraćorigin
).Upstream dotyka
git merge
igit rebase
zbytJeśli uruchomisz
git merge
lubgit rebase
bez dodatkowych argumentów, Git użyje upstream z bieżącej gałęzi. Więc skraca użycie tych dwóch poleceń.Upstream wpływa
git pull
I tak nigdy nie powinieneś 2 używać
git pull
, ale jeśli to zrobisz, użyjgit pull
ustawienia nadrzędnego, aby dowiedzieć się, z którego pilota pobrać, a następnie z którą gałąź połączyć lub ponownie bazować. Oznacza to, żegit pull
robi to samo, co - ponieważgit fetch
faktycznie działagit fetch
- a następnie robi to samo, cogit merge
lubgit rebase
, ponieważ faktycznie działagit merge
lubgit rebase
.(Zwykle powinieneś po prostu wykonać te dwa kroki ręcznie, przynajmniej do czasu, gdy znasz Git na tyle dobrze, że gdy któryś z nich zawiedzie, co w końcu się uda, rozpoznasz, co poszło nie tak i będziesz wiedział, co z tym zrobić.)
Upstream wpływa
git status
To może być właściwie najważniejsze. Gdy już masz zestaw nadrzędny,
git status
możesz zgłosić różnicę między bieżącą gałęzią a jej nadrzędną pod względem zatwierdzeń.Jeśli, jak to jest w normalnym przypadku, znajdujesz się w gałęzi
B
z jej upstream ustawioną na i uruchomisz , natychmiast zobaczysz, czy masz zatwierdzenia, które możesz wcisnąć i / lub zatwierdzenia, na których możesz scalić lub zmienić bazę.origin/B
git status
Dzieje się tak, ponieważ
git status
działa:git rev-list --count @{u}..HEAD
: Ile commity masz naB
które są nie na ?origin/B
git rev-list --count HEAD..@{u}
: Ile commity masz na które są nie na ?origin/B
B
Utworzenie upstream daje ci wszystkie te rzeczy.
Jak to się
master
stało, że ma już zestaw upstream?Kiedy pierwszy raz klonujesz z jakiegoś pilota, użyj:
lub podobnie, ostatnim krokiem, jaki robi Git, jest zasadniczo
git checkout master
. Spowoduje to sprawdzenie twojego lokalnego oddziału -master
tylko ty nie masz lokalnego oddziałumaster
.Z drugiej strony, nie ma zdalnego śledzenia oddział nazwany
origin/master
, ponieważ po prostu go klonować.Git domyśla się, że musiało to mieć na myśli: „zrób mi nowy lokal,
master
który wskazuje na to samo zatwierdzenie co zdalne śledzenieorigin/master
, a kiedy już to robisz, ustaw górny strumień namaster
toorigin/master
”.Dzieje się tak w przypadku każdej gałęzi
git checkout
, której jeszcze nie masz. Git tworzy gałąź i sprawia, że „śledzi” (jako upstream) odpowiednią gałąź zdalnego śledzenia.Ale to nie działa dla nowych oddziałów, czyli oddziałów bez zdalnego śledzenia oddział jeszcze .
Jeśli utworzysz nowy oddział:
na razie nie ma
origin/solaris
. Lokalnysolaris
nie może śledzić gałęzi zdalnego śledzenia,origin/solaris
ponieważ nie istnieje.Kiedy po raz pierwszy pchasz nową gałąź:
który tworzy
solaris
worigin
, a tym samym tworzy równieżorigin/solaris
we własnym repozytorium Git. Ale jest za późno: masz już lokalną sieć,solaris
która nie ma upstream . 3Czy Git nie powinien po prostu ustawić tego teraz jako nadrzędny automatycznie?
Prawdopodobnie. Zobacz „źle zaimplementowany” i przypis 1. Trudno to teraz zmienić : istnieją miliony 4 skryptów, które używają Git, a niektóre mogą zależeć od jego obecnego zachowania. Zmiana zachowania wymaga nowej głównej wersji, nag-ware wymusi ustawienie jakiegoś pola konfiguracyjnego i tak dalej. Krótko mówiąc, Git jest ofiarą własnego sukcesu: wszelkie błędy, które zawiera, można dziś naprawić tylko wtedy, gdy zmiana jest albo w większości niewidoczna, wyraźnie - znacznie lepsza, albo następuje powoli w czasie.
Faktem jest, że nie dzieje się tak dzisiaj, chyba że używasz
--set-upstream
lub-u
podczasgit push
. To właśnie mówi wiadomość.Nie musisz tego robić w ten sposób. Cóż, jak zauważyliśmy powyżej, w ogóle nie musisz tego robić, ale powiedzmy, że chcesz upstream. Już utworzony oddział
solaris
naorigin
dzięki wcześniejszym naciśnięciu, jak i swoichgit branch
pokazów wyjściowych, które już mająorigin/solaris
w lokalnym repozytorium.Po prostu nie masz tego ustawionego jako upstream dla
solaris
.Aby ustawić to teraz, a nie podczas pierwszego naciśnięcia, użyj
git branch --set-upstream-to
. Polecenie--set-upstream-to
podrzędne przyjmuje nazwę dowolnej istniejącej gałęzi, na przykładorigin/solaris
, i ustawia bieżącą gałąź w górę do tej innej gałęzi.To wszystko - to wszystko, co robi - ale ma to wszystkie konsekwencje wymienione powyżej. Oznacza to, że możesz po prostu biegać
git fetch
, następnie rozglądać się, a następnie biegaćgit merge
lubgit rebase
odpowiednio, a następnie tworzyć nowe zatwierdzenia i biecgit push
, bez dodatkowego zamieszania.1 Prawdę mówiąc, nie było wtedy jasne, czy początkowa implementacja była podatna na błędy. Stało się to jasne dopiero wtedy, gdy każdy nowy użytkownik za każdym razem popełniał te same błędy. Jest teraz „mniej biedny”, co nie znaczy, że jest „wspaniały”.
2 „Nigdy” jest trochę mocne, ale uważam, że nowicjusze Git dużo lepiej rozumieją rzeczy, kiedy oddzielam kroki, zwłaszcza gdy mogę im pokazać, co
git fetch
faktycznie zrobiło, i wtedy mogą zobaczyć, co zrobiągit merge
lubgit rebase
zrobią dalej.3 Jeśli uruchomisz swoją pierwszą
git push
jako —git push -u origin solaris
tj., Jeśli dodasz-u
flagę — Git ustawiorigin/solaris
jako nadrzędny dla twojej bieżącej gałęzi, jeśli (i tylko jeśli) push się powiedzie. Więc powinieneś zaopatrywać-u
się przy pierwszym pchnięciu. W rzeczywistości możesz go podać przy dowolnym późniejszym naciśnięciu i w tym momencie ustawi lub zmieni górny strumień. Ale myślę, żegit branch --set-upstream-to
jest łatwiej, jeśli zapomniałeś.4 Mierzone metodą Austina Powersa / Dr Evila, mówiąc po prostu „jeden MILLLL-YUN”.
źródło
--set-upstream /dev/null
? Dlaczego ciężar spoczywa na zwykłym przypadku? Naprawdę nie rozumiem niektórych z tych decyzji dotyczących inżynierii i użyteczności.git push -u
, ale naprawdę wygląda na to, żegit push -u
powinno być domyślne, lub przynajmniej domyślne, jeśli nie ma jeszcze nadrzędnego , a powinno być,git push --no-set-upstream
gdy obecnie nie ma nadrzędnego strumienia i chcesz zachować tak (z niezrozumiałego powodu :-)).git config --add push.default current
, git push automatycznie utworzy gałąź w zdalnym repozytorium, jeśli to konieczne.Różnica między
git push origin <branch>
i
git push --set-upstream origin <branch>
polega na tym, że oba te pliki dobrze trafiają do zdalnego repozytorium, ale zauważasz różnicę, gdy pociągniesz.
Jeśli to zrobisz:
git push origin <branch>
podczas ciągnięcia musisz:
git pull origin <branch>
Ale jeśli to zrobisz:
git push --set-upstream origin <branch>
wtedy podczas ciągnięcia musisz tylko:
git pull
Dodanie do
--set-upstream
pozwala więc na uniknięcie konieczności określania, z której gałęzi chcesz pobierać za każdym razem, gdy to robiszgit pull
.źródło
--set-upstream
wgit push
(w przeciwieństwie dogit branch
z--set-upstream-to
) jest to, co-b
jestgit checkout
(w przeciwieństwie dogit branch
lub obecniegit switch -c
). To jest szaleństwo przez cały czas i nie powinieneś oczekiwać niczego mniej. Oczywiście zgit push set-upstream
będziesz chciał określić,remote branch
podczas gdy zgit branch --set-upstream-to
używaszremote/branch
(znanego również jako commreftreeish 😉).Zasadniczo pełne polecenie jest jak
git push <remote> <local_ref>:<remote_ref>
. Jeśli uruchomisz tylkogit push
, git nie wie, co dokładnie zrobić, chyba że stworzyłeś konfigurację, która pomoże gitowi podjąć decyzję. W repozytorium git możemy skonfigurować wiele pilotów. Możemy również przekazać lokalną referencję do dowolnego zdalnego referencji. Pełne polecenie jest najprostszym sposobem na wykonanie pchnięcia. Jeśli chcesz wpisać mniej słów, musisz najpierw skonfigurować, na przykład --set-upstream.źródło
Rozumiem, że "-u" lub "--set-upstream" pozwala określić górne (zdalne) repozytorium dla gałęzi, w której się znajdujesz, więc następnym razem, gdy uruchomisz "git push", nie będziesz nawet trzeba określić zdalne repozytorium.
Wypchnij i skonfiguruj repozytorium upstream (zdalne) jako źródło:
Następnym razem, gdy będziesz pchać, nie musisz określać zdalnego repozytorium:
źródło