Git 是否有任何特定的语法来引用转发提交(不使用它&x27;的SHA1)?

Git 是否有任何特定的语法来引用转发提交(不使用它&x27;的SHA1)?,git,Git,我可以使用^和~*number*引用向后修订,如319411a^或HEAD~3 是否有任何特定的语法来引用前向提交(类似于上面的语法) 我不是在问是否可以简单地引用转发提交。我想问的是,是否可以在不手动查找所需修订SHA1的情况下引用正向修订。Git commit对象只有一个父指针,遍历仅向后。提交可能有也可能没有一个或多个“转发”提交。没有;但是,使用git rev list然后进一步工作,就可以找到指向给定提交的项。您必须首先选择某个起点(可能是--all),然后排除目标版本及其父版本: g

我可以使用
^
~*number*
引用向后修订,如
319411a^
HEAD~3

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


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

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

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

git版本列表--全部--非版本

当然,这会产生一个很长的rev列表,其中许多都是无趣的,因此需要进一步过滤:您需要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
的文档)。使用:

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

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获得更好的起点(如所述)。请注意,您需要解析掉指示当前分支的
*
,如果您将头“分离”,则“当前分支”为“无分支”您可能需要添加
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
!/bin/sh
#
#git-rev-list-children.sh
查找分支()
{
本地目标=“1美元”
集合--$(git分支--包含$target)|
sed-e's/^\*(.*)/HEAD/'-e's/^[*]/')
案例$#in
0)回显“没有包含$revname的分支”;返回1;;
以撒
回音$@
}
查找儿童()
{
本地目标=“1美元”
转移
git版本列表--父级“$@”^$target | grep“$target”|
边读边做
设置--$line
回声1美元
完成
}
#如果需要,在此处添加选项解析(--short?)
案例$#in
0)回显“用法:git版本列表子项…”2;出口1;;
以撒
对于revname do
target=$(git rev parse“$revname”)| |退出1
设置--$(查找分支“$revname”| |退出1)
查找子项“$target”“$@”
完成

的可能重复,还有@Hasturkun这些问题都没有提到它的语法。用这两种方法,你必须找出想要的结果SHA1@talles:没有子/子代提交的语法,AFAIK。(同时,链接的问题涉及到语法。)我还想指出并建议您阅读
#! /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