Czy używanie Git Stash jako przepływu pracy jest antypatrunkiem?

25

Ostatnio przyglądałem się, jak ja i mój zespół korzystamy z Git i jak działają nasze przepływy pracy. Obecnie używamy przepływu pracy gałęzi funkcji, który wydaje się działać dobrze.

Widziałem także, że niektóre osoby w naszym zespole korzystają z przepływu pracy opartego na skrytce git . Przepływ pracy przebiega mniej więcej tak:

  • Praca w głównej gałęzi (jak master)
  • Dokonuj zobowiązań w drodze
  • Jeśli chcesz uzyskać zmiany lub zmienić gałęzie, wepchnij swoje niezaangażowane zmiany do skrytki
  • Po zakończeniu aktualizacji usuń zmiany ze schowka.

Powinienem wspomnieć, że ten przepływ pracy jest używany zamiast przepływu pracy gałęzi funkcji. Zamiast brać gałąź i pracować nad nią, programiści tutaj zawsze pracują tylko nad jedną gałąź i wypychają / odrzucają stos, jeśli uznają to za stosowne.

Właściwie nie sądzę, że jest to świetny przepływ pracy, a rozgałęzianie byłoby bardziej odpowiednie niż używanie w ten sposób git stash. Widzę wartość git skrytki jako operację awaryjną, ale nie do używania jej w codziennym, regularnym przepływie pracy.

Czy regularne używanie git stash byłoby uważane za anty-wzór? Jeśli tak, jakie konkretne problemy mogą się pojawić? Jeśli nie, jakie są korzyści?

joshin4colours
źródło
2
Możesz spróbować zapytać współpracowników, czy mieli problemy z przepływem pracy. Jeśli nie, to nie uważam tego za szkodliwe.
AlexFoxGill
@AlexG To ważny punkt. Zadaję tutaj pytanie, aby sprawdzić, czy ludzie znaleźli jakieś „gotchas”.
joshin4colours
3
Jeśli dobrze to rozumiem ... If you need to get changes or switch branches, push your uncommitted changes onto the stash- właśnie do tego służy skrytka.
3
@MichaelT Mój lokalny oddział zezwala na wszystko. Bezwarunkowo.
maaartinus
2
Mój wzór to: -> nie używaj git stash -> używaj gałęzi funkcji -> zapisz pracę w toku z komunikatem zatwierdzenia „wip”. -> interaktywne rebase na gałęzi zgnieść WIP użytkownika w jeden znaczący popełnić, ale dla swoich lokalnych unpushed jedyne zmiany. -> push to remote -> scal do master (i push) odpowiednio do twojego przepływu pracy git.
Michael Durrant

Odpowiedzi:

31

Z książki Git SCM :

Często, gdy pracujesz nad częścią swojego projektu, rzeczy są w nieuporządkowanym stanie i chcesz zmienić gałęzie, aby trochę popracować nad czymś innym. Problem polega na tym, że nie chcesz wykonywać częściowo wykonanej pracy, abyś mógł później wrócić do tego punktu. Odpowiedzią na ten problem jest polecenie git stash.

Składowanie przyjmuje stan „brudny” katalogu roboczego - to znaczy zmodyfikowane pliki śledzenia i zmiany etapowe - i zapisuje je na stosie niedokończonych zmian, które można ponownie zastosować w dowolnym momencie.

Biorąc pod uwagę ten opis, powiedziałbym, że jest to Anty Wzór. Zbyt uproszczonym wyjaśnieniem Git Stash byłoby to, że jest to „Wytnij i wklej” kontroli źródła. Bierzesz kilka zmienionych plików, „przechowujesz” je w pisaku przytrzymującym poza normalnym procesem rozgałęziania Git, a następnie ponownie stosujesz te zmiany w innym oddziale.

Cofając się nieco dalej, zobowiązanie do opanowania jest tutaj anty-wzorem . Użyj oddziałów. Do tego zostały zaprojektowane.

