Co dokładnie robi „u”? „Git push -u origin master” vs „git push origin master”

334

Najwyraźniej jestem okropny w używaniu gita, pomimo moich najlepszych prób zrozumienia tego.

Z kernel.org dla git push:

-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).

Oto branch.<name>.mergeod git config:

branch.<name>.merge

Definiuje wraz z branch.<name>.remoteodgałęzieniem dla danego odgałęzienia. Mówi git fetch / git pull, którą gałąź połączyć, a także może wpływać na git push (patrz push.default). Gdy jest w gałęzi <name>, mówi git pobrać domyślny plik referencyjny, który ma zostać oznaczony do scalenia w FETCH_HEAD. Wartość jest obsługiwana jak zdalna część refspec i musi być zgodna z ref, która jest pobierana z pilota podanego przez "branch.<name>.remote". Informacje o scalaniu są używane przez git pull (który na początku wywołuje git fetch), aby wyszukać domyślną gałąź do scalenia. Bez tej opcji, git pull defaults, aby scalić pierwszy pobrany refspec. Podaj wiele wartości, aby uzyskać scalenie ośmiornicy. Jeśli chcesz skonfigurować git pull, aby łączył się <name>z innym oddziałem w lokalnym repozytorium, możesz wskazaćbranch.<name>.mergedo żądanej gałęzi i użyj specjalnego ustawienia. (kropka) dla branch.<name>.remote.

Z powodzeniem skonfigurowałem zdalne repozytorium za pomocą github i pomyślnie wypuściłem swoje pierwsze zatwierdzenie do niego za pomocą:

git push -u origin master

Następnie nieumyślnie zepchnąłem drugie zatwierdzenie do mojego zdalnego repozytorium, używając:

git commit -m '[...]'

Jednak błędnie myśląc, że muszę ponownie wcisnąć do originz master, wpadłem:

# note: no -u
git push origin master

Co to zrobiło? Wydawało się, że nie miało to żadnego efektu. Czy „cofnąłem” git push -u origin master?

Zamknięcie Cowboy
źródło
44
I'm apparently terrible at using git, despite my best attempts to understand it.- Nigdy nie miałem kogoś tak dobrze mnie odtwarzającego.
dgo 30.04.16

Odpowiedzi:

335

Kluczem jest „git-pull bez argumentów”. Kiedy robisz git pullz gałęzi, bez określania źródłowego pilota lub gałęzi, git sprawdza branch.<name>.mergeustawienie, aby wiedzieć, skąd pobierać. git push -uustawia te informacje dla gałęzi, którą przekazujesz.

Aby zobaczyć różnicę, użyjmy nowej pustej gałęzi:

$ git checkout -b test

Po pierwsze, pchamy bez -u:

$ git push origin test
$ git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.test.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "test"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

Teraz jeśli dodamy -u:

$ git push -u origin test
Branch test set up to track remote branch test from origin.
Everything up-to-date
$ git pull
Already up-to-date.

Pamiętaj, że informacje o śledzeniu zostały skonfigurowane tak, aby git pulldziałały zgodnie z oczekiwaniami bez określania pilota lub oddziału.

Aktualizacja: Wskazówki dotyczące bonusów:

  • Jak Mark wspomina w komentarzu, oprócz git pulltego ustawienia wpływa również na domyślne zachowanie git push. Jeśli masz zwyczaj -uprzechwytywania zdalnej gałęzi, którą zamierzasz śledzić, zalecamy ustawienie push.defaultwartości konfiguracji na upstream.
  • git push -u <remote> HEADpopchnie bieżącą gałąź do gałęzi o tej samej nazwie na <remote>(a także skonfiguruje śledzenie, abyś mógł to zrobić git pushpóźniej).
