在Git中引用提交的子代

Att*_*lus 36 git

如果你想移动HEAD到当前的父节点HEAD,这很容易:

git reset --hard HEAD^
Run Code Online (Sandbox Code Playgroud)

但有没有简单的方法来完成与此操作完全相反的操作,即将头设置为当前头的第一个子提交?

现在,我使用gitk作为解决方法(alt-tab,向上箭头,alt-tab,中键单击),但我想要一个更优雅的解决方案,也可以在gitk不可用时使用.

Att*_*lus 16

很可能不是最快的解决方案,但它可以满足我的需求:

#!/bin/bash

REV=$1

if [[ -z "$REV" ]]; then
    echo "Usage: git-get-child  []"
    exit
fi

HASH=$(git rev-parse $REV)

NUM=$2

if [[ -z "$NUM" ]]; then
    NUM=1
fi

git rev-list --all --parents | grep " $HASH" | sed -n "${NUM}s/\([^ ]*\) .*$/\\1/p"

git rev-list --all --parents正是我所需要的:它遍历所有可到达的提交,并为每个提交打印以下行:

SHA1_commit SHA1_parent1 SHA1_parent2 等等

grep表达式中的空格确保只找到所讨论的SHA1是父级的那些行.然后我们得到第n个孩子的第n行并得到孩子的SHA1.

  • 请参阅下文,了解可能显着的[性能改进](http://stackoverflow.com/questions/1761825/referencing-the-child-of-a-commit-in-git/5353204#5353204) (2认同)

Rai*_*ome 12

上述方法中使用git rev-list --all考虑了所有可用的提交,它可以有很多,并且通常不是必需的.如果可以从某个分支访问有趣的子提交,则可以减少对子提交感兴趣的脚本需要处理的提交数:

branches=$(git branch --contains $commit| grep -v '[*] ('| sed -e 's+^..++')
Run Code Online (Sandbox Code Playgroud)

将确定$ commit是其祖先的分支集.

使用这个集合,sed应该准确地产生$ commit和它是祖先的所有分支头之间的所有父子关系的集合.


Mic*_*ael 6

部分基于Paul Wagland 的回答,部分基于他的来源,我使用以下内容:

git log --ancestry-path --format=%H ${commit}..master | tail -1
Run Code Online (Sandbox Code Playgroud)

我发现保罗的回答给了我错误的旧提交输出(可能是由于合并?),主要区别在于--ancestry-path标志。

  • 使用 `--reverse` 并使用 `head -1` 进行温和的加速 (2认同)