我刚刚发现了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
相比,节省了大量时间。
3条答案
按热度按时间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 status”会更新索引,并修复“git describe”输出,就像您的解决方法一样。对于git 1.7.6及更早版本,正确的管道修复应该是:
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兼容。
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 describe
(man)在(且仅在)使用“--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+“了解更多关于稀疏索引的信息。