Comment puis-je trouver le prochain commit dans git? (enfant / enfants de ref)

ref^ fait référence au commit avant ref , qu’en est-il de la validation après ref ?

Par exemple, si je coche git checkout 12345 comment puis-je vérifier le prochain commit?

Merci.

PS Oui, git est une arborescence de pointeurs DAG. Comment trouver le commit après celui-ci?

Pour lister tous les commits, à partir de celui en cours, puis de son fils, et ainsi de suite – basiquement le journal standard de Git, mais en sens inverse, utilisez quelque chose comme:

 git log --reverse --ancestry-path 894e8b4e93d8f3^..master 

où 894e8b4e93d8f3 est le premier commit à afficher.

Le créateur de Hudson (maintenant Jenkins) Kohsuke Kawaguchi vient de publier (novembre 2013):
kohsuke / git-children-de :

Étant donné un commit, trouvez les enfants immédiats de ce commit.

 #!/bin/bash -e # given a commit, find immediate children of that commit. for arg in "$@"; do for commit in $(git rev-parse $arg^0); do for child in $(git log --format='%H %P' --all | grep -F " $commit" | cut -f1 -d' '); do git describe $child done done done 

Comme illustré par ce fil , dans un VCS basé sur l’historique représenté par un DAG (Directed Acyclic Graph) , il n’y a pas “un parent” ou “un enfant”.

  C1 -> C2 -> C3 / \ A -> BE -> F \ / D1 -> D2 ----/ 

La commande des commits se fait par “topo-order” ou “date-order” (voir livre GitPro )

Mais depuis Git1.6.0 , vous pouvez lister les enfants d’un commit.

 git rev-list --children git log --children 

Remarque: pour les validations parentales , vous avez le même problème, avec le suffixe ^ à un paramètre de révision qui signifie le premier parent de cet object de validation. ^ signifie le e parent (c.-à-d. que rev^ équivaut à rev^1 ).

Si vous êtes sur foo twig et lancez ” git merge bar ” alors foo sera le premier parent.
Ie: Le premier parent est la twig sur laquelle vous étiez lorsque vous avez fusionné, et le second est le commit sur la twig dans laquelle vous avez fusionné.

ce que j’ai trouvé est

 git rev-list --ancestry-path commit1..commit2 

où je commit1 tant que commit en cours et commit2 dans le head actuel. Cela me renvoie une liste de tous les commits qui construisent un chemin entre commit1 et commit2 .

La dernière ligne de la sortie est l’enfant de commit1 (sur le chemin de commit2).

Il n’y a pas de “next commit” unique. L’historique de Git étant un DAG et non une ligne, de nombreux commits peuvent avoir un parent commun (twigs) et les validations peuvent avoir plusieurs parents (fusions).

Si vous avez en tête une twig particulière, vous pouvez consulter son journal et voir ce que la liste de validation contient comme parent.

Je vois ce que tu veux dire. C’est frustrant d’avoir une syntaxe abondante pour aller aux commits précédents, mais aucun pour aller aux prochains. Dans une histoire complexe, le problème de “qu’est-ce que le prochain engagement” devient plutôt difficile, mais dans le cas d’une fusion complexe, la même dureté apparaît également avec les commits “précédents”. Dans le cas simple, dans une seule twig avec un historique linéaire (même seulement localement pour un nombre limité de commits), ce serait bien et logique d’aller de l’avant et de revenir en arrière.

Le vrai problème avec ceci, cependant, est que les commits d’enfants ne sont pas référencés, c’est une liste de liens en amont seulement. Trouver l’enfant commit nécessite une recherche, ce qui n’est pas trop grave, mais probablement pas quelque chose que git veut mettre dans la logique refspec.

En tout cas, je suis tombé sur cette question parce que je veux simplement avancer dans l’histoire que l’on commet à la fois, en faisant des tests, et parfois il faut avancer et non reculer. Eh bien, avec un peu plus de reflection, je suis venu avec cette solution:

Choisissez un engagement avant où vous êtes. Cela pourrait probablement être une tête de twig. Si vous êtes à la twig ~ 10, alors “git checkout branch ~ 9” puis “git checkout ~ 8” pour obtenir le suivant, puis “git checkout branch ~ 7” et ainsi de suite.

Décrémenter le nombre devrait être très facile dans un script si vous en avez besoin. Beaucoup plus facile que d’parsingr la liste de révocation de git.

Dans le cas où vous n’avez pas en tête un commit de destination particulier, mais que vous voulez voir des commits enfants qui peuvent se trouver sur une twig, vous pouvez utiliser cette commande:

 git rev-list --children --all | grep ^${COMMIT} 