dahlbyk
źródło
4
git push <remote> <branch>sprawia, że ​​wszystko jest jednoznaczne . W przypadku pominięcia zdalnego lub oddziału git wraca do ustawień konfiguracji oddziału, które są dla ciebie ustawione git push -u.
dahlbyk
2
@dahlbyk Poszedłem naprzód i oznaczyłem cię jako odpowiedź, ale ten komentarz nieco mnie dezorientuje. W swojej odpowiedzi wykazałeś, że git był zdezorientowany po git push origin test(którego nie ma -u). Następnie pokazałeś, że git push -u origin test usuwa to dwuznaczność. Czy jest literówka, czy znów jestem gęsty?
ClosureCowboy
1
Myślę, że rozmawiamy obok siebie. :) Kiedy mówię, git push <remote> <branch>jest jednoznaczny, mam na myśli to, w stosunku do git pushktórego opiera się konfiguracja gałęzi. Podobnie git pull <remote> <branch>jest jednoznaczny i git pullpolega na konfiguracji oddziału. Po popychany z -uzarówno git pushi git pullbędzie działać zgodnie z oczekiwaniami.
dahlbyk
10
@dahlbyk: Twoja odpowiedź jest w porządku, ale w powyższych komentarzach powtarzasz powszechne nieporozumienie na temat git push- chyba że push.defaultsam ustalisz , git pushużywa tylko konfiguracji odgałęzienia w górę, aby zdecydować, do którego pilota przesłać, a nie do oddziału zdalnego w celu aktualizacji.
Mark Longair
1
Najlepszą praktyką dla git jest git push origin masterto samo dla drugiej strony IE. git pull origin master.. Więc jeśli załóżmy, że zmiana gałęzi, możesz git push origin branch_nameto samo zrobić z IE po drugiej stronie. git pull origin branch_name
Arpit Vaisnav
87
git push -u origin master

… jest taki sam jak:

git push origin master ; git branch --set-upstream master origin/master

Zrób ostatnie zdanie, jeśli zapomnisz -u!

Lub możesz to zmusić:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

Jeśli pozwolisz, aby polecenie to zrobiło za ciebie, wybierze twoje błędy, tak jakbyś wpisał nieistniejącą gałąź lub nie git remote add; chociaż to może być to, czego chcesz. :)

Sabgenton
źródło
1
BTW masterto tylko przykład :)
Sabgenton
Ok, drugi bit jest teraz amortyzowany w nowszych wersjach dla: git branch master -u origin/masterdetails @ stackoverflow.com/a/2286030/790359
sabgenton
2
Jeśli zapomnisz skorzystać z -uopcji, wpisz git push -unatychmiast, będzie OK.
zeekvfu
1
Nowsze wersje git wskazują, że --setup-upstreambędą przestarzałe: The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
Bill Hoag,
--set-upstream jest przestarzałe, teraz działa:git branch --set-upstream-to=origin/master master
Alberto Perez
43

Mówiąc prościej:

Technicznie -uflaga dodaje odniesienie śledzenia do serwera nadrzędnego, na który naciskasz.

Ważne jest tutaj to, że pozwala to zrobić git pullbez podawania dodatkowych argumentów. Na przykład, kiedy to zrobisz git push -u origin master, możesz później zadzwonić, git pulla git będzie wiedział, że tak naprawdę miałeś na myśli git pull origin master.

W przeciwnym razie trzeba wpisać całe polecenie.

Adépòjù Olúwáségun
źródło
1
Więc jeśli ustawię -uflagę przy orgin masterkażdym kolejnym ściągnięciu, będzie się do niej odnosił. A jeśli chcę zmienić git pullzachowanie, powinienem uruchomić, git push -u origin some_other_brancha git pullteraz będę się odnosił some_other_branch? Dziękuję Ci!
Toma Tomov
1
czy możemy również użyć „git push” zamiast „git push origin master”?
cegprakash
Tak, możesz @cegprakash. Jednak początkowo zrobiłbyśgit push -u origin master
Adépòjù Olúwáségun
-11

Wszystkie niezbędne polecenia git bash do wypychania i pobierania do Github:

git status 
git pull
git add filefullpath

git commit -m "comments for checkin file" 
git push origin branch/master
git remote -v 
git log -2 

Jeśli chcesz edytować plik:

edit filename.* 

Aby zobaczyć wszystkie gałęzie i ich zobowiązania:

git show-branch
Kamta Mishra
źródło
4
Myślę, że odpowiedziałeś poza zakresem pytania.
Adépòjù Olúwáségun