Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
列出git repo中的标记,按它们在图形中的显示方式排序_Git_Sorting_Tags - Fatal编程技术网

列出git repo中的标记,按它们在图形中的显示方式排序

列出git repo中的标记,按它们在图形中的显示方式排序,git,sorting,tags,Git,Sorting,Tags,给定一个分支和提交,我想找到引入给定提交的第一个标记 我想写一个脚本来实现这一点 我不想打印所有标记(git log--tags--simplify by decoration可以打印),只打印出现在分支尖端和提交之间的标记。我可以使用--merged和--contains选项的git-tag命令来实现这一点,但它会打印按名称排序的标签。我需要按照它们在图表中的显示方式对它们进行排序(这样我就可以只做| tail-1),而不能通过按asauthordate、committerdate、creat

给定一个分支和提交,我想找到引入给定提交的第一个标记

我想写一个脚本来实现这一点

我不想打印所有标记(git log--tags--simplify by decoration可以打印),只打印出现在分支尖端和提交之间的标记。我可以使用
--merged
--contains
选项的
git-tag
命令来实现这一点,但它会打印按名称排序的标签。我需要按照它们在图表中的显示方式对它们进行排序(这样我就可以只做
| tail-1
),而不能通过按as
authordate
committerdate
creatordate
taggerdate
对它们进行排序

为了提供更多的上下文,该脚本与这个SO of
git find merge
正好相反

更新:

#!/bin/sh

commit=$1
if [ -z $commit ]; then
    echo 1>&2 "fatal: commit is required"
    exit 1
fi
commit=$(git rev-parse $commit)
branch=${2-@}
pattern=${3-.}

# tags between branch and commit sorted as in graph following a pattern
tags=$(
    git log --decorate --simplify-by-decoration --ancestry-path \
        --pretty="format:%D" $commit..$branch \
    | sed 's/, /\n/g' \
    | grep '^tag: ' \
    | sed 's/tag: //' \
    | egrep "$pattern"
)
if [ ! -z "$tags" ]; then
    echo "tags:"
    for tag in $tags; do
        echo "  $tag"
    done
    echo ""
fi

tag=$(echo "$tags" | tail -1)
if [ -z "$tag" ]; then
    # tag not found
    echo 1>&2 "fatal: no tag found"
    exit 1
fi

git show -s "$tag"
下面是我最终从torek的答案(github链接: 脚本)

~/bin/git查找标记:

#!/bin/sh

commit=$1
if [ -z $commit ]; then
    echo 1>&2 "fatal: commit is required"
    exit 1
fi
commit=$(git rev-parse $commit)
branch=${2-@}
pattern=${3-.}

# tags between branch and commit sorted as in graph following a pattern
tags=$(
    git log --decorate --simplify-by-decoration --ancestry-path \
        --pretty="format:%D" $commit..$branch \
    | sed 's/, /\n/g' \
    | grep '^tag: ' \
    | sed 's/tag: //' \
    | egrep "$pattern"
)
if [ ! -z "$tags" ]; then
    echo "tags:"
    for tag in $tags; do
        echo "  $tag"
    done
    echo ""
fi

tag=$(echo "$tags" | tail -1)
if [ -z "$tag" ]; then
    # tag not found
    echo 1>&2 "fatal: no tag found"
    exit 1
fi

git show -s "$tag"

看来,
git log
已经做了您想要做的事情:

git log --oneline --decorate --simplify-by-decoration --ancestry-path start..end
例如,我在Git的Git存储库上运行了以下内容:

$ git log --oneline --decorate --simplify-by-decoration --ancestry-path \
    HEAD~20..HEAD
b06d36431 (HEAD -> master, tag: v2.13.0, origin/master, origin/HEAD) Git 2.13
4fa66c85f (tag: v2.13.0-rc2) Git 2.13-rc2
027a3b943 (tag: v2.13.0-rc1) Git 2.13-rc1
(请注意,这里没有
--tags
)。有关注意事项,请参见下面的详细信息

细节 一般来说,这个问题是无法完全解决的,因为没有严格定义图形的发出顺序。我们(从文档中)知道,
--graph
打开
--topo sort
;但也有两种不同拓扑类型都有效的图,例如经典菱形:

 ...     newer / child commits
  |
  D
 / \
B   C
 \ /
  A      older / parent commits
  |
 ...
这里的两个有效订单是(D,B,C,A)和(D,C,B,A),我们不知道(除非我们作弊1)将使用哪个订单
git log
。如果除了A之外的所有代码都被标记,那么最后一个将是(B,C)中的一个,但我们不知道是哪一个

如果您可以确定没有不明确的排序,VonC建议的
--contains
,或者更直接的
git merge base--is consence
测试,可以确定任何给定的标记提交是否是任何其他标记提交的祖先。“拓扑顺序”的定义是“先显示父项后再显示子项”,即“最父项-y”的是最后一个

如果没有,并且您想要匹配
git log
将要做的事情,则需要使用
git log
。不过,既然它已经实现了您想要的功能,就使用它吧。:-)您希望它:

  • 仅日志标记的提交:
    --通过修饰简化
    或多或少地完成了这项工作,但它也会包括分支名称(因此,请注意不要只使用
    | tail-1
    :您需要更复杂一点,以便获取最后一个标记,但您可以沿着
    grep标记:
    的路径进行
  • 仅显示在某个端点(
    结束
    )处或之前以及某个起点(
    ^start
    )之后的提交。请注意,如果要包括起点本身,请添加
    ^@
    后缀,这意味着“提交的所有父项,但不包括提交本身”
  • 避免不是
    开始
    提交的子项的提交:
    --祖先路径
    通过排除从
    结束
    可到达的、尚未被
    ^start
    排除的提交来达到目的
我们将
^start-end
拼写为更熟悉的
start..end
,尽管两种方法都可以



1
git log的源代码将(非常困难)告诉您在这些情况下实际发生的排序。

我记得(2011)及其--no-ff反模式。从那以后,我发现了--no ff的例子,特别是在最近(2017年5月)的文章中,你真的确定不能调整/排序
git标记--contains
()以得到你想要的吗?@VonC,默认排序是按名称排序,而按其他键(字段名)排序不是我想要的(详细信息请参见问题).
git descripe
显示可从提交中访问的最新标记,并选择最新标记
git descripe--contains
选择提交后出现的(最早的)标记。但两者都以标签的创建日期为准。如果有一个
--graph
选项,它会更好。
git log--oneline--decoration--simplify by decoration
会按照标签在图形中的显示列出标签(这是我想要的),但它会在repo中列出所有标签,并且不遵守
start..end
范围。所以,当范围没有任何标记时,这不起作用。@hIpPy:quitious;正如我在上面的输出中所显示的,它在Git的Git回购中对我起了作用。无论存储库中是否有标记,
--祖先路径^limit start
必须工作。不要使用
--tags
,因为这提供了太多的起点。我也有
--tags
。我的错,对不起。