Dlaczego muszę jawnie wcisnąć nowy oddział?

180

Jestem nowy giti ćwiczę. Utworzyłem oddział lokalny, ale zobaczyłem, że kiedy to zrobiłem, git pushmój oddział nie został przesłany do repozytorium. Musiałem faktycznie: git push -u origin --all.
Dlaczego to? Czy gałąź nie jest nową zmianą, która ma być wprowadzana domyślnie? Dlaczego muszę uruchomić drugie polecenie?

Cratylus
źródło
15
Zauważ, że można to skonfigurować (ustawienie push.default, patrz man git-config). Jeśli to zrobisz git config --add push.default current, git pushw razie potrzeby automatycznie utworzy gałąź w zdalnym repozytorium. Dlaczego nie jest to domyślne, wyjaśniono w odpowiedziach.
sleske
@sleske Zgadzam się. Pozostałe zasady „ currenti upstream” można znaleźć w mojej starszej odpowiedzi stackoverflow.com/a/13751847/6309 .
VCC
Dlaczego nie zaakceptować odpowiedzi?
laike9m,

Odpowiedzi:

224

Rzeczywistym powodem jest to, że w nowym repozytorium (git init) nie ma żadnej gałęzi (nie master, żadnej gałęzi, zero gałęzi)

Więc kiedy naciskasz po raz pierwszy do pustego repozytorium upstream (zwykle nagiego ), to repozytorium upstream nie ma gałęzi o tej samej nazwie.

I:

W obu przypadkach, ponieważ upstream puste repozytorium nie ma gałęzi:

  • nie ma jeszcze pasującej nazwanej gałęzi
  • w ogóle nie ma odgałęzienia (o tej samej nazwie lub bez! Śledzenie lub nie)

Oznacza to, że twój pierwszy lokalny push nie ma pojęcia:

  • gdzie naciskać
  • co wcisnąć (ponieważ nie może znaleźć żadnej gałęzi nadrzędnej, która byłaby zapisana jako zdalna gałąź śledzenia i / lub o tej samej nazwie)

Musisz przynajmniej wykonać:

git push origin master

Ale jeśli tylko to zrobisz, będziesz:

  • utworzy mastergałąź upstream na upstream (teraz niepuste repo): good.
  • nie zapisuje, że lokalny oddział „ master” musi zostać wypchnięty do upstream ( origin) ” master„ (upstream branch): zły.

Dlatego zaleca się, aby za pierwszym razem wykonać:

git push -u origin master

Będzie to rejestrowane origin/masterjako gałąź zdalnego śledzenia i umożliwi automatyczne push masterdo następnego push origin/master.

git checkout master
git push

I to będzie działać również w przypadku zasad wypychania current”lub„ upstream”.
W każdym przypadku po git push -u origin masterinicjalizacji wystarczy zwykłe wypychanie git, aby kontynuować przepychanie mastera do prawej gałęzi.

VonC
źródło
2
Po tym punkcie następny git pushoczekuje również, że gałąź już istnieje?
Cratylus
2
Tak. Prześle wszelkie aktualizacje do tego oddziału do repozytorium nadrzędnego.
RyPeck,
@Cratylus tak, ze względu na nową domyślną zasadę push ' simple': push do dowolnego zarejestrowanego odgałęzienia, jeśli ten odgałęzienie ma taką samą nazwę jak lokalny. Wystarczy proste git push.
VCC
1
@ButtleButkus Dziękujemy. Przywróciłem link.
VonC
3
W bardziej ogólnym przypadku pytającego o nową gałąź „new_branch” użyłbyś git push --set-upstream origin new_branchlub git push -u origin new_branchw skrócie. To, -allże pytający użył ominęło nazwanie nowego nowego oddziału, włączając wszystkie gałęzie. W odpowiedzi ujął to + Klas Mellbourn.
Paul Masri-Stone,
106

Nie widzisz poniżej

Uważam tę „cechę” za dość irytującą, ponieważ nie próbuję wystrzelić rakiet na Księżyc, tylko pchnąć moją cholerną gałąź. Prawdopodobnie też to robisz, inaczej by cię tu nie było!

Oto poprawka: jeśli chcesz, aby niejawnie naciskała na bieżącą gałąź niezależnie od tego, czy gałąź ta istnieje na początku, po prostu wydaj tę komendę raz i nigdy więcej nie będziesz musiał nigdzie:

