2009-09-25 19 views
5

Przeszukałem dokumentację git merge i rebase, a coś nie zapada w pamięć. Aktywnie pracuję nad projektem w Git i muszę udostępniać określone kamienie milowe innym programistów. Chcę udostępnić kod dokładnie w takiej postaci, w jakiej znajduje się w każdym etapie/wydaniu, ale nie wszystkie moje małe zatwierdzenia poprzedzające każde wydanie.Git rebase/merge dla publicznych wydań

Jak utworzyć gałąź wydania odzwierciedlającą gałąź rozwojową, w której zatwierdzenia w gałęzi wydania zawierają po kilka zatwierdzeń z gałęzi rozwojowej? Innymi słowy, gałąź wydania powinna mieć skompresowaną historię, ale poza tym powinna pasować do gałęzi rozwojowej.

Początkowo myślałem, że używanie oddzielnej gałęzi i używanie git merge - squash będzie skuteczne, tworząc nowy oddział z serią zatwierdzeń, które odzwierciedlają pełen zestaw zmian między poszczególnymi wersjami. Rozumiem teraz, że git merge - squash nie działa w przypadku powtarzających się zastosowań.

Git rebase będzie działać, aby zwinąć kilka commitów w jedno duże zatwierdzenie, ale ponieważ zmienia historię commitowania, nie zmieniłaby mojej prywatnej historii ani publicznych wydań?

Nie chcę stracić historii małych zmian, ale chcę popchnąć połączone zatwierdzenia do wspólnego serwera.

Odpowiedz

7

Z pewnością, jeśli twoje zobowiązania są warte zachowania i stanowią twoją pracę na rzecz publicznego wydania, to powinny one stanowić część twojej opublikowanej historii? Jeśli nie chcesz publikować pełnej historii repozytorium, możesz lepiej użyć tylko wersji git archive, aby utworzyć pakiety wydania.

Powiedziawszy, że jeśli naprawdę chcesz stworzyć gałąź wydania z oddzielną historią, to jest to możliwe. Przygotowujesz się jednak do zwiększenia nakładów na konserwację, ponieważ nigdy nie możesz łączyć się z prywatną historią z publiczną gałęzią dystrybucji, ponieważ spowoduje to przeniesienie całej prywatnej historii do twojej gałęzi wydawniczej. Oto co robi git; śledzi, skąd pochodzą zmiany.

Możesz łączyć się z oddziałem wydawniczym z oddziałem prywatnym, ale ponieważ twoja praca (prawdopodobnie) pochodzi z prywatnej branży, nie przyniesie ci to zbyt wiele. Najłatwiejszą opcją jest posiadanie oddzielnej gałęzi wydania, która zawiera tylko migawki zatwierdzenia stanu oddziału prywatnego w punktach wydania.

Zakładając, że osiągnęła punkt, w którym chcesz utworzyć popełnić na gałęzi uwalniania (release) w oparciu o aktualny popełnić w prywatnej branży (private) i przy założeniu, że masz drzewo ma zostać wydany wyrejestrowany z bez zmian w indeksie, oto, co możesz zrobić.

# Low-level plumbing command to switch branches without checking anything out 
# (Note: it doesn't matter if this branch hasn't yet been created.) 
git symbolic-ref HEAD refs/heads/release 

# Create a new commit based on the current index in the release branch 
git commit -m "Public release commit" 

# Switch back to the private branch 
git checkout private 

Można to zrobić dla każdego wydania (lub sub-release) oraz nowy popełnić będą budowane bezpośrednio na szczycie poprzedniej wersji bez zastosowano jedną z prywatnych historii.

+0

To na pewno to robi. Pracował dla mnie :) –

+0

Dzięki, Charles. To robi to, czego szukam. – Neil

2

Po prostu utwórz nowy oddział i wykonaj wszystkie zgniatania. Opublikuj to. Twoje mniejsze zatwierdzenia będą nadal obecne w innych oddziałach.

Moja Workflow za to będzie wyglądać mniej więcej tak:

git co -b release_branch_squash release_branch_with_all_commits 

git rebase last_release_tag 

Teraz nadszedł czas, aby poradzić sobie ze wszystkimi konfliktami, które mogą się pojawić. Naprawdę nie wiem, wiedzieć, jak tego uniknąć. Zwykle nie stanowi to większego problemu. Moje repozytorium git zapisało już większość rozwiązań do rozwiązywania konfliktów.

git rebase --interactive last_release_tag 

To przyniesie vim. Dla wszystkich wersji, które chcę zgnieść, zastępuję pick z squash. Następnie zapisz i wyjdź. Gotowe.

+0

Czy możesz opracować? Z komentarzy takich jak http://stackoverflow.com/questions/1464642/git-merge-squash-repeatedly/1465119#1465119 wygląda na to, że powtarzające się scalanie - squash nie zadziała. Kiedy próbuję tego, otrzymuję bardzo długą listę konfliktów, mimo że pliki mają wspólną historię. Jeśli rozumiem poprawnie, git merge - squash tworzy nowe zatwierdzenie, które nie udostępnia historii starych zatwierdzeń, więc przyszłe scalenia nie mają wspólnych przodków. Opisałeś zachowanie, którego pragnę, ale potykam się o to, żeby Git to zrobił. – Neil

+0

Zaktualizowałem odpowiedź za pomocą proponowanego przepływu pracy. Chociaż muszę przyznać, że rozwiązanie Charlesa Bayleya może być lepiej dostosowane do twoich potrzeb. – davrieb

Powiązane problemy