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

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


当前回答

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

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

其他回答

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

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

[core]
  filemode = false

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

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

cd my-submodule
git push
cd ../
rm -rf my-submodule
git submodule init
git submodule 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 submodule foreach --recursive git checkout .

这并没有为我做的技巧,但它给了我一个文件列表(在我的情况下只有一个),在子模块中已更改(没有我做任何事情)。

所以我可以转到子模块,git状态显示我的head被分离-> git checkout master, git状态再次看到修改后的文件,git checkout >filename<, git拉和一切正常。