Polecenie, którego szukasz, jest git rebase
konkretną -i/--interactive
opcją.
Zakładam, że chcesz zostawić zatwierdzenie c w gałęzi A i że naprawdę masz na myśli, że chcesz przenieść pozostałe zatwierdzenia do innych gałęzi, zamiast scalać, ponieważ scalenia są proste. Zacznijmy od manipulowania gałęzią A.
git rebase -i <SHA1 of commit a>^ branchA
Te ^
środki poprzedni popełnienia, więc to polecenie mówi zmieniają bazę oddział używając popełnić przed „a” jako podstawy. Git przedstawi listę zatwierdzeń z tego zakresu. Zmień ich kolejność i powiedz gitowi, aby zgasił odpowiednie:
pick c ...
pick a ...
squash d ...
squash e ...
squash g ...
pick b
squash f
Teraz historia powinna wyglądać tak:
c - [a+d+e+g] - [b+f] (branchA)
/
--o-x-x-x-x-x-x-x-x-x-x (master)
Teraz weźmy nowo zgniecione zatwierdzenie b + f dla branchB.
git checkout branchB
git cherry-pick branchA # cherry-pick one commit, the tip of branchA
I to samo dla a + d + e + g dla mistrza:
git checkout master
git cherry-pick branchA^
Na koniec zaktualizuj gałąźA, aby wskazywała na c:
git branch -f branchA branchA^^
Powinniśmy teraz mieć:
c (branch A) - [a+d+e+g] - [b+f] (dangling commits)
/
--o-x-x-x-x-x-x-x-x-x-x-[a+d+e+g] (master)
\
x-x-x-x-x-[b+f] (branchB)
Zauważ, że jeśli masz wiele zatwierdzeń, które chcesz przenosić między gałęziami, możesz ponownie użyć rebase (nieinteraktywnie):
# create a temporary branch
git branch fromAtoB branchA
# move branchA back two commits
git branch -f branchA branchA~2
# rebase those two commits onto branchB
git rebase --onto branchB branchA fromAtoB
# merge (fast-forward) these into branchB
git checkout branchB
git merge fromAtoB
# clean up
git branch -d fromAtoB
Na koniec zastrzeżenie: całkiem możliwe jest zmienić kolejność zatwierdzeń w taki sposób, że niektóre nie mają już czystego zastosowania. Może to być spowodowane tym, że wybrałeś złą kolejność (umieszczając łatkę przed zatwierdzeniem wprowadzającą poprawioną funkcję); w takim przypadku będziesz chciał przerwać rebase ( git rebase --abort
). W przeciwnym razie będziesz musiał inteligentnie rozwiązać konflikty (tak jak w przypadku konfliktów scalania), dodać poprawki, a następnie biec, git rebase --continue
aby przejść dalej. Instrukcje te są również zawarte w komunikacie o błędzie wyświetlanym w przypadku wystąpienia konfliktu.