Pytanie Czy "git pull" może automatycznie ukrywać się i uruchamiać oczekujące zmiany?


Wiem, jak rozwiązać ten problem:

user@host$ git pull
Updating 9386059..6e3ffde
error: Your local changes to the following files would be overwritten by merge:
    foo.bar
Please, commit your changes or stash them before you can merge.
Aborting

Ale nie ma sposobu, aby na to pozwolić git pull zrób stash i pop tańcz dla mnie?

Jeśli to polecenie ma inną nazwę, jest w porządku.

Tworzenie aliasu powłoki dla git stash; git pull; git stash pop jest rozwiązaniem, ale szukam lepszego rozwiązania.


76
2018-05-13 07:58


pochodzenie


a co z a git Alias? - Яois
Bieganie git stash; git pull; git stash pop programowo jest niebezpieczne, ponieważ jeśli nie ma nic do skasowania, git stash będzie no-op, ale git stash pop wyskoczy ostatnia skrytka (jeśli istnieje), co jest prawie na pewno nie czego chcesz. Użytkownik torek ma świetny post na ten temat w Stack Overflow, ale nie mogę go znaleźć ... - jubobs
@Jubobs to? stackoverflow.com/a/20412685/6309 Albo ten? stackoverflow.com/a/20480591/6309 - VonC
@guettli Nie sugerowałem, że twoje pytanie jest duplikatem, właśnie odpowiadałem na komentarz Jubobs. - VonC
Jako kolejny krok operacja powinna zakończyć się sukcesem tylko wtedy, gdy skrytkę można łatwo zastosować po pociągnięciu. Jeśli występują konflikty, cała operacja nie powiedzie się atomowo, aby drzewo nie uległo zmianie. Oto, co chciałbym zrobić: albo zlikwiduj zmiany z lokalnymi połączonymi, albo też zawiedziesz z błędem i pozwól mi ręcznie zdecydować, co dalej. Czy możliwa jest taka "transakcja" git? - Ed Avis


Odpowiedzi:


Dla Git 2.6+ (wydany 28 września 2015)

Jedyny git config ustawienie, które mogłoby być interesujące:

rebase.autoStash

Po ustawieniu wartości true, automatycznie tworzy tymczasową zawartość przed rozpoczęciem operacji i stosuje ją po zakończeniu operacji.
  Oznacza to, że możesz uruchomić bazę danych w brudnym worktree.

Należy jednak zachować ostrożność: ostateczna aplikacja ze stosem po udanym rebaserze może spowodować nietrywialne konflikty. Domyślnie false.

połączyć to z:

pull.rebase

W przypadku wartości true rozgałęzienia gałęzi na szczycie pobranej gałęzi, zamiast łączenia domyślnej gałęzi z domyślnym pilotem po uruchomieniu "git pull".

git config pull.rebase true
git config rebase.autoStash true

To by wystarczyło na proste git pull pracować nawet w brudnym drzewie.
W takim przypadku nie jest potrzebny żaden alias.


Widzieć Zatwierdź 53c76dc (04 lipca 2015) przez Kevin Daudt (Ikke).
(Scalone przez Junio ​​C Hamano - gitster - w popełnij e69b408, 17 sierpnia 2015) 

pull: pozwól na brudne drzewo kiedy rebase.autostash włączony

rebase nauczył się przechować zmiany, gdy napotka brudne drzewo pracy,   ale git pull --rebase nie.

Sprawdzaj tylko, czy drzewo robocze jest brudne, kiedy rebase.autostash nie jest   włączony.


Uwaga: jeśli chcesz ciągnąć bez autostash (nawet jeśli rebase.autoStash true jest ustawiony), masz od git 2.9 (czerwiec 2016):

 pull --rebase --no-autostash

Widzieć commit 450dd1d, zatwierdzić 1662297, zatwierdzić 44a59ff, Zatwierdź 5c82bcd, Zatwierdź 6ddc97c, commit eff960b, zatwierdzić efa195d (02 kwietnia 2016 r.), Oraz Zatwierdź f66398e, commit c48d73b (21 marca 2016 r.) Wg Mehul Jain (mehul2029).
(Scalone przez Junio ​​C Hamano - gitster - w Zatwierdź 7c137bb, 13 kwietnia 2016 r.) 