To naprawdę sprowadza się do tego:

Możesz wbić śrubę w ścianę, która zatrzyma obraz, ale należy użyć śrubokręta. Nie używaj młotka, gdy śrubokręt stoi tuż obok ciebie.

O zatwierdzeniu „złamanego” kodu

Chociaż jest to opinia, doszedłem do tej opinii z doświadczenia.

Popełniaj wcześnie i często popełniaj. Zatwierdź tyle uszkodzonego kodu, ile chcesz. Zobacz swoją lokalną historię zatwierdzeń jako „zapisz punkty”, gdy coś hackujesz. Po wykonaniu logicznej pracy, dokonaj zatwierdzenia. Pewnie, że może wszystko zepsuć, ale to nie ma znaczenia, dopóki nie popchniesz tych zmian. Przed pchnięciem, rozłóż bazę i zmiażdż swoje zobowiązania.

  1. Utwórz nowy oddział
  2. Hack hack hack
  3. Zatwierdź uszkodzony kod
  4. Poleruj kod i spraw, by działał
  5. Zatwierdź działający kod
  6. Rebase and Squash
  7. Test
  8. Naciśnij, gdy testy przebiegają pomyślnie

W przypadku OP ten wątek wiadomości jądra systemu Linux może być interesujący, ponieważ wydaje się, że niektórzy członkowie zespołu OP używają Git w podobny sposób.

@RibaldEddie powiedział w komentarzu poniżej:

Przede wszystkim skrytka nie znajduje się poza „rozgałęzionym przepływem pracy”, ponieważ pod maską skrytka jest tylko inną gałęzią.

(na ryzyko narażenia się na gniew wielu ludzi)

Linus powiedział:

Dzięki „git stash” możesz także mieć wiele różnych ukrytych rzeczy, ale one nie ustawiają się w kolejce - są to po prostu losowe, niezależne łaty, które schowałeś, ponieważ były w pewnym momencie niewygodne.

Myślę, że @RibaldEddie próbuje powiedzieć, że możesz używać git stashw przepływie pracy gałęzi funkcji - i to prawda. git stashProblemem nie jest wykorzystanie tego. Jest to połączenie zobowiązania do opanowania i używania git stash. To jest anty-wzór.

Wyjaśnianie git rebase

Z komentarza @ RibaldEddie:

Rebasing jest bardziej podobny do wklejania kopii, a jeszcze gorzej modyfikuje popełnioną historię.

(Moje podkreślenie)

Modyfikacja historii zmian nie jest złą rzeczą, o ile jest to lokalna historia zmian . Jeśli wyreżyserujesz zatwierdzenia, które już wypchnąłeś, zasadniczo osierocisz każdego, kto korzysta z twojego oddziału. To jest złe.

Powiedzmy, że dokonałeś kilku zmian w ciągu dnia. Niektóre zmiany były dobre. Niektóre ... nie tak dobrze. git rebasePolecenia w połączeniu z tępienia swoich zobowiązuje to dobry sposób, aby oczyścić się z lokalnym popełnienia historię. Fajnie jest łączyć się w jednym zatwierdzeniu z oddziałami publicznymi, ponieważ pozwala to zachować historię zatwierdzeń udostępnionych oddziałów twojego zespołu w czystości. Po aktualizacji, będziesz chciał ponownie przetestować, ale jeśli testy zakończą się pomyślnie, możesz wcisnąć jedno czyste zatwierdzenie zamiast kilku brudnych.

Jest jeszcze jeden interesujący wątek jądra Linux na czystej historii zatwierdzeń .

Znowu od Linusa:

Chcę czystej historii, ale to naprawdę oznacza (a) czystą i (b) historię.

Ludzie mogą (i prawdopodobnie powinni) opierać swoje prywatne drzewa (swoją własną pracę). To jest porządek . Ale nigdy nie kodują inne narody. To „niszczyć historię”

