ref^
odnosi się do zatwierdzenia wcześniej ref
, a co z uzyskaniem zatwierdzenia po ref
?
Na przykład, jeśli git checkout 12345
mam sprawdzić następny zatwierdzenie?
Dzięki.
PS Tak, git to drzewo struktury wskaźnika węzła DAG. Jak znaleźć zatwierdzenie po tym?
git
version-control
Schwern
źródło
źródło
git children-of
”!Odpowiedzi:
Aby wyświetlić listę wszystkich zatwierdzeń, zaczynając od bieżącego, a następnie jego potomka itd. - w zasadzie standardowy dziennik git, ale idąc w drugą stronę, użyj czegoś w rodzaju
gdzie 894e8b4e93d8f3 jest pierwszym zatwierdzeniem, które chcesz pokazać.
źródło
HEAD^
za894e8b4e93d8f3^
....
,^..
po cichufatal: unrecognized argument: --ancestry-path
do wersji git 1.7.1master
znajduje się na ścieżce przodków bieżącego zatwierdzenia. Zobacz drugi fragment kodu mojej odpowiedzi , aby znaleźć rozwiązanie, które zadziała we wszystkich przypadkach.Twórca Hudson (obecnie Jenkins) Kohsuke Kawaguchi właśnie opublikował (listopad 2013):
kohsuke / git-children-of :
Jak ilustruje ten wątek , w VCS opartym na historii reprezentowanej przez DAG (Directed Acyclic Graph) nie ma „jednego rodzica” ani „jednego dziecka”.
Kolejność zatwierdzeń odbywa się poprzez „zamówienie topo” lub „zamówienie według daty” (patrz książka GitPro )
Ale od wersji Git 1.6.0 możesz wyświetlić listę potomków zatwierdzenia.
Uwaga: w przypadku zatwierdzeń nadrzędnych występuje ten sam problem, z sufiksem
^
parametru zmiany oznaczającego pierwszego rodzica tego obiektu zatwierdzenia.^<n>
oznacza<n>
th rodzica (tj.rev^
jest równoważnerev^1
).Jeśli jesteś w oddziale
foo
i wydajesz „git merge bar
”, tofoo
będziesz pierwszym rodzicem.Tj .: pierwszy element nadrzędny to gałąź, w której byłeś podczas scalania, a drugi to zatwierdzenie w gałęzi, w której się scaliłeś.
źródło
git rev-list --children
na pewno wygląda tak, jak chcę, ale nie DWIM. Wydaje się, że zawiera listę wszystkich rodziców i ich dzieci. Przypuszczam, że mogę wymienić je wszystkie i przeanalizować je ... bleh, ale to coś.git rev-list --children
nie jest na liście tylko dzieci, ale na liście rodziców z ich dziećmi ... zawsze trzeba parsować.$ git children0of 9dd5932
fatal: No annotated tags can describe '71d7b5dd89d241072a0a078ff2c7dfec05d52e1f'.
However, there were unannotated tags: try --tags.
Jakie wyniki otrzymujesz?git-children-of
jest to, że używa git opisu, który próbuje sformatować SHA jako czytelną dla człowieka, co może się nie powieść z błędem @ TomHale, i daje takie wyniki,v1.0.4-14-g2414721
które są mylące, jeśli oczekujesz SHA. Zastąpienie go prostymecho
czyni to doskonałe narzędzie, dzięki!znalazłem to
gdzie ustawiłem
commit1
jako bieżące zatwierdzenie icommit2
do aktualnej głowy. To zwraca mi listę wszystkich zatwierdzeń, które budują ścieżkę pomiędzycommit1
acommit2
.Ostatni wiersz wyniku to potomek commit1 (na ścieżce do commit2).
źródło
| tail -1
aby zdobyć dziecko.Wiem co masz na myśli. Frustrujące jest posiadanie dużej składni do przechodzenia do poprzednich zatwierdzeń, ale nie przechodzenie do następnych. W złożonej historii problem „co to jest kolejne zatwierdzenie” staje się raczej trudny, ale w złożonym łączeniu pojawia się ta sama twardość z „poprzednimi” zobowiązaniami. W prostym przypadku w obrębie jednej gałęzi z liniową historią (nawet tylko lokalnie dla pewnej ograniczonej liczby zatwierdzeń) byłoby miło i sensownie byłoby iść do przodu i do tyłu.
Prawdziwym problemem jest jednak to, że do zatwierdzeń potomnych nie ma odniesienia, jest to tylko lista powiązana wstecz. Znalezienie zatwierdzenia potomnego wymaga wyszukiwania, co nie jest takie złe, ale prawdopodobnie nie jest czymś, co git chce umieścić w logice refspec.
W każdym razie natknąłem się na to pytanie, ponieważ chcę po prostu zrobić krok naprzód w historii, dokonując pojedynczych naruszeń, wykonując testy, a czasem trzeba zrobić krok naprzód, a nie wstecz. Po dłuższym zastanowieniu wymyśliłem to rozwiązanie:
Wybierz zatwierdzenie przed miejscem, w którym jesteś. Prawdopodobnie może to być głowa oddziału. Jeśli jesteś w oddziale ~ 10, to „git checkout branch ~ 9”, a następnie „git checkout branch ~ 8”, aby uzyskać następny, a następnie „git checkout branch ~ 7” i tak dalej.
Zmniejszenie liczby powinno być naprawdę łatwe w skrypcie, jeśli jest to potrzebne. O wiele łatwiej niż parsowanie git rev-list.
źródło
BRANCH=master; git co $BRANCH~$[ $(git rev-list HEAD..$BRANCH | wc -l) - 1 ]
Musisz iść w kierunku gałęzi, nie ma mowy o tym.Dwie praktyczne odpowiedzi:
Jedno dziecko
Na podstawie odpowiedzi @ Michaela zhakowałem
child
alias w swoim.gitconfig
.Działa zgodnie z oczekiwaniami w przypadku domyślnym, a także jest wszechstronny.
Domyślnie podaje potomka HEAD (chyba że podano inny argument zatwierdzenia), wykonując przodek o krok w kierunku końca bieżącej gałęzi (chyba że drugi argument zatwierdzenia jest podany jako drugi argument).
Użyj
%h
zamiast,%H
jeśli chcesz mieć krótki formularz skrótu.Wiele dzieci
Z odłączoną GŁOWĄ (nie ma gałęzi) lub aby uzyskać wszystkie dzieci niezależnie od gałęzi:
Zmień na,
$1
aby$*
wydrukować wszystkie dzieci.Możesz także zmienić
--all
na zatwierdzenie, aby wyświetlać tylko dzieci, które są przodkami tego zatwierdzenia - innymi słowy, aby wyświetlać tylko dzieci „w kierunku” danego zatwierdzenia. Może to pomóc zawęzić wyniki od wielu dzieci do jednego.źródło
Nie ma unikalnego „następnego zatwierdzenia”. Ponieważ historia w Git jest DAG, a nie wierszem, wiele zatwierdzeń może mieć wspólnego rodzica (gałęzie), a zatwierdzenia mogą mieć więcej niż jednego rodzica (scalenia).
Jeśli masz na myśli konkretną gałąź, możesz spojrzeć na jej log i zobaczyć, co zatwierdza na liście obecną jako nadrzędną.
źródło
<rev>^
to „zatwierdzenie nadrzędne” („pierwszy nadrzędny” dla zatwierdzeń scalania).Wypróbowałem wiele różnych rozwiązań i żadne nie działało dla mnie. Musiałem wymyślić własne.
znajdź następny zatwierdzenie
znajdź poprzednie zatwierdzenie
źródło
W przypadku, gdy nie masz na myśli konkretnego zatwierdzenia „docelowego”, ale zamiast tego chcesz zobaczyć zatwierdzenia potomne, które mogą znajdować się w dowolnej gałęzi, możesz użyć tego polecenia:
Jeśli chcesz zobaczyć wszystkie dzieci i wnuki , musisz użyć
rev-list --children
rekurencyjnie:(Wersja, która daje tylko wnuczki, użyłaby bardziej złożonego
sed
i / lubcut
.)Na koniec możesz wprowadzić to do
log --graph
polecenia, aby zobaczyć strukturę drzewa, w następujący sposób:Uwaga : wszystkie powyższe polecenia zakładają, że zmienna powłoki została ustawiona na
${COMMIT}
jakieś odniesienie (gałąź, znacznik, sha1) zatwierdzenia, którego dziećmi jesteś zainteresowany.źródło
${COMMIT}
nie istnieje, ale możesz użyć$(git rev-parse HEAD)
zamiast tego${COMMIT}
.(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:
Używanie
middle~2
następuje dwukrotnie zgodnie ze strzałkami odC
tyłu doA
. Więc jak możemy przenieśćC
sięD
? Odpowiedź brzmi: zaczynamy odE
, używając nazwylast
i pracujemy wstecz, aż do niej dojdziemymiddle
, rejestrując punkty, które odwiedzamy po drodze . Następnie poruszamy się tak daleko, jak chcemy, w kierunkulast
: przesuń się o jeden krokD
lub dwa doE
.Jest to szczególnie ważne, gdy mamy oddziały:
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ącC
) samą i, powiedzmy,G
używamy:W
--topo-order
gwarantuje, ż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łufeature2
, tylko commity list, które mają zobowiązaćC
jako jeden z ich własnych przodków. To znaczy, jeśli wykres - lub jego odpowiednia część - faktycznie wygląda tak:prosty wniosek formie
feature2..master
wylicza zobowiązujeJ
,G
aI
, aF
, aH
w pewnym porządku. Z--ancestry-path
nokautujemyH
iI
: nie są potomkamiC
, tylko zA
. Dzięki--topo-order
nam upewnić się, że rzeczywista kolejność jest wyliczenieJ
, potemG
, potemF
.git rev-list
Komenda wycieki tych identyfikatorów hash na standardowe wyjście, po jednej w wierszu. Aby przejść o krok do przodu w kierunkufeature2
, chcemy tylko ostatniej linii.Jest możliwe (i kuszące i może być użyteczne) dodawanie,
--reverse
dzięki czemugit rev-list
po wygenerowaniu drukuje zatwierdzenia w odwrotnej kolejności. To działa, ale jeśli używasz go w potoku takim jak ten:aby uzyskać „następny zatwierdzenie w kierunku id2”, a istnieje bardzo długa lista zatwierdzeń,
git rev-list
polecenie może uzyskać zepsuty potok, gdy próbuje zapisać, dohead
któ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 1
dogit rev-list
polecenia wraz z--reverse
. Nie rób tego! Togit rev-list
zatrzymuje 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”:
przesunięcie jednego zatwierdzenia „do przodu” z w
H
kierunkulast
spowoduje alboI
alboK
. 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:
Następnie odwiedzaj każdy zatwierdzenie na tej liście, pojedynczo, a otrzymasz cały łańcuch.
--topo-order
Zadba trafiszI
-i-J
w tej kolejności, aK
-i-L
w tej kolejności (choć nie ma łatwego sposobu, aby przewidzieć, czy zrobisz parę IJ przed lub po parę KL).źródło
Mam ten alias w
~/.gitconfig
źródło
f()
? I to musi byćhead -1
pierwsze dziecko, w przeciwnym razie zgłosi to HEAD.f()
. Tak,head -1
to odważne domysły.nextref = "!f() { git log --reverse --ancestry-path --pretty=%H $1..HEAD | head -${2:-1} | tail -1; }; f"
abyś mógł wybrać, jak daleko naprzód, opcjonalnieUdało mi się znaleźć następne dziecko w następujący sposób:
źródło
Jeśli wszystkie zatwierdzenia potomne znajdują się w jakiejś gałęzi, możesz użyć
gitk --all commit^..
, gdzie „zatwierdzenie” jest czymś identyfikującym zatwierdzenie. Na przykład, jeśli skrót SHA-1 zatwierdzenia to c6661c5, wpiszgitk --all c6661c5^..
Prawdopodobnie będziesz musiał wprowadzić pełny SHA-1 w komórce gitk „SHA1 ID:”. Będziesz potrzebował pełnego SHA-1, który w tym przykładzie można uzyskać za pośrednictwem
git rev-parse c6661c5
Alternatywnie,
git rev-list --all --children | grep '^c6661c5883bb53d400ce160a5897610ecedbdc9d'
stworzy wiersz zawierający wszystkie dzieci tego zatwierdzenia, przypuszczalnie bez względu na to, czy w grę wchodzi oddział.źródło
Każde zatwierdzenie przechowuje wskaźnik do swojego elementu nadrzędnego (rodziców, w przypadku zatwierdzenia scalania (standard)).
Zatem nie ma sposobu, aby wskazać zatwierdzenie dziecka (jeśli istnieje) od rodzica.
źródło
Ten post ( http://www.jayway.com/2015/03/30/using-git-commits-to-drive-a-live-coding-session/#comment-282667 ) pokazuje fajny sposób, jeśli robisz to, jeśli możesz utworzyć dobrze zdefiniowany znacznik na końcu stosu zatwierdzeń. Zasadniczo
git config --global alias.next '!git checkout `git rev-list HEAD..demo-end | tail -1`'
gdzie „demo-end” jest ostatnim tagiem.źródło
Istniejące odpowiedzi zakładają, że masz gałąź zawierającą szukany zatwierdzenie.
W moim przypadku zatwierdzenie, którego szukałem, nie było włączone,
git rev-list --all
ponieważ żadna gałąź tego nie zawierała.Skończyłem przeglądać
gitk --reflog
ręcznie.Jeśli nie możesz znaleźć swojego zatwierdzenia nawet w dzienniku, spróbuj:
git fsck --full
aby wyświetlić listę zwisających (tzn. nie w żadnej gałęzi) zatwierdzeń, lubgit fsck --lost-found
zrobić referencje wskazujące na wiszące zobowiązania do zastosowania technik w innych odpowiedziach.źródło