我刚刚运行了一个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
这是什么意思?我该如何解决?
答案 0 :(得分:240)
如Mark Longair的博客文章Git Submodules Explained中所述,
版本1.7.0及更高版本的git在git子模块的行为中包含annoying change。
如果子模块有任何已修改的文件或未跟踪的文件,则现在认为它们是脏的,而之前只有在子模块中的HEAD指向错误的提交时才会出现这种情况。git子模块输出中加号(
+
)的含义已经改变,第一次遇到这个问题需要花一点时间来弄清楚出了什么问题,例如通过查找通过更改日志或在git.git上使用git bisect来查找更改。对于用户来说,为“在指定的版本中引入不同的符号,但是很脏”会更加友好。
你可以通过以下方式修复它:
提交或撤消每个子模块中的更改/演变,然后再返回到父repo(diff不再报告“脏”文件)。要将cd
子模块的所有更改撤消到子模块的根目录中并执行git checkout .
dotnetCarpenter comments您可以执行以下操作:git submodule foreach --recursive git checkout .
或将--ignore-submodules
添加到git diff
,暂时忽略这些“脏”子模块。
作为Noam comments below,this question提到,自git版本1.7.2起,您可以忽略脏子模块:
git status --ignore-submodules=dirty
答案 1 :(得分:18)
同样删除子模块,然后运行git submodule init
和git submodule update
显然可以解决问题,但可能并不总是合适或可能。
答案 2 :(得分:14)
编辑:这个答案(以及大多数其他答案)已经过时;见Devpool's answer instead。
最初,没有配置选项来制作" git diff --ignore-submodules"和" git status --ignore-submodules"全局默认值(但另见Setting git default flags on commands)。另一种方法是在ignore
文件中为git diff
和git status
设置要忽略的每个子模块的默认.git/config
配置选项(仅限本地) )或.gitmodules
(将由git版本化)。例如:
[submodule "foobar"]
url = git@bitbucket.org:foo/bar.git
ignore = untracked
ignore = untracked
忽略未跟踪的文件,ignore = dirty
也忽略已修改的文件,ignore = all
忽略也提交。
显然没有办法为所有子模块添加通配符。
答案 3 :(得分:13)
这种情况是因为您对子模块的指针不是子模块目录中的实际指针。要解决此问题,您必须再次运行git submodule update
:
答案 4 :(得分:8)
git submodule foreach --recursive git checkout .
这对我来说不起作用,但是它给了我一个文件列表(在我的情况下只有一个)在子模块中已被更改(没有我在那里做任何事情)。
所以我可以转到子模块,git状态显示我的HEAD被分离 - > git checkout master,git status再次查看修改后的文件,git checkout> filename<,git pull,一切都很好。
答案 5 :(得分:6)
我最终删除了子模块目录并再次初始化
cd my-submodule
git push
cd ../
rm -rf my-submodule
git submodule init
git submodule update
答案 6 :(得分:6)
要忽略任何子模块中的所有未跟踪文件,请使用以下命令忽略这些更改。
git config --global diff.ignoreSubmodules dirty
它将在本地git config中添加以下配置选项:
[diff]
ignoreSubmodules = dirty
可以找到更多信息here
答案 7 :(得分:5)
如果启用了filemode设置并且您更改了子模块子树中的文件权限,则子模块可能会被标记为脏。
要禁用子模块中的filemode,您可以编辑 / .git / modules / path / to / your / submodule / config 并添加
[core]
filemode = false
如果要忽略所有脏状态,可以在 / .gitmodules 文件中设置ignore = dirty
属性,但我认为最好只禁用filemode。
答案 8 :(得分:1)
您对您的存储库有足够的权限吗?
我的解决方案与 git
无关,但是我看到了相同的错误消息,以及子模块的 dirty 状态。
根本原因是 .git
文件夹中的某些文件归 root
所有,因此 git
没有写入权限,因此 git
无法更改 <以我的用户身份运行时子模块的 em>dirty 状态。
你有同样的问题吗?
从存储库的根文件夹中,使用 find
列出根拥有的文件 [可选]
find .git -user root
解决方案 [Linux]
将 .git
文件夹中的所有文件更改为您作为所有者
sudo chown -R $USER:$USER .git
# alternatively, only the files listed in the above command...
sudo find .git -user root -exec chown $USER:$USER {} +
这是怎么发生的?
就我而言,我在 docker 容器的子模块中构建了库,docker 守护进程传统上作为 root
运行,因此创建的文件属于 root:root
所有权。
我的用户通过该服务通过代理获得 root 权限,因此即使我没有 sudo
任何内容,我的 git 存储库仍然拥有 root
拥有的更改。
我希望这对某人有所帮助,请移步这里。
答案 9 :(得分:0)
在我的情况下,我不确定导致这种情况发生的原因,但我知道我只是想将子模块重置为最新的远程提交并完成它。这包括在这里结合几个不同问题的答案:
git submodule update --recursive --remote --init
来源: