2013-04-11 19 views
7

Przyjmijmy następujące wykresu:Jak mogę znaleźć pierwsze zatwierdzenie oddziału?

A -- B -- C -- D -- E -- F 
     \ 
     G -- H -- I 

chciałbym znaleźć G aby móc interaktywnego rebase do Squash zobowiązuje (ale nadal zachować jeden popełnić na gałęzi tematu), które zostaną poddane przeglądowi i scalone później. Nie chcę po prostu zmieniać nazwy całej gałęzi, ponieważ chcę zachować informację, że istnieje gałąź i została ona scalona.

(Wiem, że mogę spojrzeć na historię i po prostu użyć sumy kontrolnej SHA zatwierdzenia, ale szukam sposobu, aby to zrobić bez ręcznego wykopywania informacji lub liczenia, ile commitów zostało zrobionych i użyć ~ z HEAD z tym numerem).

Edit: wyjaśnienie tego, co chcę osiągnąć:

Chcę tego uniknąć:

A -- B -- C -- D -- E -- F -- J 
     \     /
     G -- H -- I -- -- -- - 

i mieć coś takiego w zamian:

A -- B -- C -- D -- E -- F -- J 
     \     /
     G' -- -- -- -- -- -- - 

Innymi słowy, chcesz zmiażdżyć zatwierdzenia za pomocą interaktywnego rebase na gałęzi tematu w jeden, ale nadal trzymaj gałąź i używaj regularnego scalania, aby zintegrować zmiany z gałęzi tematu do wzorca.

+0

Zobacz http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git –

+1

To jest inne pytanie. Wyjaśniono to nawet tak samo jak ja. Jeśli przetłumaczymy to na mój przykład, on szuka "B", ale szukam "G". –

Odpowiedz

11

Brak commity „na oddział” w git. Są tylko zatwierdzenia osiągalne z oddziału. I ta informacja nie jest bardzo dobrym wskaźnikiem, do której gałęzi należało pierwotnie zobowiązanie. Widzę dwa sposoby interpretować pytanie:

  • Chcę znaleźć pierwszy popełnić po scaleniu-podstawy branch i master który znajduje się na stronie oddziału.
  • Chcę znaleźć pierwszy zobowiązują się, że jest osiągalny z branch, ale nie od master.

Założę się, że chodziło ci o drugą. Odpowiedź na to pytanie jest zwracana przez to polecenie:

git rev-list ^master mybranch | tail -n 1 

Uwaga: To wszystko nie będzie strasznie jeśli odgałęzienie gałęzi tematycznych.


Jestem trochę zmieszany co do tego, co chcesz osiągnąć. Jeśli chcesz cały oddział być reprezentowane przez jeden commit, ale jeszcze dostać seryjnej, należy to zrobić:

git checkout mybranch 
git reset --soft `git merge-base mybranch master` 
git commit -m 'All of Mybranch' 
git checkout master 
git merge --no-ff mybranch 

pamiętać, że ta rozpocznie się squash na pierwszym scalania bazy. To może nie być to, co chcesz, jeśli wcześniej scaliłeś master w mybranch. Można modyfikować to, aby rozpocząć w pierwszym dniu mybranch popełnić, ale nie na mistrza (może mieć wierd i nieoczekiwane rezultaty w skomplikowanych historiach) zastępując drugą komendę z tym:

git reset --soft `git rev-list ^master mybranch | tail -n 1`^ 
+0

Dzięki. Dodałem wyjaśnienie tego, co chcę zrobić, zobacz moje zmiany. –

+0

Zakładałem, że tak - dokładnie to wyjaśniam w mojej odpowiedzi. – Chronial

+0

Świetnie, to działa bardzo dobrze. Dziękuję Ci. –

4

Dostaniesz B z git merge-base

git merge-base F I 

Albo prościej z

git merge-base my_branch my_other_branch 

Można wtedy rebase z wynikiem

git rebase -i B 

i po prostu pierwsza popełnić g, podczas zgniatania wszystkich pozostałych.

+0

To całkiem sprytne. –

1

git merge-base da ci B. Chcesz wszystkich bezpośrednich dzieci B, które są także przodkami I. To jest związane z How do I find the next commit in git? i Referencing the child of a commit in Git. Spróbuj czegoś takiego:

root=$(git merge-base master topic-branch) 

git rev-list --parents ^$root topic-branch | grep " $root" | cut -f1 -d' ' 

będzie tej liście wszystkie zobowiązuje od nasady do czubka topic-branch wraz z rodzicami i pokazać te, gdzie dominującej jest merge-base korzeń.

Ponieważ tematem oddział może zawierać scala nie może być więcej niż jeden „pierwszy” popełnić w oddziale, topologicznie.

Powiązane problemy