更新Q2 2018和Git 2.18:
使用"git mv
"移动一个包含子模块的子模块时,忘记对嵌套的子子模块进行必要的调整;
现在代码路径已经学会递归进入子模块。
请查看由Jonathan Tan (jhowtan
)于2018年3月28日提交的提交 6856077。
请查看由Stefan Beller (stefanbeller
)于2018年3月28日提交的提交 da62f78, 提交 0c89fdd, 提交 3b8fb39, 提交 f793b89, 提交 61aad92。
(已合并至提交 0c7ecb7,作者为Junio C Hamano -- gitster
--,发布日期为2018年5月8日)
子模块:移动子模块后修复嵌套的子模块
由于子模块本身可以有嵌套的子模块,因此我们希望在需要时修复嵌套的子模块。添加一个选项以递归进入嵌套的子模块并连接它们。
由于子模块是通过其名称(确定其与超级项目的git目录相关联)在内部标识的,并且通过超级项目的工作树中的路径进行标识,因此我们需要确保名称<->路径
映射保持完整。我们可以通过先编写.gitmodules
文件,然后强制重新加载子模块配置机制来在git-mv
命令中实现这一点。
2017年第四季度更新:
最新的Git 2.14.x/2.15 (2017年第四季度)文档记录了该漏洞
请参见提交记录c514167 (2017年9月15日) by Heiko Voigt (hvoigt
)。
(由Junio C Hamano -- gitster
--于2017年9月25日合并至提交记录450b908)
当使用
git-mv
命令移动子模块时,它会检测到并更新相关配置文件(
.gitmodules
、工作树和 gitfile)的路径。
但对于递归子模块,在用户重命名根子模块时,此方法无效。
原始答案 2015
我刚刚在 Windows 上使用 git 2.6.0 进行了测试,移动包含嵌套子模块的子模块似乎存在问题:
C:\Users\vonc\prog\git\tests\submove>git clone --recursive a a1
Cloning into 'a1'...
done.
Submodule '2015/b' (C:/Users/vonc/prog/git/tests/submove/b) registered for path '2015/b'
Submodule 'c' (C:/Users/vonc/prog/git/tests/submove/c) registered for path 'c'
Cloning into '2015/b'...
done.
Submodule path '2015/b': checked out 'dc18955ec7b9ad0c04245968e2474646e4d593b2'
Cloning into 'c'...
done.
Submodule path 'c': checked out 'fb4722eaca17ac171b7a2c8c5a1ac1e697f0ee85'
Submodule 'd' (C:/Users/vonc/prog/git/tests/submove/d) registered for path 'd'
Cloning into 'd'...
done.
Submodule path 'c/d': checked out '73cd7b8ff82519720b2fcca18df5ed00dd618b71'
我有:
a1
c
d
2015
b
如果我尝试将子模块c移动到2015子文件夹中:
C:\Users\vonc\prog\git\tests\submove\a1>git mv c 2015/c
C:\Users\vonc\prog\git\tests\submove\a1>git status
fatal: Not a git repository: d/../../.git/modules/c/modules/d
fatal: 'git status --porcelain' failed in submodule 2015/c
我发现我需要在嵌套模块
d
中修改两个东西:
1/ 手动修改 .git/modules/c/modules/d/config
以注入正确的路径:
git config -f .git/modules/c/modules/d/config core.worktree ../../../../../2015/c/d
^^^^
2/ 修改 d
工作树:
git config -f .git/modules/c/modules/d/config core.worktree ../../../../../2015/c/d
从那里开始,git status
可以工作,但我喜欢(确保)添加一个 git submodule sync --recursive
:
C:\Users\vonc\prog\git\tests\submove\a1>git submodule sync --recursive
Synchronizing submodule url for '2015/b'
Synchronizing submodule url for '2015/c'
Synchronizing submodule url for '2015/c/d'
git status
显示了预期的结果:
C:\Users\vonc\prog\git\tests\submove\a1>git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: .gitmodules
renamed: c -> 2015/c
我添加并提交了那个更改:
C:\Users\vonc\prog\git\tests\submove\a1>git add .
C:\Users\vonc\prog\git\tests\submove\a1>git commit -m "move sub c in 2015/c"
[master 8289632] move sub c in 2015/c
2 files changed, 1 insertion(+), 1 deletion(-)
rename c => 2015/c (100%)
C:\Users\vonc\prog\git\tests\submove\a1>gl
* 8289632 - (HEAD -> master) move sub c in 2015/c (3 seconds ago) <VonC>
* 7ebb8e0 - (origin/master, origin/HEAD) a with sub c (38 minutes ago) <VonC>
我现在克隆该仓库以检查移动是否被正确注册:
C:\Users\vonc\prog\git\tests\submove>git clone --recursive a1 a2
Cloning into 'a2'...
done.
Submodule '2015/b' (C:/Users/vonc/prog/git/tests/submove/b) registered for path '2015/b'
Submodule 'c' (C:/Users/vonc/prog/git/tests/submove/c) registered for path '2015/c'
Cloning into '2015/b'...
done.
Submodule path '2015/b': checked out 'dc18955ec7b9ad0c04245968e2474646e4d593b2'
Cloning into '2015/c'...
done.
Submodule path '2015/c': checked out 'fb4722eaca17ac171b7a2c8c5a1ac1e697f0ee85'
Submodule 'd' (C:/Users/vonc/prog/git/tests/submove/d) registered for path 'd'
Cloning into 'd'...
done.
Submodule path '2015/c/d': checked out '73cd7b8ff82519720b2fcca18df5ed00dd618b71'
正如您所看到的,
c
和
c/d
位于预期的
2015/
子文件夹中:
C:\Users\vonc\prog\git\tests\submove>cd a2
C:\Users\vonc\prog\git\tests\submove\a2>dir 2015\c
Directory of C:\Users\vonc\prog\git\tests\submove\a2\2015\c
03/10/2015 18:10 <DIR> .
03/10/2015 18:10 <DIR> ..
03/10/2015 18:10 29 .git
03/10/2015 18:10 40 .gitmodules
03/10/2015 18:10 <DIR> d
2 File(s) 69 bytes
3 Dir(s) 23 656 910 848 bytes free
C:\Users\vonc\prog\git\tests\submove\a2>dir 2015\c\d
Directory of C:\Users\vonc\prog\git\tests\submove\a2\2015\c\d
03/10/2015 18:10 <DIR> .
03/10/2015 18:10 <DIR> ..
03/10/2015 18:10 42 .git
03/10/2015 18:10 3 d.txt
2 File(s) 45 bytes
2 Dir(s) 23 656 910 848 bytes free
git mv
的一个错误。 - VonC