Więc część historyczna jest dość łatwa. Jest tylko jedna główna zasada i jedno drobne wyjaśnienie:

  • Nigdy nie wolno NIGDY niszczyć historii innych ludzi. Nie wolno bazować na zobowiązaniach innych osób. Zasadniczo, jeśli nie ma na nim Twojego podpisu, jest poza limitem: nie możesz go zmienić, bo to nie jest twoje.

    Zauważ, że tak naprawdę chodzi o historię innych ludzi , a nie o kodeks innych ludzi . Jeśli przesłali ci różne rzeczy jako łatkę przesłaną e-mailem, a ty zastosowałeś ją za pomocą „git am -s”, to jest to ich kod, ale twoja historia.

    Możesz więc zwariować na punkcie „git rebase”, nawet jeśli nie napisałeś kodu, o ile sam zatwierdzenie jest twoje prywatne.

  • Niewielkie wyjaśnienie zasady: po opublikowaniu Twojej historii na jakiejś stronie publicznej inne osoby mogą z niej korzystać, więc teraz nie jest to już Twoja prywatna historia.

    Tak więc drobnym wyjaśnieniem jest to, że nie chodzi tylko o „twoje zatwierdzenie”, ale także o to, że jest prywatne dla twojego drzewa, a ty jeszcze go nie wypchnąłeś i nie ogłosiłeś.

...

Teraz „czysta” część jest nieco bardziej subtelna, chociaż pierwsze zasady są dość oczywiste i łatwe:

  • Zachowaj czytelność swojej historii

    Niektórzy ludzie to robią, po prostu wypracowując sobie coś w głowie i nie popełniając błędów. ale to bardzo rzadkie i dla reszty z nas, podczas pracy nad naszymi problemami, używamy „git rebase” itp.

    Więc „git rebase” nie jest zły. Ale ma rację tylko wtedy, gdy jest to TWÓJ BARDZO WŁASNY PRYWATNY drzewo git.

  • Nie wystawiaj swojego badziewia.

    Oznacza to: jeśli nadal znajdujesz się w fazie „git rebase”, nie wypychasz go. Jeśli nie jest gotowy, wysyłasz łatki lub używasz prywatnych drzewek git (tak jak „zamiennik serii poprawek”), o których nie mówisz ogółowi społeczeństwa.

(moje podkreślenie)

Wniosek

W końcu OP ma kilku programistów, którzy robią to:

git checkout master
(edit files)
git commit -am "..."
(edit files)
git stash
git pull
git stash (pop|apply)

Istnieją tutaj dwa problemy:

  1. Programiści zobowiązują się do opanowania. Zablokuj to natychmiast. To naprawdę największy problem.
  2. Programiści stale używają git stashi git pullnadrzędnie, kiedy powinni używać gałęzi funkcji.

Nie ma nic złego w używaniu git stash- szczególnie przed ściągnięciem - ale używanie git stashw ten sposób jest anty-wzorem, gdy są lepsze przepływy pracy w Git.

Ich użycie git stashczerwonego śledzia. To nie jest problem. Problemem jest zobowiązanie się do opanowania.

Greg Burghardt
źródło
4
Wow, to nie w porządku. Przede wszystkim skrytka nie znajduje się poza „rozgałęzionym przepływem pracy”, ponieważ pod maską skrytka jest tylko inną gałęzią. Pomysł, że jest to przepływ pracy kopiuj-wklej, nie ma sensu. Rebasing jest bardziej podobny do wklejania kopii, a jeszcze gorzej modyfikuje popełnioną historię. Wreszcie przepływ pracy jest całkowicie bezużyteczny, gdy tylko trzeba udostępnić pracę w toku współpracownikom, ponieważ rozpada się ona po wprowadzeniu zmian. To, jak ma sześć głosów, jest zadziwiające.
RibaldEddie
8
@RibaldEddie: Nie ma nic złego w przebudowywaniu i przepisywaniu historii zmian, o ile jest to lokalna historia zmian. Po wprowadzeniu tych zmian Twój komentarz byłby poprawny, ale przeczytaj moją odpowiedź ponownie. Mówi: „Przed pchaniem, rozłóż bazę i zmiażdż swoje zobowiązania”. To lokalna historia zatwierdzeń, która jest całkowicie pod twoją kontrolą.
Greg Burghardt
1
@RibaldEddie: Wyjaśniłem swoją odpowiedź. Trzeba było trochę posprzątać.
Greg Burghardt
Podam trochę więcej kontekstu w mojej własnej odpowiedzi.
RibaldEddie,
Zobacz moją odpowiedź poniżej - chociaż zobowiązanie do opanowania jest anty-wzorem, nie jest to prawdziwy problem.
RibaldEddie
7