git config --global push.default current

Więc jeśli tworzysz takie gałęzie:

git checkout -b my-new-branch

a następnie dokonaj kilku zatwierdzeń, a następnie wykonaj

git push -u

aby wydobyć je z pochodzenia (będąc w tej gałęzi) i utworzy dla ciebie wspomnianą gałąź, jeśli nie istnieje.

Zauważ, że bit -u upewnia się, że są one połączone, jeśli chcesz pobrać później z tej gałęzi. Jeśli nie planujesz później wyciągnąć gałęzi (lub jeśli nie masz nic przeciwko kolejnej wkładce) -u nie jest konieczne.

John Culviner
źródło
3
Kiedy to zrobię, jeśli zrobię git pull, natychmiast po tym - dwie gałęzie nie zostaną połączone. :(
Alisso
to jedyna odpowiedź, która naprawiła mój problem.
Raymond Chenon
2
Aby je połączyć, użyjgit push -u
Ben Creasy
Dzięki! Ta odpowiedź powinna zostać zaakceptowana jako szybkie i „brudne” rozwiązanie. Jestem prawie pewien, że jest to najbliższe intencji OP.
youngrrrr
3
> Nie próbuję odpalać rakiet na Księżyc. -- TAK.
VCavallo
39

Dane wyjściowe git pushpodczas wypychania nowej gałęzi

> git checkout -b new_branch
Switched to a new branch 'new_branch'
> git push
fatal: The current branch new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new_branch

Prosty git pushzakłada, że ​​istnieje już gałąź zdalna, którą śledzi bieżąca gałąź lokalna. Jeśli nie ma takiej zdalnej gałęzi i chcesz ją utworzyć, musisz to określić za pomocą flagi -u(krótkiej formy --set-upstream).

Dlaczego tak jest Wydaje mi się, że realizatorzy uważali, że utworzenie gałęzi na pilocie jest tak ważną czynnością, że ciężko byłoby to zrobić przez pomyłkę. git pushto coś, co robisz cały czas.

„Czy gałąź nie jest domyślnie nową zmianą, którą należy wprowadzić?” Powiedziałbym, że „zmiana” w Git jest zatwierdzeniem. Gałąź jest wskaźnikiem zatwierdzenia. Dla mnie bardziej sensowne jest myślenie o pchnięciu jako o czymś, co popycha zobowiązania do innych repozytoriów. To, które zatwierdzenia są wypychane, zależy od tego, w której gałęzi jesteś, i relacji śledzenia tej gałęzi do gałęzi na pilocie.

Możesz przeczytać więcej o śledzeniu gałęzi w rozdziale Zdalne gałęzie książki Pro Git .

Klas Mellbourn
źródło
Nie dostałem, fatalale już zrobiłem zatwierdzenie w oddziale. Czy to sprawa?
Cratylus
@ Cratylus nie, to nie ma znaczenia. Zatwierdzenie jest bezpieczne w twoim repozytorium i git push -u originskopiowane do zdalnego repozytorium.
Klas Mellbourn,
Nie, mam na myśli fakt, że nie otrzymałem wiadomości fatalpodobnej do tej, o której wspomniałeś w odpowiedzi. Czy ta różnica zależy od tego, czy coś powierzyłem oddziałowi?
Cratylus
@ Cratylus Nie wiem, dlaczego nie otrzymałeś fatalwiadomości. Domyślam się, że różnica zależy dokładnie od tego, jakiej implementacji git używasz. Moje dane wyjściowe pochodzą z wersji 1.8.1.msysgit.1 działającej w systemie Windows 8.
Klas Mellbourn,
Mam tę samą wersję, ale na Vistę
Cratylus
4

Tak szybko nie mogłem znaleźć uzasadnienia dla oryginalnych programistów, ale mogę dać ci wykształcone domysły na podstawie kilku lat doświadczenia w Git.

Nie, nie każda gałąź jest czymś, co chcesz wypchnąć do świata zewnętrznego. Może reprezentować prywatny eksperyment.

Co więcej, gdzie należy git pushwysłać wszystkie oddziały? Git może współpracować z wieloma pilotami i możesz mieć różne zestawy gałęzi na każdym. Np. Centralny projekt repozytorium GitHub może mieć gałęzie wydania; widelec GitHub może mieć gałęzie tematów do przeglądu; a lokalny serwer Git może mieć oddziały zawierające lokalną konfigurację. Gdyby git pushpopchnąć wszystkie gałęzie do pilota, który śledzi bieżąca gałąź, tego rodzaju schemat byłby łatwy do zepsucia.

Fred Foo
źródło
1) It might represent a private experiment.Ok, ale o co chodzi? „Główna” gałąź, na której wszyscy pracują, tzn. masterNie ma na nią wpływu. Chyba że chcesz ukryć kod źródłowy 2) git push, without a remote, pushes to the current branch's remoteZgubiłem cię tutaj :(
Cratylus
@Cratylus: 1) w projekcie z dziesiątkami programistów, którzy wszyscy zajmują się ad lib, otrzymasz bardzo niechlujne repo. Pracuję nad takimi projektami i za git fetchkażdym razem nie chciałbym setek pół-pracujących gałęzi. 2) Mam na myśli git pushdomyślne zachowanie. Przesyła do pilota, że ​​bieżąca gałąź śledzi, jeśli istnieje.
Fred Foo,
3