Zatwierdź f66398e w szczególności obejmuje:

pull --rebase: Dodaj --[no-]autostash flaga

Gdyby rebase.autoStash zmienna konfiguracyjna jest ustawiona, nie ma takiej możliwości   zastąp to dla "git pull --rebase"z linii poleceń.

Nauczać "git pull --rebase"the --[no-]autostash flagę linii poleceń, która   zastępuje bieżącą wartość rebase.autoStash, jeśli ustawione. Tak jak "git rebase"   rozumie --[no-]autostash opcja, to tylko kwestia przemijania   opcja leżących u podstaw "git rebase" gdy "git pull --rebase" jest nazywany.


Ostrzeżenie: przed Git 2.14 (Q3 2017), "git pull --rebase --autostash"nie zapisywał się automatycznie, gdy lokalna historia szybko przechodzi do wyższego poziomu.

Widzieć Zatwierdź f15e7cf (01 czerwca 2017 r.) Wg Tyler Brazier (tylerbrazier).
(Scalone przez Junio ​​C Hamano - gitster - w zatwierdzić 35898ea, 05 czerwca 2017 r.) 

pull: ff --rebase --autostash działa w brudnym repo

Gdy git pull --rebase --autostash w brudnym repozytorium spowodowało   szybko do przodu, nic nie było uruchamiane i ciągnięcie nie powiodło się.
  Stało się tak ze względu na skrót, aby uniknąć uruchamiania bazy rebase, gdy możemy szybko przewinąć do przodu,   ale autostash jest ignorowany na tej liście kodowej.


Aktualizacja: Mariusz Pawelski pyta w komentarzach ciekawe pytanie:

Więc wszyscy o tym piszą autostash kiedy robisz rebase (lub pull --rebase).

Ale nikt nie zajmuje się autostashingiem, kiedy robisz normalny ciąg łączy się.
  Więc nie ma automatycznego przełączania? Lub czegoś mi brakuje? Wolę robić git pull --rebase ale OP zapytał o "standard"git pull

Odpowiedź:

The oryginalny wątek omawiając tę ​​funkcję autostash, została ona zaimplementowana pierwotnie zarówno dla git pull (scalanie) i git pull --rebase.

Ale ... Junio ​​C Hamano (opiekun Gita) zauważył, że:

Jeśli pull-merge były czymś, co wywołałoby "irytację"   które wywołały ten temat, z definicji lokalna zmiana się pokrywa   z połączeniem, a ten wewnętrzny "pop ukryty" dotknie ścieżek   połączenie zostało dotknięte i najprawdopodobniej nie spowoduje "Upuszczenia", ale odejdzie   dalsze konflikty do rozwiązania.

Podejrzewam to pull.autostash Konfiguracja nie jest dobrym dodatkiem, ponieważ zachęca do złego, wywołującego ból przebiegu pracy.
  W prostych przypadkach może nie zaszkodzić, ale gdy lokalne zmiany są złożone, aktywnie boli, niż nie mając go, a konfiguracja pozbawia motywacji do wyboru.

Równanie jest nieco inne dla "pull-rebase", jako "rebase"   nalega, aby zacząć od czystego drzewa roboczego, więc "pobierz i   następnie przestań "irytować, czuję się większy." Mam takie podejrzenie   rozluźnienie, które może być bardziej produktywnym rozwiązaniem prawdziwego problemu.

Tak więc, biorąc pod uwagę klasyczne pull-merge, lepiej:

zachęć użytkownika do zastanowienia się nad naturą WIP, którą ma w drzewie roboczym przed uruchomieniem "git pull".
  Czy to zbyt skomplikowana bestia, która może kolidować z tym, co robią inni, lub   czy jest to drobna zmiana, którą może ukryć i wyrzucić?