Osobiście używam tylko stashdo krótkich, nieoczekiwanych przerw, jak ktoś zadający pytanie, które wymaga zmiany na inny oddział. Robię to, ponieważ wcześniej zapomniałem o skrytkach, wtedy nie zastosowałyby się czysto. Regularne zatwierdzenia w gałęziach funkcji są o wiele trudniejsze do zapomnienia i łatwiejsze do scalenia, więc teraz mam tendencję do po prostu złamania zatwierdzenia, a następnie zrobienia git reset HEAD~1lub zmiany bazy, jeśli nie chcę tego zachować później.

Jednak wielką zaletą rozproszonej kontroli wersji jest to, że ludzie mogą korzystać z preferowanego przepływu pracy we własnych repozytoriach, o ile repozytoria udostępnione spełniają standardy. Upewniłbym się, że ludzie nie korzystają tylko z stashprzepływu pracy, ponieważ nie mają wystarczającego przeszkolenia lub świadomości alternatyw, ale jeśli nadal wybiorą przepływ pracy, który wydaje ci się nieoptymalny, zostawiłbym to.

Karl Bielefeldt
źródło
1

Myślę, że częścią twojego pytania, która jest anty-wzorzec, jest użycie jednej wspólnej gałęzi master . Jeśli jednak należy uwzględnić gałąź rozwijającą oprócz gałęzi głównej, a następnie użyć skrytek do obsługi własnych przełączników kontekstu w gałęzi rozwijania, nie byłoby to anty-wzorcem i bardzo ściśle odzwierciedla część przepływu pracy opisują takie organizacje jak Etsy i Facebook.

To powiedziawszy, powyższa odpowiedź @Greg Burghardt jest nieco zbyt przychylna tak zwanemu przepływowi pracy git-flow lub gałęzi funkcji. Zwykłem opowiadać się za podobną strategią, ale po uświadomieniu sobie, że dodaje ona niepotrzebnej złożoności i stwarza fałszywe poczucie bezpieczeństwa, już tego nie robię. Jest to również pozostałość po czasach zdecentralizowanych systemów kontroli wersji, takich jak subversion.

Po pierwsze, ponieważ Git jest zdecentralizowanym systemem kontroli wersji, w przeciwieństwie do subversion, lokalne repozytorium programisty jest zasadniczo gigantyczną gałęzią samego kodu. To, co jednostka rozwija lokalnie, nie ma wpływu i nie powinno mieć wpływu na innych członków zespołu, chyba że uszkodzony lub błędny kod zostanie przekazany do dowolnych gałęzi udostępnianych w repozytorium współdzielonym.

Polecenie rebase może jednak uszkodzić historię gałęzi, gdy występuje konflikt scalania w jednym z odtwarzanych zatwierdzeń. Od http://ryantablada.com/post/the-dangers-of-rebasing-a-branch

Reszta bazy przebiega bezproblemowo, wszystkie testy zdają się pomyślnie. PR jest tworzony.

A potem napisany jest więcej kodu, który opiera się na właściwości commentsForAllPosts i wszystko jest zepsute. Ale do kogo idziemy i proszymy o pomoc? git blame pokazuje, że wiersz kodu został napisany tylko przez inżyniera po stronie serwera i podnosi ręce.