HEAD jest skrótem od aktualnej gałęzi, więc HEAD git push -u działa. Teraz, aby uniknąć tego wpisywania za każdym razem, gdy używam aliasu:

git config --global alias.pp 'push -u origin HEAD'

Następnie za każdym razem, gdy chcę przesłać gałąź utworzoną za pomocą gałęzi git -b, mogę przesłać ją za pomocą:

git pp

Mam nadzieję, że to komuś oszczędza czas!

Aurimas Rekštys
źródło
2

Przy pierwszej kontroli

Krok 1: git remote -v
// jeśli znaleziono, zainicjuj git, a następnie usuń lub pomiń krok 2

Krok 2: git remote rm origin
// Następnie skonfiguruj swój adres e-mail globalnie git

Krok 3: git config --global user.email "[email protected]"

Krok 4: git initial

Krok 5: git commit -m "Initial Project"
// Jeśli już dodajesz repozytorium projektu, pomiń krok 6

Krok 6: git remote add origin %repo link from bitbucket.org%

Krok 7: git push -u origin master

Md.Milton
źródło
1

Właśnie doświadczyłem dalszej permutacji tego problemu.

Miałem nazwę oddziału, feat/XYZ-1234-some-descriptionponieważ pracowałem nad wydaniem Jira 1234. W trakcie pracy stworzyłem nowy numer Jira, aby śledzić mniejszy fragment pracy, a kiedy przyszedłem do wypychania, postanowiłem przesłać do nazwy oddziału z tym nowym numerem wydania w:

git push -u origin feat/XYZ-5678-a-different-description # failed

To dało mi błąd omawiany w tym wątku SO. Ale ponieważ próbowałem przekazać nazwę inną niż moja obecna, mój problem był inny niż tutaj opisany. Ostatecznie zmieniłem nazwę mojego lokalnego oddziału, zanim mogłem go przekazać:

git branch -m feat/XYZ-1234-some-description feat/XYZ-5678-a-different-description
git push -u origin feat/XYZ-5678-a-different-description # now works

Po nieco więcej lekturach zdałem sobie sprawę, że mogłem ustawić opcję srcna git pushalbo do bieżącej nazwy oddziału, albo po prostu w HEADrazie potrzeby:

git push -u origin feat/XYZ-1234-some-description:feat/XYZ-5678-a-different-description # also works
Mark Birbeck
źródło
-1

Jeśli włączysz po raz pierwszy wprowadzanie nowych zmian z nowego oddziału. I poniżej błędu:

*git push -f
fatal: The current branch Coding_Preparation has no upstream branch.

Aby przesunąć bieżącą gałąź i ustawić pilota jako wysyłającego, użyj

git push -u origin new_branch_name


** Successful Result:** 
 git push -u origin Coding_Preparation
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 599 bytes | 599.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'Coding_Preparation' on GitHub by visiting: ...
 * [new branch]      Coding_Preparation -> Coding_Preparation
Branch 'Coding_Preparation' set up to track remote branch 'Coding_Preparation' from 'origin'.
Mukesh Kumar
źródło