2013-05-08 10 views
11

Mam następujący git obieg:Czy zgniatanie to jedna najlepsza praktyka (w tym konkretnym przepływie pracy)?

  1. Utwórz nową cechą oddziału
  2. Prace nad fabularnym oddziału
  3. Commit często
  4. Gdy funkcja jest zakończona, wtopić się master oddziału
  5. spłukać i powtórzyć

Czasami jednak potrzebuję aby przywrócić całą funkcję z master. Może to wymagać dużej liczby revert ing. (Powodem konieczności przywrócenia funkcji jest posiadanie strony internetowej działającej na jednym repo, a następnie skryptu, który wdraża witrynę do naszej witryny produkcyjnej lub witryny testowej, obie są wykonywane z naszego głównego oddziału. Nie pytaj, po prostu nad tym pracowałem. Czasami pracuję nad czymś, co wystawiam na scenie, ale wtedy trzeba dokonać natychmiastowej zmiany, więc potrzebowałem jakiegoś sposobu, aby wyciągnąć moje zmiany w porządku. do czyszczenia repo ..)

Myślę, że najłatwiej to zrobić, jeśli każda gałąź funkcji ma tylko jedno zatwierdzenie. Wtedy mógłbym revert zatwierdzić. Tak więc naturalnie myślę o zgnieceniu wszystkich zatwierdzeń gałęzi funkcji w jeden, przed scaleniem go w master.

Więc teraz mój workflow wyglądałby następująco:

  1. Utwórz nową funkcję oddziału
  2. Prace nad fabularnym oddziału
  3. Commit często
  4. Gdy funkcja jest kompletna git rebase -i HEAD ~ number_of_commits (lub jeśli oddział zdalny jest dostępny, pochodzenie/cecha-gałęzi)

Czy są jakieś problemy z tą logiką? Czy jest to sprzeczne z najlepszymi praktykami? Zrobiłem kilka testów samemu i cały przepływ pracy wydaje się przebiegać sprawnie i rozwiązuje mój problem, ale chciałem uruchomić ten pomysł przez innych (mądrzejszych) Git-ererów, aby sprawdzić, czy coś jest z tym nie tak.

Dzięki!

+1

Czy spojrzałeś na 'git merge --squash'? Czy istnieje jakiś szczególny powód, dla którego wybrałeś 'rebase' zamiast używać' squash merge'? Nie masz historii liniowej, gdy wykonujesz 'scalanie', ale zatwierdzenia w gałęzi operacji będą nadal miały liniową historię, a ty będziesz miał tylko jedno scalenie. – Tuxdude

+0

Po prostu przyjrzałem się temu scenariuszowi. Bardzo dobrze. Nie wiem, którego użyć więcej (może "rebase", ponieważ wyrzucam te gałęzie dość często), ale posiadanie historii w moim dziale funkcji jest miłe. Dzięki za pomoc! –

+1

@Tuxdude: Rozważ podjęcie tej odpowiedzi. Prawdopodobnie * jest * odpowiedzią. – sleske

Odpowiedz

12

Powinieneś poprzestać na łączeniu squasha z git, tj. git merge --squash, aby niepotrzebnie nie przepisywać historii.

Zarówno git merge --squash, jak i git rebase --interactive można użyć do wygenerowania zatwierdzenia zgniecionego z tym samym wypadkowym drzewem roboczym, ale mają one służyć 2 całkowicie innym celom.Twoje drzewo ostatecznie wygląda inaczej w obu przypadkach.

drzewo początkowa:

a -- b -- c -- d master 
     \ 
     \-- e -- f feature1 

Po git checkout master; git merge --squash feature1; git commit:

a -- b -- c -- d -- F master 
     \ 
     \-- e -- f feature1 

Po git checkout master; git rebase -i feature1 i decyduje się pick c i squash d:

a -- b   /-- F master 
     \  /
     \-- e -- f feature1 

Jak widać z tą różnicą, robisz nie przepisuj historii dowolnego oddziału przy użyciu git merge --squash, ale kończy się przepisywanie historii master podczas korzystania z git rebase -i.

Należy również zauważyć, że faktyczne zatwierdzenia (dla tych, które zostały zgniecione) byłyby obecne w historii git w obu przypadkach, tak długo, jak masz jakieś odniesienie do gałęzi lub znacznika, przez które te poprawki są osiągalne.

Innymi słowy, w powyższym przykładzie, jeśli usuniesz feature1 po zrobieniu merge --squash, to nie będzie w stanie rzeczywiście zobaczyć zobowiązuje e lub f w przyszłości (zwłaszcza po 90 dni reflog okresie). To samo dotyczy zgłoszeń c i d w przykładzie.

+0

Dziękuję za wspaniałe wyjaśnienie! –

3

Jedną z wad tej metody jest to, że znacznie ogranicza ona użyteczność git bisect w śledzeniu błędów w kodzie.

Powiedział, że jeśli okaże się powracanie całą funkcję wystarczająco często, aby gdzie szukasz sposobów, aby zoptymalizować ten proces, można zadać sobie pytanie, czy jesteś wtopienie master zbyt szybko. Możesz rozważyć użycie wielu długich gałęzi, aby lepiej skonfigurować przepływ pracy, który pasuje do Twojego projektu.

+0

Powodem jest to, że mam stronę internetową, która działa z jednego repo. Stamtąd używamy skryptu, który wdraża witrynę do naszej witryny Produkcyjnej lub miejsca postoju. Oba są wykonywane z naszej gałęzi 'master'. (Nie pytaj, to jest właśnie to, z czym miałem do czynienia). Czasami pracuję nad czymś, co mam na scenie, ale wtedy trzeba dokonać natychmiastowej zmiany, więc potrzebowałem jakiegoś sposobu na zrobienie moich zmian w celu oczyszczenia repo. –

+0

Jeśli to możliwe, spróbowałbym zmodyfikować skrypt, aby wdrożyć inny oddział do etapowania (lub najlepiej pozwolić na rozmieszczenie dowolnych gałęzi w dowolnej lokacji). Ale jeśli nie możesz, twoje proponowane podejście wydaje się rozsądne. –

+0

Tak, pracuję nad tym z naszym zespołem, ale na razie zamierzałem sprawdzić, czy jest na to dobry sposób. Dzięki za pomoc! –

Powiązane problemy