Teraz twój inżynier z przodu jest na wakacjach, na zwolnieniu lekarskim lub kto wie. Nikt nie może ustalić, jak powinien wyglądać ten kod!

Rebase zabił zdolność zespołu do spojrzenia na historię, aby dowiedzieć się, co poszło nie tak, ponieważ wszelkie konflikty scalania w gałęzi potomnej są zabijane, a oryginalny kod zostaje utracony na zawsze.

Gdyby pojawił się ten sam konflikt scalania i zastosowano scalenie, wina wskazywałaby, że ten wiersz kodu został dotknięty w procesie scalania, zatwierdzenie w gałęzi nadrzędnej i zatwierdzenie w gałęzi potomnej. Niektórzy bawią się trzema kombinacjami i możesz przywrócić pierwotne zamiary z powrotem do bazy kodu i pracować bez tony głowy drapiącej palcem w palec. A wszystko, co naprawdę miałeś, to kolejne zatwierdzenie

Ponadto model wielu rozgałęzień zakłada, że ​​żadne dwa rozgałęzienia nie mogą nigdy zawierać współzależnych zmian kodu. Gdy tak się stanie, programista musi teraz żonglować jeszcze większą liczbą gałęzi, aby działać wydajnie.

Zasadniczy anty-wzorzec, który widzę, nie jest związany z gałęziami a zapasami, ale raczej z rodzajami problemów, o których niektórzy bardzo mądrzy ludzie rozmawiają od jakiegoś czasu: czy masz zaufanie do swojego kodu za pomocą testy jednostkowe i dobra architektura? Czy jesteś w stanie wprowadzać przyrostowe zmiany w kodzie, aby programiści mogli łatwo zorientować się w zmianach i zrozumieć, co zrobi zmiana? Czy Twoi programiści nawet raz uruchamiają nowy kod, aby sprawdzić, czy rzeczywiście działa? (Tak, widziałem to wcześniej).

Jeśli odpowiedź na te pytania brzmi „nie”, to tak naprawdę nie ma znaczenia, ile masz gałęzi - programiści stwierdzą, że kod jest gotowy, działa i nadaje się do produkcji, gdy tak naprawdę nie jest, i żadna liczba gałęzi nie będzie pomożemy ci, gdy ten kod i tak przejdzie do produkcji.

RibaldEddie
źródło
2
Twój komentarz na temat zmiany bazy danych z problemami z rozwiązaniem scalania nie jest prawdziwy. Rebase to ten sam rodzaj scalania, co rzeczywiste scalenie. Git po prostu łączy zobowiązania pod maską. Odzyskiwanie i rozwiązywanie konfliktu scalania nie szkodzi historii zatwierdzeń. Odzyskiwanie i nieprawidłowe rozwiązywanie konfliktu scalania szkodzi rzeczom, co jest równie prawdopodobne w przypadku normalnego scalenia. Muszę się zgodzić, że gałęzie funkcji zwiększają złożoność, ale może to być niezbędna złożoność, jeśli programiści muszą żonglować wieloma niepowiązanymi zmianami.
Greg Burghardt
Więc mówisz, że fuzje mogą zniszczyć historię ?! Brzmi jak usprawiedliwienie unikania posiadania zbyt wielu gałęzi!
RibaldEddie
1
Połączenia nie mogą zniszczyć historii. Myślę, że możesz nie rozumieć, jak działa zmiana i łączenie. Kiedy wywoływany jest konflikt scalania, to człowiek musi go rozwiązać. Jeśli człowiek rozwiązuje to niepoprawnie, nie możesz winić Gita (lub SVN, CVS lub {wstaw tutaj kontrolę źródła}).
Greg Burghardt,
To, co mówisz, jest w pewnym sensie sprzeczne z tym, co powiedziałeś wcześniej. Czy czytałeś artykuł, który zacytowałem? Czy rozumiesz kontekst, w którym rebase straci historię?
RibaldEddie,
1
Czytam artykuł „W Keen staramy się przesuwać nasz kod po prawie każdym zatwierdzeniu.” To brzmi dla mnie szalenie. Albo robią zbyt duże zmiany, albo wypychają kod, który nie jest jeszcze gotowy. Jeśli natychmiast podasz do publicznej wiadomości wszystkie swoje zobowiązania, tak, zmiana bazy spowoduje problemy. To zasada „doktorze, doktorze, boli mnie, kiedy to robię”.
Kyralessa
1

