为什么“git-descripte-dirty”在描述干净的签出时会添加“-dirty”后缀



我刚刚发现了git describe--dirty选项,它看起来应该做一些非常有用的事情,即当工作树变脏时,在git describe的输出上添加一个后缀,但我的一些存储库似乎不是这样:

$ git status
# On branch 8.30
nothing to commit (working directory clean)
$ git describe --dirty
8.30rel-8-g9c1cbdb-dirty

我认为这可能是因为工作目录相对于标签是脏的,但事实似乎也并非如此:

$ git status
# On branch 1.4
nothing to commit (working directory clean)
$ git describe --tags --dirty --long
1.4rel-0-gfedfe66-dirty

当我使用Mercurial时,我曾经大量使用hg id,并且喜欢它的默认行为是在它为脏存储库报告的任何提交哈希中添加+后缀,所以从那以后我一直在寻找等效的git,但鉴于文档:,git describe --dirty似乎没有达到我所期望的效果

   --dirty[=<mark>]
       Describe the working tree. It means describe HEAD and appends
       <mark> (-dirty by default) if the working tree is dirty.

我是误解了--dirty应该做什么,还是没有正确使用它?

如果有什么不同的话,所有的git存储库都是通过buckminster部署的,因此不涉及子模块,文件系统是nfs共享。


更新:我发现了一个变通办法,但我完全不知道这会有什么不同。

如果我在回购上运行git diff --quiet HEAD,那么git describe会突然像我预期的那样工作:

$ git status
# On branch 8.30
nothing to commit (working directory clean)
$ git describe --dirty
8.30rel-8-g9c1cbdb-dirty
$ git diff --quiet HEAD
$ git describe --dirty
8.30rel-8-g9c1cbdb

我还发现,当git describe将存储库报告为dirty时,gitk也显示"本地未提交的更改,未签入索引",然后列出工作目录中的每个文件,但没有与它们的差异,只有---- filename ----行。


进一步更新:由于这仍然是一个问题,我最终编写了一个git-describe-dirty脚本,该脚本从运行git describe --dirty开始,但如果发现存储库脏了,则运行git update-index -q --refresh,然后重试并获得第二个结果。

当迭代数百个存储库时,与每次运行git update-index -q --refresh ; git describe --dirty相比,使用git describe-dirty并仅对最初指示其脏的存储库运行索引更新可以节省大量时间。

如果运行的是git 1.7.6或更早版本,则需要在使用git describe --dirty之前运行git update-index --refresh,因为索引可能已过时。使用git diff --quiet HEAD的解决方法之所以有效,是因为"git-diff"是一个瓷命令,可能会更新索引本身。

为git 1.7.7修复此问题的git commit描述了这个问题:

当运行git-descripte-dirty时,应该刷新索引。先前缓存的索引会导致describe认为该索引是脏的,事实上,它只是过时了。

请注意,您描述的步骤的确切顺序不应该有这个问题,因为git status会更新索引。但我仍然认为你会看到同样的问题,因为你描述的变通方法是匹配的。以下是我如何证明这个问题:

% git describe --tags --dirty
v1.0.0
% touch pom.xml
% git describe --tags --dirty
v1.0.0-dirty
% git status
# On branch dev
nothing to commit (working directory clean)
% git describe --tags --dirty
v1.0.0

在这里,运行"git-status"会作为副作用更新索引,并修复"git-descripte"输出,就像您的解决方法一样。git 1.7.6及更早版本的正确管道修复程序为:

% touch pom.xml
% git describe --tags --dirty
v1.0.0-dirty
% git update-index --refresh
% git describe --tags --dirty
v1.0.0

请注意,大约一年前还有另一个关于git describe --dirty的错误修复:https://github.com/git/git/commit/a1e19004e11dcbc0ceebd92c425ceb1770e52d0b

"git--工作树=$there--git dir=$here-descripte--dirty"没有正确工作,因为它没有注意用户指定的工作树的位置

在出现此错误的情况下,此处显示的解决方案不起作用,因此我们不得不升级安装。截至今天(2020-02-20(,Debianbuster似乎没有现成的修复程序,但Debian牛眼主git包目前与buster兼容。

Git 2.13(2017年第二季度(在--dirty标志上用--broken标志改进了一点,因为";CCD_ 28";当无法确定工作树中的状态与HEAD的状态匹配(例如已损坏存储库或损坏的子模块(。

参见Stefan Beller(stefanbeller(提交的b0176ce(2017年3月21日(
(由Junio C Hamano合并——gitster——提交844768a,2017年3月27日(

builtin/describe:引入--broken标志

git-describe告诉您所处的版本号或错误,例如,当您在存储库外运行它时,这可能发生在下载tar ball而不是使用git获取源代码时。

为了保持这种只出错的特性,当不在存储库中时,必须将严重(子模块(错误降级为温和地报告它们而不是使CCD_ 34完全出错。

为了实现这一点,引入了一个标志"--broken",它与"--dirty"相同,但使用了一个实际的子进程来检查脏度
当孩子意外死亡时,我们将附加"-broken"而不是'-dirty'


注意,对于Git 2.41(Q2 2023(;CCD_ 39">(man(学会更好地使用稀疏索引。

参见Raghul Nanth A提交的748b8d6(2023年4月3日((NanthR(
(由Junio C Hamano合并——gitster——提交7ac228c,2023年4月21日(

describe:为描述启用稀疏索引

签字人:Raghul Nanth A

CCD_ 43(man(将索引与工作树进行比较;CCD_ 44";旗帜
这是由run_diff_index()函数完成的
该函数已经意识到了导致8d2c373的系列中的稀疏索引("Merge branch'ld/solese diff-chrain'",2021-12-21,Git v2.35.0-rc0-Merge列在第4批中(
因此,我们可以将requires full index设置为false;描述";。

参见";如何在2.27+";有关稀疏索引的更多信息。

最新更新