(Zaczęło się to jako odpowiedź na zduplikowane pytanie. Przeprowadziłem trochę lekkiej edycji, aby je oczyścić).
Wszystkie wewnętrzne strzałki Gita są jednokierunkowe, skierowane do tyłu. Dlatego nie ma krótkiej wygodnej składni do poruszania się do przodu: to po prostu niemożliwe.
Możliwe jest „poruszanie się przeciw strzałom”, ale sposób na zrobienie tego jest zaskakujący, jeśli nie widziałeś go wcześniej, a potem oczywisty później. Powiedzmy, że mamy:
A <-B <-C <-D <-E <-- last
^
|
\--------- middle
Używanie middle~2następuje dwukrotnie zgodnie ze strzałkami od Ctyłu do A. Więc jak możemy przenieść Csię D? Odpowiedź brzmi: zaczynamy od E, używając nazwy lasti pracujemy wstecz, aż do niej dojdziemy middle, rejestrując punkty, które odwiedzamy po drodze . Następnie poruszamy się tak daleko, jak chcemy, w kierunku last: przesuń się o jeden krok Dlub dwa do E.
Jest to szczególnie ważne, gdy mamy oddziały:
D--E <-- feature1
/
...--B--C <-- master
\
F--G <-- feature2
Który zatwierdzenie jest krok po kroku C? Nie ma poprawnej odpowiedzi, dopóki nie dodasz do pytania: w kierunku cechy___ (wypełnij puste pole).
Aby wyliczyć commits pomiędzy C(wykluczając C) samą i, powiedzmy, Gużywamy:
git rev-list --topo-order --ancestry-path master..feature2
W --topo-ordergwarantuje, że nawet w obecności złożonego rozgałęzienia i-łączących się commity wyjdzie w topologicznie-posortowanych. Jest to wymagane tylko wtedy, gdy łańcuch nie jest liniowy. Te --ancestry-pathśrodki ograniczające że gdy pracujemy z tyłu feature2, tylko commity list, które mają zobowiązać Cjako jeden z ich własnych przodków. To znaczy, jeśli wykres - lub jego odpowiednia część - faktycznie wygląda tak:
A--B--C <-- master
\ \
\ F--G--J <-- feature2
\ /
H-------I <-- feature3
prosty wniosek formie feature2..masterwylicza zobowiązuje J, Ga I, a F, a Hw pewnym porządku. Z --ancestry-pathnokautujemy Hi I: nie są potomkami C, tylko z A. Dzięki --topo-ordernam upewnić się, że rzeczywista kolejność jest wyliczenie J, potem G, potem F.
git rev-listKomenda wycieki tych identyfikatorów hash na standardowe wyjście, po jednej w wierszu. Aby przejść o krok do przodu w kierunku feature2, chcemy tylko ostatniej linii.
Jest możliwe (i kuszące i może być użyteczne) dodawanie, --reversedzięki czemu git rev-listpo wygenerowaniu drukuje zatwierdzenia w odwrotnej kolejności. To działa, ale jeśli używasz go w potoku takim jak ten:
git rev-list --topo-order --ancestry-path --reverse <id1>...<id2> | head -1
aby uzyskać „następny zatwierdzenie w kierunku id2”, a istnieje bardzo długa lista zatwierdzeń, git rev-listpolecenie może uzyskać zepsuty potok, gdy próbuje zapisać, do headktórego przestał czytać dane wejściowe i zakończył działanie. Ponieważ błędy w potokach są zwykle ignorowane przez powłokę, działa to głównie. Tylko upewnij się, że są ignorowane w twoim użyciu.
Kuszące jest także dodanie -n 1do git rev-listpolecenia wraz z --reverse. Nie rób tego! To git rev-listzatrzymuje się po przejściu o jeden krok wstecz , a następnie odwróceniu (jednopunktowej) listy odwiedzonych zatwierdzeń. Tak powstaje za <id2>każdym razem.
Ważna uwaga dodatkowa
Zauważ, że w przypadku fragmentów graficznych „diament” lub „pierścień benzenowy”:
I--J
/ \
...--H M--... <-- last
\ /
K--L
przesunięcie jednego zatwierdzenia „do przodu” z w Hkierunku lastspowoduje albo I albo K . Nic nie możesz na to poradzić: oba zobowiązania są o krok do przodu! Jeśli następnie zaczniesz od wynikowego zatwierdzenia i przejdziesz do następnego kroku, jesteś teraz zaangażowany w dowolną ścieżkę, którą zacząłeś.
Lekarstwem na to jest unikanie przemieszczania się o krok i blokowanie łańcuchów zależnych od ścieżki. Zamiast tego, jeśli planujesz odwiedzić cały łańcuch ścieżki przodków, zanim zrobisz cokolwiek innego , utwórz pełną listę wszystkich zatwierdzeń w łańcuchu:
git rev-list --topo-order --reverse --ancestry-path A..B > /tmp/list-of-commits
Następnie odwiedzaj każdy zatwierdzenie na tej liście, pojedynczo, a otrzymasz cały łańcuch. --topo-orderZadba trafisz I-i- Jw tej kolejności, a K-i- Lw tej kolejności (choć nie ma łatwego sposobu, aby przewidzieć, czy zrobisz parę IJ przed lub po parę KL).