3

^我可以用and ~*number*,like 319411a^or来引用向后的修订HEAD~3

是否有任何特定的语法来引用前向提交(类似于上面的语法)?

不是在问是否可以简单地引用转发提交。我在问是否可以在不手动查找所需的修订版 SHA1 的情况下引用前向修订版。

4

2 回答 2

2

没有;但是,使用git rev-list然后进一步的工作,有可能找到指向给定提交的项目。您必须首先选择某个起点(可能--all),然后排除目标 rev 及其父级:

git rev-list --all --not rev

这当然会产生一长串 revs,其中许多是无趣的,因此需要进一步过滤:您想要那些 rev 的父级为rev.

这个 shell 脚本(没有错误检查等)只处理第一父:

target=$(git rev-parse $1)
git rev-list --all --not $target |
    while read rev; do
        if [ $(git rev-parse --verify --quiet $rev^) = $target ]; then
            echo $rev
        fi
    done

但应该很明显如何从那里开始想象它(请参阅文档git rev-list)。利用:

git rev-list -1 --parents $rev

将单个 rev 转换为“rev 及其父级”列表,用于合并,例如:

set -- $(git rev-list -1 --parents $rev)
shift # discard the rev itself
echo there are $# parents and they are $*
for parent do
    if [ $parent = $target ]; then
        echo $rev has $target as a parent
    fi
done

编辑:在大型仓库中,您可以获得更好的起点git branch --contains(正如RainerBlome 在“引用提交的子项”中所指出的那样。请注意,您需要解析*指示的当前分支,并且如果您有 HEAD “分离” “当前分支”是“无分支”,您可能想添加HEAD作为起点。然后,git rev-list --parents | grep ...是找到所需参考的快速方法。我已使用这些建议来提高性能等。

这是一个完整的脚本,也有一些错误检查;轻微测试。

#! /bin/sh
#
# git-rev-list-children.sh

find_branches()
{
        local target="$1"

        set -- $(git branch --contains $target |
            sed -e 's/^\* (.*)/HEAD/' -e 's/^[* ] //')
        case $# in
        0) echo "there are no branches containing $revname"; return 1;;
        esac
        echo $@
}

find_children()
{
        local target="$1"
        shift

        git rev-list --parents "$@" ^$target | grep " $target" |
            while read line; do
                set -- $line
                echo $1
            done
}

# add option parsing (--short?) here if desired
case $# in
0) echo "usage: git-rev-list-children <rev> ..." >&2; exit 1;;
esac

for revname do
        target=$(git rev-parse "$revname") || exit 1
        set -- $(find_branches "$revname" || exit 1)
        find_children "$target" "$@"
done
于 2013-09-09T21:55:24.753 回答
0

Git 提交对象只有一个父指针,并且只能向后遍历。提交可能有也可能没有一个或多个“转发”提交。

于 2013-09-09T15:28:46.317 回答