Mam następujący układ repozytorium:
- oddział główny (produkcja)
- integracja
- pracujący
To, co chcę osiągnąć, to wybranie zakresu zatwierdzeń z działającej gałęzi i połączenie ich z gałęzią integracji. Jestem całkiem nowy w Git i nie mogę dowiedzieć się, jak to dokładnie zrobić (wiosenne wybieranie zakresów zatwierdzania w jednej operacji, a nie scalanie) bez zepsucia repozytorium. Wszelkie wskazówki lub przemyślenia na ten temat? Dzięki!
git
git-merge
git-cherry-pick
crazybyte
źródło
źródło
Odpowiedzi:
Jeśli chodzi o zakres zobowiązań, wybieranie
jestnie było praktyczne.Jak wspomniano poniżej przez Keitha Kim , Git 1.7.2+ wprowadził możliwość wybrania szeregu zatwierdzeń (ale wciąż musisz być świadomy konsekwencji wybierania wiśni dla przyszłego scalenia )
Damian komentuje i ostrzega:
Jeśli chcesz, aby wybrać zakres
B
poprzezD
(włącznie) , że byłobyB^..D
.Zobacz „ Git utworzyć gałąź z zakresu poprzednich zatwierdzeń? ” Jako ilustrację.
Jak wspomina Jubobs w komentarzach :
Uwaga: od wersji Git 2.9.x / 2.10 (III kwartał 2016 r.) Możesz wybrać zakres zatwierdzania bezpośrednio w gałęzi sierocej (pusta głowa): patrz „ Jak zmienić istniejącą gałąź w sierotę w git ”.
Oryginalna odpowiedź (styczeń 2010 r.)
rebase --onto
Byłoby lepiej, gdzie można odtworzyć dany zakres popełnić na szczycie swojego oddziału integracyjnego, jak Charles Bailey opisane tutaj .(także poszukaj „Oto jak przeszczepiłbyś gałąź tematu opartą na jednej gałęzi do drugiej” na stronie podręcznika git rebase , aby zobaczyć praktyczny przykład
git rebase --onto
)Jeśli obecna gałąź to integracja:
To odtworzy wszystko między:
first_SHA-1_of_working_branch_range
(stąd~1
): pierwszego zatwierdzenia, które chcesz odtworzyćintegration
” (co wskazuje na ostatnie zatwierdzenie, które chcesz odtworzyć, zworking
gałęzi)na „
tmp
” (który wskazuje, gdzieintegration
wcześniej wskazywał)Jeśli wystąpi konflikt przy odtwarzaniu jednego z tych zatwierdzeń:
git rebase --continue
”.git rebase --skip
”git rebase --abort
” (i odłóżintegration
gałąź natmp
gałąź)Po tym
rebase --onto
,integration
będzie z powrotem na ostatni popełnić oddziału integracyjnego (czyli „tmp
” oddział + wszystkie odtwarzanych zobowiązuje)Przy zbieraniu wiśni lub
rebase --onto
, nie zapomnij, ma to konsekwencje dla kolejnych połączeń, jak opisano tutaj .Omówiono tutaj czyste
cherry-pick
rozwiązanie , które wymagałoby:Ale w każdym razie, kiedy trzeba „odtworzyć” zakres zatwierdzeń, słowo „powtórz” powinno zachęcić cię do korzystania z funkcji „
rebase
” Git.źródło
-m
opcji, jak sobie z nimi radzisz? Czy istnieje sposób na odfiltrowanie tych zatwierdzeń?-m
ma je dla Ciebie obsłużyć, wybierając linię główną, do której odwołuje się-m
parametr wybrany dla tego zbioru.-m
opcję tylko wtedy, gdy trafi w zatwierdzenie nadrzędne, gdy zakres wyborów jest bardzo szeroki? W tej chwili, jeśli zdam, że-m
tak,git cherry-pick a87afaaf..asfa789 -m 1
to dotyczy wszystkich zatwierdzeń w zakresie.error: Commit 8fcaf3b61823c14674c841ea88c6067dfda3af48 is a merge but no -m option was given.
naprawdę zdałem sobie sprawę, że możesz po prostugit cherry-pick --continue
i byłby w porządku (ale nie obejmowałby zatwierdzenia przez rodzica)Od wersji git v1.7.2 cherry pick może przyjmować szereg zatwierdzeń:
źródło
cherry-pick A..B
nie dostanie zatwierdzenia A (będziesz tego potrzebowaćA~1..B
), a jeśli pojawią się jakieś konflikty, git nie będzie automatycznie kontynuował tak, jak robi to rebase (przynajmniej od 1.7.3.1)git cherry-pick A..B C
naiwnie nie działa tak, jak można się tego spodziewać. Nie wybierze wszystkiego z zakresuA..B
i zatwierdziC
! Aby to zrobić, trzeba podzielić na dwie linie, po pierwszegit cherry-pick A..B
, a następniegit cherry-pick C
. Tak więc, gdy masz zasięg, musisz wykonać go osobno.Załóżmy, że masz 2 oddziały,
„branchA”: obejmuje zatwierdzenia, które chcesz skopiować (z „commitA” do „commitB”
„gałąź B”: gałąź, którą chcesz, aby zatwierdzenia były przekazywane z „gałęzi A”
1)
2) pobierz identyfikatory „commitA” i „commitB”
3)
4)
5) W przypadku konfliktu rozwiąż go i wpisz
aby kontynuować proces wyboru.
źródło
Czy na pewno nie chcesz scalać gałęzi? Jeśli działająca gałąź zawiera kilka ostatnich zatwierdzeń, których nie chcesz, możesz po prostu utworzyć nowy oddział z HEAD w żądanym momencie.
Teraz, jeśli naprawdę chcesz wybrać zakres zatwierdzeń, z jakiegokolwiek powodu, eleganckim sposobem na to jest po prostu wyciągnięcie zestawu łat i zastosowanie go w nowej gałęzi integracji:
Zasadniczo to właśnie robi git-rebase, ale bez potrzeby grania w gry. Możesz dodać
--3way
do,git-am
jeśli chcesz scalić. Upewnij się, że nie ma innych plików * .patch w katalogu, w którym to robisz, jeśli postępujesz zgodnie z instrukcjami dosłownie ...źródło
A^
uwzględnićA
.Owinąłem kod VonC w krótki skrypt bash
git-multi-cherry-pick
, aby ułatwić uruchamianie:Obecnie używam tego, ponieważ odbudowuję historię projektu, w którym zarówno kod innej firmy, jak i dostosowania zostały zmieszane razem w tym samym pniu svn. Teraz dzielę główny kod innej firmy, moduły innej firmy i dostosowania na ich własne gałęzie git, aby lepiej zrozumieć modyfikacje w przyszłości.
git-cherry-pick
jest pomocny w tej sytuacji, ponieważ mam dwa drzewa w tym samym repozytorium, ale bez wspólnego przodka.źródło
Wszystkie powyższe opcje podpowiedzą o rozwiązaniu konfliktów scalania. Jeśli scalasz zmiany zatwierdzone dla zespołu, trudno jest rozwiązać konflikty scalania ze strony programistów i kontynuować. Jednak „git merge” wykona scalenie za jednym razem, ale nie można przekazać szeregu poprawek jako argumentu. musimy użyć poleceń „git diff” i „git Apply”, aby wykonać zakres scalania obrotów. Zauważyłem, że „git Apply” zakończy się niepowodzeniem, jeśli plik łatki różni się dla zbyt wielu plików, więc musimy utworzyć łatkę dla każdego pliku, a następnie zastosować. Zauważ, że skrypt nie będzie mógł usunąć plików usuniętych w gałęzi źródłowej. Jest to rzadki przypadek, możesz ręcznie usunąć takie pliki z gałęzi docelowej. Status wyjścia „git Apply” nie wynosi zero, jeśli nie jest w stanie zastosować łatki,
Poniżej znajduje się skrypt.
źródło
Testowałem to kilka dni temu, po przeczytaniu bardzo jasnego wyjaśnienia Vonc.
Moje kroki
Początek
dev
: ABCDEFGHIJtarget
: ABCDE
aniH
Kroki, aby skopiować funkcje bez kroku E i H w oddziale
dev_feature_wo_E_H
git checkout dev
git checkout -b dev_feature_wo_E_H
git rebase --interactive --rebase-merges --no-ff D
gdzie umieszczamdrop
przódE
iH
edytor rebasecommit
Kroki, aby skopiować oddział
dev_feature_wo_E_H
na miejscu docelowym.git checkout target
git merge --no-ff --no-commit dev_feature_wo_E_H
commit
Kilka uwag
cherry-pick
w poprzednich dniachgit cherry-pick
jest potężny i prosty, alemerge
muszę rozwiązać konflikt początkowych zatwierdzeń i duplikatów zatwierdzeń, więc dla jednego lub dwóchcherry-pick
jest w porządku „wybieranie czereśni”, ale dla więcej jest zbyt gadatliwy i gałąź stanie się zbyt złożonagit rebase --onto
źródło
Inną opcją może być połączenie naszej strategii ze zmianą przed zakresem, a następnie scalenie „normalne” z ostatnim zatwierdzeniem tego zakresu (lub rozgałęzienie, gdy jest to ostatnie). Załóżmy więc, że tylko 2345 i 3456 zatwierdzeń mastera zostaną połączone w gałąź funkcji:
w gałęzi funkcji:
źródło