为什么`git describe -dirty`在描述一个clean checkout时要加上一个`-dirty`后缀?

qcuzuvrc  于 2023-05-05  发布在  Git
关注(0)|答案(3)|浏览(230)

我刚刚发现了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

当我使用use 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共享。

**更新:**我发现了一个解决方案,但我完全不知道这可能会有什么不同。

如果我在repo上运行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也显示“Local uncommitted changes,not checkin to index”,然后列出工作目录中的每个文件,但没有与它们的差异,只有---- filename ----行。

**进一步更新:**由于这仍然是一个问题,我最终写了一个git-describe-dirty脚本,它首先运行git describe --dirty,但如果它发现存储库是脏的,在再次尝试并获得第二个结果之前运行git update-index -q --refresh

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

htrmnn0y

htrmnn0y1#

如果你运行的是git 1.7.6或更早版本,你需要在使用git describe --dirty之前运行git update-index --refresh,因为索引可能已经过时了。您使用git diff --quiet HEAD的变通方法是可行的,因为“git diff”是一个瓷命令,可能会更新索引本身。
git 1.7.7的git commit that fixes this描述了这个问题:
当运行git describe --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 describe”输出,就像您的解决方法一样。对于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
6psbrbz9

6psbrbz92#

请注意,大约一年前,还有另一个关于git describe --dirty的错误修复:https://github.com/git/git/commit/a1e19004e11dcbc0ceebd92c425ceb1770e52d0b
“git --work-tree=$there --git-dir=$here describe --dirty”没有正确工作,因为它没有注意用户指定的工作树的位置
如果出现这个bug,这里显示的解决方法不起作用,所以我们不得不升级我们的安装。截至今天(2020-02-20),似乎没有现成的Debian buster 修复程序,但Debian bullseye 主git包现在与buster兼容。

cgh8pdjw

cgh8pdjw3#

Git 2.13(2017年第2季度)对--dirty标志进行了一点改进,增加了一个--broken标志,因为“git describe --dirty”在无法确定工作树中的状态是否与HEAD的状态匹配时会死亡(例如,“git describe --dirty”)。损坏的存储库或损坏的子模块)。
参见commit b0176ce(2017年3月21日),作者Stefan Beller ( stefanbeller )
(由Junio C Hamano -- gitster --合并至commit 844768a,2017年3月27日)

builtin/describe:引入--broken标志

git-describe告诉你你所在的版本号,或者错误,例如当你在存储库之外运行它时,这可能发生在下载tar ball而不是使用git获取源代码时。
为了保持这种只报错的特性,当不在存储库中时,严重的(子模块)错误必须降级为温和地报告它们,而不是完全报告git-describe错误。
为了实现这一点,引入了一个标志'--broken',它与'--dirty'具有相同的风格,但使用实际的子进程来检查脏性。
当该子节点意外死亡时,我们将追加'-broken'而不是'-dirty''。
请注意,在Git 2.41(2023年第2季度)中,“git describe --dirty”(man)学会了更好地使用稀疏索引。
参见Raghul Nanth A ( NanthR )commit 748b8d6(2023年4月3日)。
(由Junio C Hamano -- gitster --合并于commit 7ac228c,2023年4月21日)

describe:为describe启用稀疏索引

签字人:Raghul Nanth
git describeman)在(且仅在)使用“--dirty“标志运行时将索引与工作树进行比较。
这是由run_diff_index()函数完成的。
该函数已经意识到导致8d2c373的系列中的稀疏索引(“Merge分支'ld/sparse-diff-blame'”,2021-12-21,Git v2.35.0-rc 0--merge listed in batch #4)。
因此,我们可以将requires-full-index设置为false来表示“describe”。
请参阅“How to use git sparse-checkout in 2.27+“了解更多关于稀疏索引的信息。

相关问题