Si vous voulez voir tous les enfants et petits -enfants , vous devez utiliser récursivement les rev-list --children comme:

 git rev-list --children --all | \ egrep ^\($(git rev-list --children --all | \ grep ^${COMMIT} | \ sed 's/ /|/g')\) 

(La version qui ne donne que des petits-enfants utiliserait un sed plus complexe et / ou cut ).

Enfin, vous pouvez l’alimenter dans une commande log --graph pour voir l’arborescence, comme ceci:

 git log --graph --oneline --decorate \ \^${COMMIT}^@ \ $(git rev-list --children --all | \ egrep ^\($(git rev-list --children --all | \ grep ^${COMMIT} | \ sed 's/ /|/g')\)) 

Deux réponses pratiques:

Un enfant

Basé sur la réponse de @ Michael , j’ai piraté l’alias child dans mon .gitconfig .

Il fonctionne comme prévu dans le cas par défaut et est également polyvalent.

 # Get the child commit of the current commit. # Use $1 instead of 'HEAD' if given. Use $2 instead of curent branch if given. child = "!bash -c 'git log --format=%H --reverse --ancestry-path ${1:-HEAD}..${2:\"$(git rev-parse --abbrev-ref HEAD)\"} | head -1' -" 

Il faut par défaut donner à l’enfant de HEAD (à moins qu’un autre argument commit-ish soit donné) en suivant l’ascendance d’un pas vers la pointe de la twig en cours (à moins qu’un autre commit-ish soit donné en second argument).

Utilisez %h au lieu de %H si vous voulez le format de hachage court.

Plusieurs enfants

Avec une tête détachée (il n’y a pas de twig) ou pour amener tous les enfants indépendamment des twigs:

 # For the current (or specified) commit-ish, get the all children, print the first child children = "!bash -c 'c=${1:-HEAD}; set -- $(git rev-list --all --not \"$c\"^@ --children | grep $(git rev-parse \"$c\") ); shift; echo $1' -" 

Changer le $1 à $* pour imprimer tous les enfants

J’ai cet alias dans ~/.gitconfig

 first-child = "!f() { git log --reverse --ancestry-path --pretty=%H $1..${2:-HEAD} | head -1; }; f" 

J’ai essayé beaucoup de solutions différentes et aucune n’a fonctionné pour moi. J’ai dû venir avec le mien.

trouver le prochain commit

 function n() { git log --reverse --pretty=%H master | grep -A 1 $(git rev-parse HEAD) | tail -n1 | xargs git checkout } 

trouver l’engagement précédent

 function p() { git checkout HEAD^1 } 

J’ai réussi à trouver le prochain enfant de la manière suivante:

 git log --reverse --children -n1 HEAD (where 'n' is the number of children to show) 

Si les commits enfants sont tous sur une twig, vous pouvez utiliser gitk --all commit^.. , où “commit” est quelque chose qui identifie le commit. Par exemple, si l’abréviation SHA-1 de la validation est c6661c5, tapez alors gitk --all c6661c5^..

Vous devrez probablement entrer le SHA-1 complet dans la cellule “SHA1 ID:” de gitk. Vous aurez besoin du SHA-1 complet, qui pour cet exemple peut être obtenu via git rev-parse c6661c5

Alternativement, git rev-list --all --children | grep '^c6661c5883bb53d400ce160a5897610ecedbdc9d' git rev-list --all --children | grep '^c6661c5883bb53d400ce160a5897610ecedbdc9d' produira une ligne contenant tous les enfants de cette validation, qu’il y ait ou non une twig.

Chaque commit stocke un pointeur sur son parent (parents, en cas de validation de fusion (standard)).

Il n’y a donc aucun moyen de pointer un enfant sur le commit (s’il y en a un) du parent.

Ce message ( http://www.jayway.com/2015/03/30/using-git-commits-to-drive-a-live-coding-session/#comment-282667 ) montre un bon moyen de le faire si vous pouvez créer une balise bien définie à la fin de votre stack de validation. Essentiellement git config --global alias.next '!git checkout `git rev-list HEAD..demo-end | tail -1`' git config --global alias.next '!git checkout `git rev-list HEAD..demo-end | tail -1`' où “demo-end” est la dernière balise.

Les réponses existantes supposent que vous avez une twig (ou une référence) contenant le commit que vous recherchez.

Dans mon cas, le commit que je cherchais n’était pas dans git rev-list --all , car aucune twig ne le contenait. J’ai fini par regarder gitk --reflog manuellement.

Si vous ne parvenez pas à trouver votre commit même dans le reflog, essayez git fsck --full pour lister les git fsck --full (c’est-à-dire pas dans les twigs)