我刚刚运行了一个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

这是什么意思?我该怎么解决呢?


当前回答

同样,删除子模块,然后运行git子模块init和git子模块update显然也可以达到这个目的,但可能并不总是合适的或可能的。

其他回答

十年后的2021年1月更新:

"git diff"(man)显示子模块工作树中有未跟踪的cruft,如submodule commit <objectname>-dirty,但一个自然的期望是"-dirty"指示符将与"git describe -dirty"(man)对齐,该指示符不认为工作树中有未跟踪的文件是脏文件的来源。 Git 2.31 (Q1 2021)已经修复了不一致的问题。

参见Sangeeta Jain (sangu09)提交的8ef9312(2020年11月10日)。 (由Junio C Hamano—gitster—在commit 0806279中合并,2021年1月25日)

Diff:不显示未跟踪文件的子模块为"-dirty" 署名:Sangeeta Jain

Git diff reports a submodule directory as -dirty even when there are only untracked files in the submodule directory. This is inconsistent with what git describe --dirty(man) says when run in the submodule directory in that state. Make --ignore-submodules=untracked the default for git diff(man) when there is no configuration variable or command line option, so that the command would not give '-dirty' suffix to a submodule whose working tree has untracked files, to make it consistent with git describe --dirty that is run in the submodule working tree. And also make --ignore-submodules=none the default for git status(man) so that the user doesn't end up deleting a submodule that has uncommitted (untracked) files.

Git配置现在包括在它的手册页:

默认情况下,这设置为untracked,以便任何untracked 子模块被忽略。


原答案(2011)

正如Mark Longair的博客文章Git子模块解释中提到的,

git的1.7.0及更高版本包含了git子模块行为中一个恼人的变化。 现在,如果子模块有任何修改过的文件或未跟踪的文件,那么它们就被视为脏的,而在以前,只有当子模块中的HEAD指向错误的提交时才会被视为脏的。

在git子模块的输出中,加号(+)的含义已经发生了变化,当你第一次遇到这个问题时,需要一段时间才能弄清楚哪里出了问题,例如通过查看changelogs或在git上使用git平分。Git找到变化。对用户来说,引入一个不同的符号表示“在指定的版本,但肮脏”会更友好。

你可以通过以下方法修复:

在返回父repo (diff不应该再报告“脏”文件)之前,在每个子模块中提交或撤销更改/演进。要撤消对子模块的所有更改,只需cd到子模块的根目录并执行git签出。

dotnetCarpenter注释,你可以做一个:git子模块foreach——递归git签出。

或者在你的git diff中添加——ignore-submodules,暂时忽略那些“脏”子模块。

Git 1.7.2新版功能

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

git status --ignore-submodules=dirty

在我的例子中,我不确定是什么导致了这种情况的发生,但我知道我只是想让子模块被重置到它们最新的远程提交,然后完成它。这涉及到把这里几个不同问题的答案结合起来:

Git子模块更新——递归——远程——初始化

来源:

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

简单的方法拉最新的所有git子模块

同样,删除子模块,然后运行git子模块init和git子模块update显然也可以达到这个目的,但可能并不总是合适的或可能的。

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


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

[submodule "foobar"]
    url = git@bitbucket.org:foo/bar.git
    ignore = untracked

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

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

要禁用子模块中的文件模式,可以编辑/。Git /modules/path/到/your/submodule/config并添加

[core]
  filemode = false

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