Wie finde ich den nächsten commit im git? (Kind/Kinder mit ref)
ref^
bezieht sich auf den commit vor ref
, was immer das Begehen nach ref
?
Zum Beispiel, wenn ich git checkout 12345
wie kann ich das überprüfen die nächste zu Begehen?
Dank.
PS ja, git ist ein DAG-Knoten Zeiger struct Baum was auch immer. , Wie ich finde, ist das Begehen, nachdem diese ein?
- Duplizieren: stackoverflow.com/questions/1761825/...
- Danke, die Antwort es ist die einzige Lösung, die ich gehört habe bisher.
- Siehe auch "
git children-of
"!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Liste aller commits, die ausgehend von der aktuellen, und dann sein Kind, und so weiter - im Grunde standard-git-log, aber in die andere Richtung in der Zeit, so etwas wie
wo 894e8b4e93d8f3 ist der erste commit, die Sie zeigen möchten.
HEAD^
für894e8b4e93d8f3^
....
,^..
im hintergrund fehlschlägtfatal: unrecognized argument: --ancestry-path
im git-version 1.7.1master
ist auf die Abstammung der Pfad des aktuellen Begehen. Siehe meine Antwort's zweite code-snippet für eine Lösung, die funktioniert in allen Fällen.--reverse
hier. Es ist nur eine Präferenz, und eine unnötige option, als Teil einer Antwort, die könnte einfacher sein.Dem Schöpfer für das, Hudson (Jenkins jetzt) Kohsuke Kawaguchi soeben erschienen (November 2013):
kohsuke /git-Kinder-von:
Dargestellt durch dieser thread, in einem VCS basiert auf der Geschichte, dargestellt durch eine DAG (Gerichtete Azyklische Graph), es ist nicht "ein Elternteil" oder "ein Kind".
Die Reihenfolge der commits ist getan durch "topo-um" oder "date-Auftrag" (siehe GitPro Buch)
Aber da Git1.6.0, können Sie die Liste der Kinder eines commit.
Hinweis: für Eltern-commits, Sie haben das gleiche Problem, mit dem suffix
^
zu einer revision parameter Bedeutung der ersten Elternteil, dass commit-Objekt.^<n>
bedeutet, dass die<n>
th übergeordneten (d.h.rev^
entsprichtrev^1
).Wenn Sie auf einem ast
foo
und die Ausstellung "git merge bar
" dannfoo
werden die ersten Eltern.I. e: Die ersten Eltern ist die Filiale, die Sie waren, als Sie zusammengeführt, und der zweite ist der commit auf dem branch, dass Sie zusammengeführt werden.
git rev-list --children
sicher, sieht aus wie das, was ich will, aber es nicht DWIM. Es erscheint eine Liste aller, die Eltern und Ihre Kinder. Ich glaube, ich kann Sie alle aufzuzählen und zu analysieren, durch Sie... bleh, aber sein etwas.git rev-list --children
ist nicht für die Auflistung, nur Kinder, sondern für die Kotierung Eltern mit Ihren Kindern... man muss immer analysieren.$ git children0of 9dd5932
fatal: No annotated tags can describe '71d7b5dd89d241072a0a078ff2c7dfec05d52e1f'.
However, there were unannotated tags: try --tags.
Welchen output bekommen Sie?git-children-of
ist, dass es verwendet git describe, dass versuche zur Formatierung der SHA lesbar, die fehlschlagen können mit @TomHale Fehler, und gibt die Ergebnisse wiev1.0.4-14-g2414721
sind verwirrend, wenn Sie erwartet eine SHA. Ersetzen Sie es mit einem einfachenecho
macht es zu einem hervorragenden Werkzeug, danke!was ich gefunden habe ist
wo ich
commit1
wie der aktuelle commit-undcommit2
dem aktuellen Kopf. Dies gibt mir eine Liste aller commits, die bauen sich einen Weg zwischencommit1
undcommit2
.Die Letzte Zeile der Ausgabe ist das Kind von commit1 (auf dem Weg zu commit2).
| tail -1
um das Kind.Ich weiß, was du meinst. Es ist frustrierend zu haben, reichlich syntax für den Gang zum vorherigen begeht, aber keiner zu gehen, um die nächsten. In einer komplexen Geschichte, das problem der "was ist der nächste commit" wird es eher hart, aber dann in komplexen Zusammenführen die gleiche Härte entsteht, mit 'Vorherige' verpflichtet als gut. In dem einfachen Fall, in einem einzigen Zweig mit einer linearen Geschichte (auch wenn es nur lokal für einige begrenzte Anzahl von commits) es wäre nett und sinnvoll, um vorwärts und rückwärts gehen.
Das eigentliche problem mit diesem, jedoch, ist, dass die Kinder verpflichtet sind, sind nicht referenziert, es ist eine rückwärts verkettete Liste nur. Finden das Kind verpflichten, dauert eine Suche, die ist nicht allzu schlecht, aber wahrscheinlich nicht etwas, git will in die refspec Logik.
Jedenfalls, ich kam auf diese Frage, denn ich möchte einfach Schritt vorwärts in der Geschichte einen commit in einer Zeit, machen tests, und manchmal muss man einen Schritt vorwärts, und nicht rückwärts. Gut, mit ein paar mehr Gedanken kam ich mit dieser Lösung:
Wählen Sie ein commit vor, wo Sie sich gerade befinden. Dies könnte wahrscheinlich ein Zweig Kopf. Wenn Sie bei der Abteilung~10, dann "git checkout branch~9"
dann "git checkout branch~8", um den nächsten nach, dass
dann "git checkout branch~7" und so weiter.
Dekrementieren die Anzahl sollte wirklich leicht in ein Skript wenn Sie es brauchen. Viel einfacher als Analyse git rev-list.
BRANCH=master; git co $BRANCH~$[ $(git rev-list HEAD..$BRANCH | wc -l) - 1 ]
" Sie haben zu gehen, hin zu einem ast, kein Weg vorbei.Zwei praktische Antworten:
Ein Kind
Basierend auf @Michael die Antwort, ich hackte die
child
alias in meine.gitconfig
.Funktioniert es wie erwartet in der Standard-Fall, und ist auch vielseitig.
Ist es standardmäßig, dass dem Kind der KOPF (es sei denn, eine andere commit-ish argument gegeben ist), indem Sie die folgenden der Abstammung einen Schritt in Richtung auf die Spitze des aktuellen Zweiges (es sei denn, eine andere commit-ish gegeben wird, als zweites argument).
Verwenden
%h
statt%H
wenn Sie möchten, dass der kurze hash-form.Mehrere Kinder
Mit einem detached HEAD (es gibt keine Filiale) oder um alle Kinder, ungeachtet der Zweige:
Ändern Sie die
$1
zu$*
drucken alle Kinder.Können Sie auch ändern
--all
zu einer commit-ish zeigt nur die Kinder, die Ahnen, dass das Engagement in anderen Worten, Sie zeigen nur die Kinder "in die Richtung" die angegebene Begehen. Dies kann helfen, Sie verengen die Ausgabe nach unten von vielen Kindern nur eine.Gibt es keine eindeutigen "next commit". Weil die Geschichte in Git ist ein DAG, und nicht eine Linie, viele begeht, können eine gemeinsame übergeordnete (Zweige), und verpflichtet sich, Sie kann mehr als einen parent (fusioniert).
Wenn Sie einen bestimmten Zweig im Auge haben, können Sie sich die log-und sehen, was commit-Listen in die Gegenwart ein wie Ihre Muttergesellschaft.
<rev>^
ist "Eltern-commit" (den "ersten Eltern" für merge commits).In dem Fall, wo Sie nicht haben, eine bestimmte "Ziel" - Begehen im Sinn, sondern wollen ein Kind begeht, der möglicherweise auf alle Zweig, können Sie diesen Befehl verwenden:
Wenn Sie möchten, um zu sehen, alle Kinder und grand-Kinder, müssen Sie
rev-list --children
rekursiv, etwa so:(Die version, die gibt nur grand-Kinder verwenden eine komplexere
sed
- und/odercut
.)Schließlich, Sie ernähren können, die in einem
log --graph
Befehl zu sehen, der Baum-Struktur, in etwa so:Hinweis: die oben genannten Befehle gehen alle davon aus, dass Sie sich gesetzt haben, ist die shell-variable
${COMMIT}
zu einigen Referenz (branch, tag, sha1) der commit-deren Kinder, die Sie interessiert sind in.${COMMIT}
esist nicht, aber man könnte$(git rev-parse HEAD)
statt${COMMIT}
.Habe ich diesen alias in
~/.gitconfig
f()
? Und es musshead -1
zu werden, das erste Kind, da es sonst einfach den Bericht den KOPF.f()
. Ja,head -1
ist eine mutige Vermutung.nextref = "!f() { git log --reverse --ancestry-path --pretty=%H $1..HEAD | head -${2:-1} | tail -1; }; f"
so können Sie wählen, wie weit Voraus, OptionalIch habe versucht viele verschiedene Lösungen, und keiner für mich gearbeitet. Hatte zu kommen mit meinem eigenen.
finden die nächsten commit
finden frühere Begehen
Ich es geschafft, das nächste Kind, das auf die folgende Weise:
Wenn das Kind verpflichtet sind, alle auf manche Filiale, die Sie verwenden können
gitk --all commit^..
, wobei "Begehen" ist etwas, was die Identifizierung des commit. Zum Beispiel, wenn die commit-abgekürzten SHA-1 ist c6661c5, dann geben Siegitk --all c6661c5^..
Werden Sie wahrscheinlich benötigen, geben Sie den vollständigen SHA-1 in gitk ist "SHA1 ID:" der Zelle. Sie müssen den vollständigen SHA-1, die für dieses Beispiel erhält man über
git rev-parse c6661c5
Alternativ
git rev-list --all --children | grep '^c6661c5883bb53d400ce160a5897610ecedbdc9d'
erzeugt eine Linie, die alle Kinder dieser Begehen, vermutlich ob oder nicht es ist ein Zweig beteiligt.Jedem commit speichert einen Zeiger zu seinem übergeordneten (Eltern, im Fall von merge(standard) commit).
So, es gibt keinen Weg, um zu einem Kind zu Begehen (wenn es eine gibt) von den Eltern.
Diesem post (http://www.jayway.com/2015/03/30/using-git-commits-to-drive-a-live-coding-session/#comment-282667) zeigt eine nette Möglichkeit, wenn es tun, wenn Sie können erstellen Sie eine gut definierte tag am Ende der commit-Stapel. Im wesentlichen
git config --global alias.next '!git checkout `git rev-list HEAD..demo-end | tail -1`'
wo "demo-Ende" ist der Letzte tag.Vorhandene Antworten, die davon ausgehen, dass Sie eine Filiale (oder ref) mit der commit, den du suchst.
In meinem Fall, der commit, die ich suchte war nicht in
git rev-list --all
da kein Zweig enthalten. Ich landete auf der Suche durchgitk --reflog
manuell.Wenn Sie nicht finden können, Ihre commit-sogar im reflog, versuchen
git fsck --full
Liste baumelt (D. H. nicht in jeder Filiale) begeht, odergit fsck --lost-found
zu machen, refs und wenden Techniken in den anderen Antworten.