给定范围内标记的Git日志

给定范围内标记的Git日志,git,git-log,git-tag,Git,Git Log,Git Tag,我想做git log--no walk--tags--decoration=short所做的事情,但我还想单独检查给定范围内的标记(提交范围),而不仅仅是所有的标记。编辑:正如,git rev list(因此git log)有——通过修饰简化,哪些放弃没有(分支或)标记名指向它们的提交: git log --simplify-by-decoration --decorate=short X..Y 我可以做你想做的事。不幸的是,测试表明它还保留了分支名称指向它们的提交。这一点并非100%清楚:

我想做git log--no walk--tags--decoration=short所做的事情,但我还想单独检查给定范围内的标记(提交范围),而不仅仅是所有的标记。

编辑:正如,
git rev list
(因此
git log
)有
——通过修饰简化,哪些放弃没有(分支或)标记名指向它们的提交:

git log --simplify-by-decoration --decorate=short X..Y
我可以做你想做的事。不幸的是,测试表明它还保留了分支名称指向它们的提交。这一点并非100%清楚:

——通过装饰简化

选择由某个分支或标记引用的提交

但后来:

--simplifybydecoration
选项允许您仅查看大屏幕 历史的拓扑图,通过省略 未被标记引用

第行下方的原始答案(应该有效)


好的,听起来您想将类似
X..Y
的效果与“仅选择具有指向它们的标记的提交”结合起来

有两个主要的Git命令用于执行此类操作:

  • ,它允许您使用
    refs/
    名称空间中任何位置的任何名称;标签位于
    refs/tags/

  • ,它实际上是与git log
相同的命令,只是默认情况下不显示提交消息,而是显示哈希值。(还有其他一些细微的区别,但它们非常相似,
git log
git rev list
都是从一个源文件构建的。)

这里的主要问题是,虽然
git log
/
git rev list
很容易让您限制选择了哪些提交,例如使用
Y^X
X..Y
,或者使用
--无行走--标记[=模式]
,但它们不太擅长设置交叉操作。它们可以直接执行有限的联合式操作,例如,
git rev list--no walk--tags=foo\*--tags=bar\*--branchs=baz\*
将打印每个提交的ID,这些提交标记的名称与
foo*
bar*
匹配,或者由与
baz*
匹配的分支名称指向

revlist
命令可以使用管道和
--stdin
执行完整的、任意的集合并集操作,但不能执行交叉操作。这是Mercurial语法优于Git语法的一个方面。当然,Mercurial的优点是可以在内部使用所有Python。)

不过,您需要的是两个集合的交集:

  • 集合1:您的范围选择,可能类似于
    X..Y
    --since=date1--until=date2

  • 集合2:由(部分或全部)标记指向的每个提交

计算这组交集需要一些代码。在类Unix系统上,我们拥有所需的所有工具:Git本身和
comm
,它们可以完成设置的交集。
comm
实用程序需要对其输入进行排序,因此我们将在此处通过管道对每组进行排序。所以我们只需要一个简短的(7行)脚本

我们从通常的临时文件样板开始,例如:

tf1=$(mktemp) || die "can't make first temp file"
trap "rm -f $tf1" 0 1 2 3 15
tf2=$(mktemp) || die "can't make second temp file"
trap "rm -f $tf1 $tf2" 0 1 2 3 15
现在,我们使用
git rev list
获得集合1:

git rev-list <specifiers> | sort > $tf1
请注意,这是
%(object)
,而不是
%(objectname)
;后者只能得到带注释的标记对象的ID

最后,我们只需要两个临时文件中的提交ID,也就是说,我们需要
comm-12
,它抑制除第3列以外的所有内容(两个文件中的行):

该脚本的输出是要显示的一组提交(顺序由提交哈希排序决定,因此我们将依赖于
git log
来修复排序顺序)。现在我们只使用原始的
git log
命令,但在所选提交上运行它:

git log --no-walk --decorate=short --date-order $(script)
(当然,这些都没有经过测试)

如果
git rev list
有一个
--stdinintersect
选项,我们可以在git和shell中完成这一切:

git log --no-walk --decorate=short $( \
    git for-each-ref --format='%(object)' refs/tags | \
    git rev-list --stdin-intersect X..Y \
)

但事实并非如此,因此需要小脚本。

什么范围?按日期?通过开始和结束提交/标记ID?还有别的吗?@Wolf commit/tag id。将更新问题。什么是“标记范围”?如果标签是
fred
barney
betty
wilma
,哪些标签在哪个范围内?(更有用的是,您可能需要为每个ref使用
git--format='%(refname:short)'refs/tags
,然后您可以通过管道将这些refs/tags导入程序以进行标记选择。将所选标记作为附加参数馈送到
git log--no walk--decoration=short
)@torek标记是提交的名称,因此,当谈到一个标记时,我只是指该提交的引用,您可以将其理解为提交引用。啊,所以您可能希望只选择与类似
X..Y
aka
Y^X
的提交匹配的标记。您需要为此编写代码,为每个ref使用
git
git rev list
。虽然rev list本身可以执行联合操作,但它不能执行交叉操作。)还有
git log——通过装饰简化X..Y
@jthill啊,不,它工作得不太好。我正在列出未标记的提交。我根本不确定日志遵循的是什么模式(使用jthill命令),它只是显示了一些提交,包括标记的提交,但也列出了一些其他提交,具有多个头或其他分支的名称。啊,是的,它正在记录每个分支提交头和标记。
git log --no-walk --decorate=short --date-order $(script)
git log --no-walk --decorate=short $( \
    git for-each-ref --format='%(object)' refs/tags | \
    git rev-list --stdin-intersect X..Y \
)