Git diff 说子项目很脏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4873980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:00:58  来源:igfitidea点击:

Git diff says subproject is dirty

gitgit-submodules

提问by mrwooster

I have just run a git diff, and I am getting the following output for all of my approx 10 submodules

我刚刚运行了一个 git diff,我得到了所有大约 10 个子模块的以下输出

diff --git a/.vim/bundle/bufexplorer b/.vim/bundle/bufexplorer
--- a/.vim/bundle/bufexplorer
+++ b/.vim/bundle/bufexplorer
@@ -1 +1 @@
-Subproject commit 8c75e65b647238febd0257658b150f717a136359
+Subproject commit 8c75e65b647238febd0257658b150f717a136359-dirty

What does this mean? How do I fix it?

这是什么意思?我如何解决它?

回答by VonC

As mentioned in Mark Longair's blog post Git Submodules Explained,

正如 Mark Longair 的博客文章GitSubmodules Explained 中提到的,

Versions 1.7.0 and later of git contain an annoying changein the behavior of git submodule.
Submodules are now regarded as dirty if they have any modified files or untracked files, whereas previously it would only be the case if HEAD in the submodule pointed to the wrong commit.

The meaning of the plus sign (+) in the output of git submodule has changed, and the first time that you come across this it takes a little while to figure out what's going wrong, for example by looking through changelogs or using git bisect on git.git to find the change. It would have been much kinder to users to introduce a different symbol for “at the specified version, but dirty”.

1.7.0 及更高版本的 git 包含git 子模块行为的恼人变化
如果子模块有任何修改过的文件或未跟踪的文件现在它们被认为是脏的,而以前只有在子模块中的 HEAD 指向错误的提交时才会出现这种情况。

+git submodule 输出中加号 ( )的含义发生了变化,当您第一次遇到这种情况时,需要花一些时间才能找出问题所在,例如通过查看更改日志或在 git 上使用 git bisect .git 查找更改。为“在指定的版本中,但很脏”引入一个不同的符号对用户来说会好得多。

You can fix it by:

您可以通过以下方式修复它:

  • either committing or undoing the changes/evolutions within each of your submodules, before going back to the parent repo (where the diff shouldn't report "dirty" files anymore). To undo all changes to your submodule just cdinto the root directory of your submodule and do git checkout .

    dotnetCarpentercommentsthat you can do a: git submodule foreach --recursive git checkout .

  • or add --ignore-submodulesto your git diff, to temporarily ignore those "dirty" submodules.

  • 提交或撤消每个子模块中的更改/演变,然后再返回父存储库(差异不应再报告“脏”文件)。要将对子模块的所有更改撤消到子模块cd的根目录中,然后执行git checkout .

    dotnetCarpenter评论说您可以执行以下操作:git submodule foreach --recursive git checkout .

  • 或添加--ignore-submodules到您的git diff, 以暂时忽略那些“脏”子模块。

New in Git version 1.7.2

Git 版本 1.7.2 中的新功能

As Noamcomments below, this questionmentions that, since git version 1.7.2, you can ignore the dirty submodules with:

正如Noam在下面评论的那样这个问题提到,从 git 1.7.2 版开始,你可以忽略脏子模块:

git status --ignore-submodules=dirty

回答by user1178907

Also removing the submodule and then running git submodule initand git submodule updatewill obviously do the trick, but may not always be appropriate or possible.

还删除子模块然后运行git submodule initgit submodule update显然可以解决问题,但可能并不总是合适或可能的。

回答by Devpool

To ignore all untracked files in any submodule use the following command to ignore those changes.

要忽略任何子模块中的所有未跟踪文件,请使用以下命令忽略这些更改。

git config --global diff.ignoreSubmodules dirty

It will add the following configuration option to your local git config:

它将以下配置选项添加到您的本地 git 配置:

[diff]
  ignoreSubmodules = dirty

Further information can be found here

更多信息可以在这里找到

回答by Ralph Versteegen

EDIT: This answer (and most of the others) are obsolete; see Devpool's answer instead.

编辑:这个答案(以及大多数其他答案)已经过时;请参阅Devpool 的回答



Originally, there were no config options to make "git diff --ignore-submodules" and "git status --ignore-submodules" the global default (but see also Setting git default flags on commands). An alternative is to set a default ignoreconfig option on each individual submodule you want to ignore (for both git diffand git status), either in the .git/configfile (local only) or .gitmodules(will be versioned by git). For example:

最初,没有配置选项可以使“ git diff --ignore-submodules”和“ git status --ignore-submodules”成为全局默认值(但另请参阅在命令上设置 git 默认标志)。另一种方法是在文件中(仅限本地)或(将由 git 进行版本控制)在ignore要忽略的每个子模块上设置默认配置选项(对于git diff和)。例如:git status.git/config.gitmodules

[submodule "foobar"]
    url = [email protected]:foo/bar.git
    ignore = untracked

ignore = untrackedto ignore just untracked files, ignore = dirtyto also ignore modified files, and ignore = allto ignore also commits. There's apparently no way to wildcard it for all submodules.

ignore = untracked忽略未跟踪的文件,ignore = dirty也忽略修改的文件,并ignore = all忽略提交。显然没有办法为所有子模块通配符。

回答by Robin Ren

This is the case because the pointer you have for the submodule isn't what is actually in the submodule directory. To fix this, you must run git submodule updateagain:

之所以如此,是因为您拥有的子模块指针并不是子模块目录中实际存在的指针。要解决此问题,您必须git submodule update再次运行:

回答by JustABit

git submodule foreach --recursive git checkout .

This didn't do the trick for me but it gave me a list of files (in my case only one) that had been changed in the submodule (without me doing anything there).

这对我没有帮助,但它给了我一个在子模块中已更改的文件列表(在我的情况下只有一个)(我没有在那里做任何事情)。

So I could head over to the submodule and git status showed me that my HEAD was detached -> git checkout master, git status to see the modified file once again, git checkout >filename<, git pull and everything fine again.

所以我可以转到子模块,git status 显示我的 HEAD 已分离 -> git checkout master,git status 再次查看修改后的文件,git checkout >filename<,git pull 一切正常。

回答by Szymon Wygnański

I ended up removing the submodule directory and initializing it once again

我最终删除了子模块目录并再次初始化它

cd my-submodule
git push
cd ../
rm -rf my-submodule
git submodule init
git submodule update

回答by dryobs

A submodule may be marked as dirty if filemode settings is enabled and you changed file permissions in submodule subtree.

如果启用了文件模式设置并且您更改了子模块子树中的文件权限,则子模块可能会被标记为脏。

To disable filemode in a submodule, you can edit /.git/modules/path/to/your/submodule/configand add

要在子模块中禁用文件模式,您可以编辑/.git/modules/path/to/your/submodule/config并添加

[core]
  filemode = false

If you want to ignore all dirty states, you can either set ignore = dirtyproperty in /.gitmodulesfile, but I think it's better to only disable filemode.

如果你想忽略所有脏状态,你可以ignore = dirty/.gitmodules文件中设置属性,但我认为最好只禁用文件模式。

回答by Adam Westbrook

In my case I wasn't sure what had caused this to happen, but I knew I just wanted the submodules to be reset to their latest remote commit and be done with it. This involved combining answers from a couple of different questions on here:

就我而言,我不确定是什么导致了这种情况的发生,但我知道我只是希望将子模块重置为其最新的远程提交并完成它。这涉及结合这里几个不同问题的答案:

git submodule update --recursive --remote --init

git submodule update --recursive --remote --init

Sources:

资料来源:

How do I revert my changes to a git submodule?

如何将更改恢复到 git 子模块?

Easy way to pull latest of all git submodules

提取所有 git 子模块的最新版本的简单方法