Git diff说子项目很脏

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

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

正如Mark Longair的博客文章Git Submodules Explained所述 ,

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

git子模块输出中的加号( + )的含义已经改变了,第一次遇到这个时候需要一点时间来弄清楚什么是错误的,比如通过查看更新日志或者使用git bisect git.gitfind变化。 用户为了“在指定的版本,但是很脏”中引入不同的符号会更友善。

你可以通过以下方式解决

  • 在返回到父回购(其中diff不应该报告“脏”文件)之前,在每个子模块中提交或撤销更改/发展。 要撤销对子模块的所有更改,只需cd进入子模块的根目录并执行git checkout .

    dotnetCarpenter的 意见 ,你可以做一个: git submodule foreach --recursive git checkout .

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

Git 1.7.2版新增function

正如下面的 Noam 注释 , 这个问题提到,自git版本1.7.2以来,您可以忽略脏子模块:

 git status --ignore-submodules=dirty 

也删除子模块,然后运行git submodule initgit submodule update显然将做的伎俩,但可能并不总是适当或可能的。

这是因为您对子模块的指针不是子模块目录中的实际内容。 要解决这个问题,你必须再次运行git submodule update

 git submodule foreach --recursive git checkout . 

这对我来说并没有什么窍门,但是它给了我一个在子模块中被改变的文件列表(在我的情况下只有一个)(没有我在那里做任何事情)。

所以我可以头部到子模块和git状态告诉我,我的HEAD被分离 – > git checkout master,git status再次查看修改后的文件,git checkout> filename <,git pull,一切正常。

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

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

 [core] filemode = false 

如果要忽略所有脏状态,可以在/.gitmodules文件中设置ignore = dirty属性,但是我认为只禁用filemode会更好。

不幸的是,似乎没有configuration选项使“git diff –ignore-submodules”和“git status –ignore-submodules”成为全局默认值(但也请参阅在命令上设置git默认标志 )。 但是,您可以在.git/config文件(仅限本地)或.gitmodules (将由git版本化)中为每个要忽略的子模块(对于git diffgit status )设置默认ignoreconfiguration选项。 例如:

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

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

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

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

在我的情况下,我不知道是什么导致了这种情况发生,但我知道我只是想子模块被重置到他们最近的远程提交,并做好了。 这涉及到在这里结合几个不同问题的答案:

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

资料来源:

我该如何恢复对git子模块的更改?

简单的方法拉最新的所有git submodules