如何在不修改 .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 中的主要内容,如果未能解决你的问题,请参考以下文章

如何在不修改任何项目的情况下加速 xcode 构建?

Excel 2010:如何在不修改其输入值的情况下跨多个单元格更改公式?

Ubuntu系统下如何在不重启的情况下永久修改hostname主机名

如何在不更改代码的情况下修改 wordpress 主题?

如何在不影响其他帖子类型的情况下修改默认 WP 帖子的 slug?

如何在不使用xml的情况下修改材质组件的主题?