Jeśli ten pierwszy, będzie o wiele lepiej robić "checkout -b", trzymać   działa, dopóki zmiana lokalna nie zmieni się w nieco lepszą formę i   "commit", przed wciągnięciem do oryginalnej gałęzi.

Jeśli to drugie, lepiej sobie radzi:

  • "git pull",
  • po znalezieniu konfliktów, uruchom      
    • git stash,
    • git merge FETCH_HEAD i
    • git stash pop

111
2018-05-13 08:39



Od wersji 2.4.2 nie jest to jeszcze wdrożone. Być może któregoś dnia. rebase.autoStash stosuje się tylko w przypadku użycia rebase. pull.rebase stosuje się tylko przy użyciu pull. - Randal Schwartz
"To wystarczy, by prosty ciąg gita działał nawet w brudnym drzewie". Jak zauważył Randal, nie jest to jeszcze prawdą. Obecny mistrz pull.c wciąż wybiera die_on_unclean_work_tree. - Pradhan
@Pradhan Zgadzam się. Implementacja właśnie dostała się do mistrza dziś rano i powinna wystarczyć dla gita 2.6. Zmieniłem odpowiedź, aby to wyjaśnić. - VonC
Potwierdziłem, że autostash działa z git 2.5.5. - Joshua Hoblitt
Więc wszyscy piszą o autostash, kiedy to robisz rebase (lub pull --rebase). Ale nikt nie zajmuje się autostashingiem, kiedy robisz to normalnie pull z połączeniami. Więc nie ma automatycznego przełączania? Lub czegoś mi brakuje? Wolę robić git pull --rebase ale OP zapytał o "standard" git pull - Mariusz Pawelski


Aby zaoszczędzić kilka sekund na zbliżających się odkrywców, oto podsumowanie (podziękowania dla @VonC):

git pull --rebase --autostash

16
2017-08-12 06:27



Chodzi o to: po a git config pull.rebase true i git config rebase.autoStash true, wszystko czego będziesz potrzebować to git pull. Właśnie git pull. Żadne inne opcje nie są wymagane. - VonC
Wygląda na to, że potrzebujesz przynajmniej Git 2.9 dla --autostash opcja. The -c rebase.autoStash=true działa w Git 2.6. - ntc2


Zgodnie z powyższym komentarzem ustawienie dwóch wartości konfiguracyjnych obecnie nie działa git pull, ponieważ konfiguracja autostash odnosi się tylko do rzeczywistych rebase. Te polecenia git robią, co chcesz:

git fetch
git rebase --autostash FETCH_HEAD

Lub ustaw jako alias:

git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'

Następnie wykonaj:

git pullr

Oczywiście ten alias może zostać zmieniony zgodnie z życzeniem.


14
2017-07-22 22:56





W Git 2.6+ możesz użyć:

alias gup='git -c rebase.autoStash=true pull --rebase'

To --rebase używa git-pull rebase zamiast merge, więc ustawienia / opcje, jak --ff-only nie będą miały zastosowania.

Używam aliasu do przeciągnięcia --ff-only domyślnie (git pull --ff-only), a następnie może użyć gup (z góry) w przypadku, gdy szybkie przewijanie do przodu nie jest możliwe lub są ukryte zmiany.


5
2018-04-03 18:18





Jak już wspomniano, jest to sposób na zrobienie tego. Możesz użyć go w aliasie, aby zapisać tekst i użyć skrótu lub możesz go użyć w jednym wierszu (może to być także alias)

git stash && git pull --rebase && git stash pop

Wykona to samo, co zrobiłeś, ale w jednym wierszu (&&) i zostanie ustawiony jako alias, nawet będzie krótszy.

Poniższe linie będą wyświetlać zmiany przychodzące / wychodzące przed naciśnięciem przycisku

git log ^master origin/master
git log master ^origin/master

1
2018-05-13 08:40



Takie podejście jest niebezpieczne: jeśli nie ma nic do przechowania, pierwsze polecenie nic nie da, a następnie stash pop wypakuje niektóre losowe rzeczy z wcześniejszych. - John Zwinck