如何在不修改 .git/index 的情况下运行 git status - 例如在 PROMPT_COMMAND 中
Posted
技术标签:
【中文标题】如何在不修改 .git/index 的情况下运行 git status - 例如在 PROMPT_COMMAND 中【英文标题】:How to run git status without modifying .git/index - such as in a PROMPT_COMMAND 【发布时间】:2018-05-06 07:46:37 【问题描述】:我有一个 PROMPT_COMMAND,它使用 git status 显示 git 分支信息,不幸的是,当调用 'git status' 时,它似乎正在修改 .git/index 文件。
这不好,因为如果您使用对目标目录具有权限的用户运行(例如在共享文件系统上或如果您作为特权帐户运行) - 最终会更改该文件的所有权给您的用户,因为 git 似乎正在重新创建 .git/index 文件。
有什么方法可以运行 'git status' 来防止它修改 .git/index 文件?
【问题讨论】:
稍微回避这个问题,为什么不直接克隆存储库而不是让多个用户共享同一个存储库? 问题在于启用了 git 感知提示的管理用户。通常这不是问题 - 但只是注意到仅 cd'ing 进入其他用户目录(应用程序帐户)会导致文件权限/所有权更改。跟踪到“git status”命令的问题。 ref-parse 不显示症状。其他人也有与 Dropbox 相关的类似问题,并且索引文件不断被修改 - 触发同步 - 对于这种情况没有有用的答案。 很好的理由:) 现在的问题是确定在什么情况下,.git/index
被修改了。
在 builtin/commit.c cmd_status() 中看起来是这样的:`refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &s.pathspec, NULL, NULL);` 不幸的是没有以任何方式包装.
或调用:update_index_if_able(&the_index, &index_lock);
【参考方案1】:
运行git status
不会修改索引文件。
$ ls -l .git/index
-rw-r--r-- 1 adelsbergerm 1049089 445386 Jul 11 15:07 .git/index
$ git status
On branch REDACTED
Your branch is ahead of 'origin/REDACTED' by 211 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: REDACTED
no changes added to commit (use "git add" and/or "git commit -a")
$ ls -l .git/index
-rw-r--r-- 1 adelsbergerm 1049089 445386 Jul 11 15:07 .git/index
您声称修改文件会更改所有权的说法也值得怀疑。
我想你可能有一些操作系统,没人听说过在哪里读取文件会自动写入文件,写入文件会自动声明其所有权,但除非这些似乎是观察错误和您需要在其他地方寻找问题。
【讨论】:
git status
确实在某些情况下似乎触及.git/index
。我在运行 git status
之前和之后有一段时间没看过的 repo 中检查了.git/index
的时间戳,修改时间从 10 月 10 日更改为当前时间。 (macOS 10.12.6,git
2.13.6)。
@chepner - 我展示了我的作品。如果您认为您的不同意见值得一票否决,那么也一定值得展示您的意见。如果您可以概述git status
写入索引的情况,请随意。祝你好运。
不知道具体情况;我只知道它是可能的,所以如果他们也观察到索引的变化,这并不能真正帮助OP。
@MarkAdelsberger 您证明了运行git status
不会总是更改文件。如果您可以证明运行 git status
从不 更改文件(考虑到 OP 和我都观察它在某些情况下发生,这将是一项了不起的壮举),我会高兴地收回我的反对票。
git status
可以重写索引文件。请参阅this section of builtin/commit.c(git status
的驱动程序在提交源中!)并注意use_optional_locks
中的默认设置是启用更新索引。【参考方案2】:
如果您的 Git 版本至少为 2.15,请运行 git --no-optional-locks status
。请参阅commit 27344d6a6c8056664966e11acf674e5da6dd7ee3,它添加了这个新选项。
否则,如果您在运行git status
之前可以确保索引是最新的,git status
将不会再次更新它;但这有点棘手。或者,您可以暂时将索引设为只读——但这会干扰其他并行运行的git
命令——或者您可以将索引复制到一个临时位置并运行git status
,并将GIT_INDEX_FILE
设置为路径名临时的,然后删除临时的。最后一个很笨拙,但可以与历史 Git 一起使用。
(顺便说一下,我没有从my own hand-rolled status-constructing bash prompt code 运行git status
,尽管它不是专门为此原因。相反,我运行一个显式的git update-index
,你可以以性能为代价省略它,也许是基于在$PWD
。)
【讨论】:
感谢您提供指向该选项的指针,一旦我部署了该版本,它看起来会很好用。 谢谢!在/usr/bin/git --no-optional-locks show -s --format=%B $SHA
以上是关于如何在不修改 .git/index 的情况下运行 git status - 例如在 PROMPT_COMMAND 中的主要内容,如果未能解决你的问题,请参考以下文章
Excel 2010:如何在不修改其输入值的情况下跨多个单元格更改公式?
Ubuntu系统下如何在不重启的情况下永久修改hostname主机名