git stashjest narzędziem. Sam w sobie nie jest wzorem ani anty-wzorem. To narzędzie, podobnie jak młot to narzędzie. Używanie młotka do wbijania gwoździ jest wzorem, a używanie młotka do wkręcania śrub jest anty-wzorem. Podobnie istnieją przepływy pracy i środowiska, w których git stashmożna użyć właściwego narzędzia, oraz przepływy pracy i środowiska, w których jest ono nieprawidłowe.

Przepływ pracy „wszyscy zatwierdzają i pchają do głównej linii” to taki, który działa całkiem rozsądnie tam, gdzie nie ma zmian wysokiego ryzyka. Jest często używany w środowiskach svn, gdzie jest jeden autorytatywny serwer centralny, który ma kod.

Git jednak wiąże się z jednym serwerem centralnym. Posiadające wszystkie deweloperzy robią commit, pull(lub rebasejeśli jesteś do tego), pushcały czas mogą mieć duży bałagan.

Największe problemy przychodzą na myśl, że coś w toku jest zepsute i musisz popracować nad priorytetowym błędem. Oznacza to, że musisz nieco odłożyć tę pracę na bok, pobrać najnowsze, pracować nad tym bez uprzedniej pracy w toku, powodując problemy z kompilacją, którą próbujesz wykonać.

Do tego git stashbyłoby właściwym narzędziem do użycia.

Istnieje jednak większy problem czający się w centrum tego przepływu pracy. Czy to jest to wszystkie role gałęzi kontroli wersji są w jednym odgałęzieniu. Linia główna, rozwój, konserwacja, akumulacja i pakowanie są w Master. To jest problem. (Zobacz Zaawansowane strategie rozgałęziania SCM, aby uzyskać więcej informacji na temat tego podejścia do oddziałów)

I tak, powiedziałeś, że nie jest to świetny przepływ pracy i że są z tym problemy. Problem nie dotyczy jednak narzędzia git stash. Problemem jest brak wyraźnego rozgałęziania ról lub niezgodnych zasad .

git stashjest jednak coś, z czego korzystałem, kiedy miałem trochę czasu, kiedy budowałem, wpadłem w lepki stan, którego nie byłem pewien, czy to był właściwy ... więc ukryłem swoje zmiany a następnie zbadał inne podejście do rozwiązania problemu. Jeśli to zadziałało - świetnie, odrzuć rzeczy ze schowka i kontynuuj. Jeśli druga eksploracja stała się trudniejsza, powróć do poprzedniej zmiany i ponownie zastosuj skrytkę, aby nad tym popracować. Alternatywą byłoby zatwierdzenie, pobranie, rozgałęzienie, a następnie kontynuacja w tym nowym oddziale lub powrót i zresetowanie go. Pytanie brzmi: czy naprawdę warto umieścić to w historii, gdy jest to coś, co chcę trochę zbadać?

git stashnie jest anty-wzorem. Używanie git stashjako alternatywy dla rozgałęziania, podczas gdy wszyscy zobowiązują się do Mistrza, jest anty-wzorem - ale nie z powodu git stash.

Jeśli jeszcze go nie trafiłeś, poczekaj, aż pojawią się problemy z kompilacjami , gdy ktoś musi wprowadzić znaczące zmiany architektoniczne w wielu plikach (i konfliktach scalania) lub jakiś nieprzetestowany kod w toku, który wycieka do produkcji w tym celu anty-wzór, aby cię dogonić.

Społeczność
źródło