如何在git中find下一个提交?

ref^引用ref^前的提交,那么 ref 之后获取提交呢?

例如,如果我git checkout 12345如何检查下一个提交?

谢谢。

PS是的,git的DAG节点指针结构树什么的。 如何在这之后find提交?

列出所有的提交,从当前的一个,然后是它的孩子,等等 – 基本上是标准的git日志,但按照其他方式,使用类似

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

其中894e8b4e93d8f3是您想要显示的第一个提交。

Hudson(现在的Jenkins) Kohsuke Kawaguchi的创造者刚刚出版(2013年11月):
kohsuke / git-children-of :

给定提交,find该提交的直接子项。

 #!/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 

如此线程所示 ,在基于由DAG(定向非循环图)表示的历史的VCS中,不存在“单亲”或“一个孩子”。

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

提交的顺序是通过“topo-order”或“date-order”完成的(参见GitPro的书 )

但是从Git1.6.0开始 ,你可以列出提交的子代。

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

注:对于父提交 ,你有同样的问题,后缀^到一个修订参数,意味着该提交对象的第一个父。 ^<n>表示第<n>个父母(即, rev^相当于rev^1 )。

如果你在分支foo并发出“ git merge bar ”,那么foo将是第一个父项。
即:第一个父代是你合并时的分支,第二个是你合并的分支上的提交。

我发现的是

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

在那里我将commit1设置为当前提交,并将commit2设置为当前头部。 这会返回一个在commit1commit2之间build立path的所有提交的列表。

输出的最后一行是commit1的子节点(在commit2的path上)。

没有独特的“下一个承诺”。 由于Git中的历史logging是一个DAG,而不是一行,所以许多提交可以有一个共同的父(分支),提交可以有多个父(合并)。

如果你有一个特定的分支,你可以看看它的日志,看看什么提交列出当前的一个作为其父。

我明白你的意思。 对于前面的提交有足够的语法是令人沮丧的,但没有一个去下一个提交。 在一个复杂的历史中,“下一个承诺”的问题变得相当困难,但是在复杂的合并中,同样的硬度也出现在“先前”承诺之上。 在简单的情况下,在一个具有线性历史logging的单个分支内部(即使只是局部地进行一些有限数量的提交),这将是好的,并且向前和向后是有意义的。

然而,真正的问题是,子提交没有被引用,只是一个向后链表。 find子提交需要一个search,这不是太糟糕,但可能不是git想要放入refspec逻辑的东西。

无论如何,我遇到了这个问题,因为我只是想一次一个地从事历史性的事情,做一些testing,有时候你必须站出来而不是落后。 那么,有更多的想法,我想出了这个解决scheme:

在你所在的地方select一个提交。 这可能是一个分支头。 如果你在分支〜10,然后“git checkout branch〜9”,然后“git checkout branch〜8”获得下一个,然后是“git checkout branch〜7”等等。

如果你需要的话,减less数量应该是非常容易的。 比parsinggit rev-list容易得多。

两个实用的答案:

一个小孩

基于@迈克尔的回答 ,我砍了我的.gitconfigchild别名。

它在默认情况下按预期工作,也是多function的。

 # 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' -" 

它默认给HEAD的孩子(除非另外提供一个commit-ish参数),通过跟随祖先一步走向当前分支的尖端(除非另一个提交ish作为第二个参数)。

如果你想使用短哈希表,可以使用%h而不是%H

多个孩子

有一个分离的头(没有分支),或者让所有的孩子不分枝:

 # 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' -" 

$1更改为$*以打印所有的孩子

我在~/.gitconfig有这个别名

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

在你没有特定的“目的地”提交的情况下,而是想看到可能在任何分支上的子提交,你可以使用这个命令:

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

如果你想看到所有的孩子 rev-list --children ,你必须recursion地使用rev-list --children ,就像这样:

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

给予大孩子的版本会使用更复杂的sed和/或cut 。)

最后,你可以把它提供给一个log --graph命令来查看树结构,如下所示:

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

我已经尝试了许多不同的解决scheme,但都没有为我工作 必须拿出我自己的。

find下一个提交

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

find以前的提交

 function p() { git checkout HEAD^1 } 

如果子提交全部在某个分支上,则可以使用gitk --all commit^.. ,其中“commit”是标识提交的内容。 例如,如果提交的缩写SHA-1是c6661c5,则键入gitk --all c6661c5^..

您可能需要将完整的SHA-1input到gitk的“SHA1 ID:”单元格中。 你将需要完整的SHA-1,这个例子可以通过git rev-parse c6661c5

或者, git rev-list --all --children | grep '^c6661c5883bb53d400ce160a5897610ecedbdc9d' git rev-list --all --children | grep '^c6661c5883bb53d400ce160a5897610ecedbdc9d'将产生一个包含这个提交的所有子代的行,大概是否涉及到一个分支。

我设法通过以下方式find下一个孩子:

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

每个提交存储一个指向其父(父母,在合并(标准)提交的情况下)。

所以,没有办法指向父级的子级提交(如果有的话)。

这篇文章( http://www.jayway.com/2015/03/30/using-git-commits-to-drive-a-live-coding-session/#comment-282667 )显示了一个整洁的方式,如果这样做,如果您可以在提交堆栈的末尾创build一个定义良好的标记。 基本上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`' ,其中”demo-end“是最后一个标签。

在我的情况下,我正在寻找的提交不在git rev-list --all ,因为没有分支包含。 我结束了通过手动查看gitk --reflog