将 git 子模块移动到另一个目录后,它失败并显示错误 'git status --porcelain' failed in submodule
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20991138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
After moving git submodule to another directory it fails with error 'git status --porcelain' failed in submodule
提问by jaccus
Initially I had the following (simplified) repo structure:
最初我有以下(简化的)repo 结构:
MyRepo
external1/MySub (git submodule)
.gitsubmodules
Where
在哪里
$ cat .gitsubmodules
[submodule "external1/MySub"]
path = external1/MySub
url = user@repo:/remoterepo/externals/MySub.git
I then wanted to move MySubmodule to another directory in the same git repository, e.g., external2so the structure is as follows:
然后我想将 MySubmodule 移动到同一个 git 存储库中的另一个目录,例如external2所以结构如下:
MyRepo
external2/MySub (git submodule)
.gitsubmodules
What I did, and thought is enough, I simply moved (via OS mv
) the external1/MySubdirectory to external2/MySuband edited the .gitsubmodulesfile to:
我所做的,并且认为已经足够了,我只是将(通过 OS mv
)external1/MySub目录移动到external2/MySub并将.gitsubmodules文件编辑为:
$ cat .gitsubmodules
[submodule "external2/MySub"]
path = external2/MySub
url = user@repo:/remoterepo/externals/MySub.git
After this change, I get the following error:
进行此更改后,我收到以下错误:
$ git status
fatal: Could not chdir to '../../../../../repo/external/MySub': No such file or directory
fatal: 'git status --porcelain' failed in submodule repo/external2/MySub
What am I missing? Any other changes need to be done for such move to work?
我错过了什么?是否需要进行任何其他更改才能使此类移动生效?
(I'm using git version 1.8.3rc3 on Windows 8.1)
(我在 Windows 8.1 上使用 git 版本 1.8.3rc3)
回答by VonC
I simply moved the external1/MySub directory to external2/MySub
我只是将 external1/MySub 目录移动到 external2/MySub
Move as in mv
(unix command), or git mv
(git command)?
在mv
(unix 命令)或git mv
(git 命令)中移动?
You need to move the special entryof the indexrepresenting the submodule for the parent repo.
Normally, (reading git mv
), this should have been enough:
通常,(阅读git mv
),这应该已经足够了:
git mv external1/MySub external2/MySub
Moving a submodule using a gitfile (which means they were cloned with a Git version 1.7.8 or newer) will update the
gitfile
andcore.worktree
setting to make the submodule work in the new location.
It also will attempt to update thesubmodule.<name>.path
setting in thegitmodules
file and stage that file (unless -n is used).
使用 gitfile 移动子模块(这意味着它们是使用 Git 版本 1.7.8 或更高版本克隆的)将更新
gitfile
和core.worktree
设置以使子模块在新位置工作。
它还将尝试更新文件中的submodule.<name>.path
设置gitmodules
并暂存该文件(除非使用 -n)。
That works best with the latest 1.8.5 git (like msysgit for Windows, or latest package for Unix)
这最适合最新的 1.8.5 git(如Windows 的 msysgit或Unix 的最新包)
If you get message
如果你收到消息
fatal: renaming '%submodule%' failed: No such file or directory
it is probably because you're adding a directory level, e.g. moving submodule "
math
" to "libs/math
".git mv
doesn't create missing [intermediate] directories, you shouldmkdir
them yourself.
这可能是因为您正在添加目录级别,例如将子模块“
math
”移动到“libs/math
”。git mv
不会创建丢失的 [中间] 目录,您应该mkdir
自己创建。
git 2.9 (June 2016) will improve git mv
for submodule:
git 2.9(2016 年 6 月)将改进git mv
子模块:
See commit a127331(19 Apr 2016) by Stefan Beller (stefanbeller
).
(Merged by Junio C Hamano -- gitster
--in commit 9cb50a3, 29 Apr 2016)
请参阅Stefan Beller ( ) 的提交 a127331(2016 年 4 月 19 日)。(由Junio C Hamano合并-- --在提交 9cb50a3,2016 年 4 月 29 日)stefanbeller
gitster
mv
: allow moving nested submodules"
git mv old new
" did not adjust the path for a submodule that lives as a subdirectory insideold/
directory correctly.submodules however need to update their link to the git directory as well as updates to the
.gitmodules
file.
mv
: 允许移动嵌套的子模块"
git mv old new
" 没有正确调整作为目录内子目录存在的子模块的路径old/
。然而,子模块需要更新它们到 git 目录的链接以及对
.gitmodules
文件的更新。
Git 2.12 (Q1 2017) offers to move nested submodules to the parent repo:
Git 2.12(2017 年第一季度)提供了将嵌套子模块移动到父存储库的功能:
There is a new submodule helper "git submodule absorbgitdirs
" to make it easier to move embedded .git/
directory for submodules in a
superproject to .git/modules/
(and point the latter with the former
that is turned into a "gitdir:
" file) has been added.
添加了一个新的子模块助手“ git submodule absorbgitdirs
”,可以更轻松地将.git/
超级项目中的子模块的嵌入目录移动到.git/modules/
(并将后者指向变成“ gitdir:
”文件的前者)。
See commit 7c4be45(27 Dec 2016), commit f6f8586, commit 47e83eb, commit 1a248cf(12 Dec 2016), and commit 6f94351, commit 89c8626, commit 90c0011, commit 6f94351, commit 89c8626, commit 90c0011(08 Dec 2016) by Stefan Beller (stefanbeller
).
(Merged by Junio C Hamano -- gitster
--in commit da2b74e, 10 Jan 2017)
见提交7c4be45(2016年12月27日),提交f6f8586,提交47e83eb,提交1a248cf(2016年12月12日),以及提交6f94351,提交89c8626,提交90c0011,提交6f94351,提交89c8626,提交90c0011(2016年12月8日)由斯蒂芬贝勒(stefanbeller
)。
(由Junio C gitster
Hamano合并-- --在da2b74e 提交中,2017 年 1 月 10 日)
submodule: add
absorb-git-dir
functionWhen a submodule has its
git
dir inside the working dir, the submodule support for checkout that we plan to add in a later patch will fail.Add functionality to migrate the git directory to be absorbed into the superprojects git directory.
The newly added code in this patch is structured such that other areas of Git can also make use of it. The code in the submodule--helper is a mere wrapper and option parser for the function
absorb_git_dir_into_superproject
, that takes care of embedding the submodules git directory into the superprojects git dir. That function makes use of the more abstract function for this use caserelocate_gitdir
, which can be used by e.g. the worktree code eventually to move around a git directory.
子模块:添加
absorb-git-dir
功能当子模块的
git
目录位于工作目录中时,我们计划在以后的补丁中添加的对检出的子模块支持将失败。添加将 git 目录迁移到 superprojects git 目录中的功能。
此补丁中新添加的代码的结构使得 Git 的其他区域也可以使用它。子模块中的代码--helper 只是函数的
absorb_git_dir_into_superproject
包装器和选项解析器,负责将子模块 git 目录嵌入到超级项目 git 目录中。该函数为此用例relocate_gitdir
使用了更抽象的函数, 例如工作树代码最终可以使用它来移动 git 目录。
Note: there is still (Git 2.14.x/2.15, Q4 2017) a bug linked to submodule moving: see "Git: moving submodules recursively (nested submodules)".
注意:仍然存在(Git 2.14.x/2.15,2017 年第四季度)一个与子模块移动相关的错误:请参阅“ Git:递归移动子模块(嵌套子模块)”。
Git 2.15.x/2.16 (Q1 2018) will make moving submodule more robust, since "git fetch --recurse-submodules
" now knows that submodules can be
moved around in the superproject in addition to getting updated,
and finds the ones that need to be fetched accordingly.
Git 2.15.x/2.16(2018 年第一季度)将使移动子模块更加健壮,因为“ git fetch --recurse-submodules
”现在知道除了更新之外还可以在超级项目中移动子模块,并相应地找到需要获取的子模块。
See commit 4b4aced, commit c68f837(16 Oct 2017), and commit 01ce122(06 Oct 2017) by Heiko Voigt (hvoigt
).
(Merged by Junio C Hamano -- gitster
--in commit b4d658b, 06 Nov 2017)
请参阅Heiko Voigt ( ) 的commit 4b4aced、commit c68f837(2017 年 10 月 16 日)和commit 01ce122(2017 年 10 月 6 日)。(由Junio C Hamano合并-- --在提交 b4d658b 中,2017 年 11 月 6 日)hvoigt
gitster
implement fetching of moved submodules
We store the changed submodules paths to calculate which submodule needs fetching. This does not work for moved submodules since their paths do not stay the same in case of a moved submodules.
In case of new submodules we do not have a path in the current checkout, since they just appeared in this fetch.It is more general to collect the submodule names for changes instead of their paths to include the above cases. If we do not have a configuration for a gitlink we rely on constructing a default name from the path if a git repository can be found at its path. We skip non-configured gitlinks whose default name collides with a configured one.
实现获取移动的子模块
我们存储更改的子模块路径以计算需要获取哪个子模块。这不适用于移动的子模块,因为在移动子模块的情况下,它们的路径不会保持不变。
对于新的子模块,我们在当前结帐中没有路径,因为它们只是出现在此提取中。更普遍的是收集子模块名称以进行更改而不是包含上述情况的路径。如果我们没有 gitlink 的配置,如果可以在其路径中找到 git 存储库,我们将依赖于从路径构造默认名称。我们跳过默认名称与已配置名称冲突的未配置 gitlink。
Note that, beforeGit 2.19 (Q3 2018), the code to try seeing if a fetch is necessary in a submodule during a fetch with --recurse-submodules
got confused when the path to the submodule was changed in the range of commits in the
superproject, sometimes showing "(null)
".
This has been corrected.
请注意,在Git 2.19(2018 年第 3 季度)之前,--recurse-submodules
当在超级项目的提交范围内更改子模块的路径时,尝试查看在获取期间是否需要在子模块中进行获取的代码会感到困惑,有时会显示“ (null)
”。
这已得到纠正。
See commit c3749f6, commit 5fc8475(14 Jun 2018) by Stefan Beller (stefanbeller
).
(Merged by Junio C Hamano -- gitster
--in commit 085d2ab, 28 Jun 2018)
请参阅Stefan Beller ( ) 的commit c3749f6和commit 5fc8475(2018 年 6 月 14 日)。(由Junio C Hamano合并-- --在commit 085d2ab,2018 年 6 月 28 日)stefanbeller
gitster
submodule
: fixNULL
correctness in renamed broken submodulesWhen fetching with recursing into submodules, the fetch logic inspects the superproject which submodules actually need to be fetched.
This is tricky for submodules that were renamed in the fetched range of commits. This was implemented in c68f837(implement fetching of moved submodules, 2017-10-16, Git v2.16.0), and this patch fixes a mistake in the logic there.
submodule
:修复NULL
重命名的损坏子模块的正确性当以递归方式获取子模块时,获取逻辑会检查超级项目实际上需要获取哪些子模块。
对于在获取的提交范围内重命名的子模块,这很棘手。这是在c68f837中实现的(实现获取移动的子模块,2017-10-16,Git v2.16.0),这个补丁修复了那里的逻辑错误。
回答by jaccus
I changed a few more things manually and it actually worked with git 1.8.3rc3 (unnecessary with git 1.8.5):
我手动更改了一些东西,它实际上与 git 1.8.3rc3 一起工作(与 git 1.8.5 不需要):
Fix
gitdir
path in .git submodule filerepo/external2/MySub/.git
:-gitdir: ../../../.git/modules/external1/MySub +gitdir: ../../../.git/modules/external2/MySub
Rename submodule directory under
repo/.git/modules/
directory$ mv repo/.git/modules/external1 repo/.git/modules/external2
Fix
worktree
path inrepo/.git/modules/external2/MySub/config
-worktree = ../../../../../external1/MySub +worktree = ../../../../../external2/MySub
修复
gitdir
.git 子模块文件中的路径repo/external2/MySub/.git
:-gitdir: ../../../.git/modules/external1/MySub +gitdir: ../../../.git/modules/external2/MySub
重命名目录下的子模块
repo/.git/modules/
目录$ mv repo/.git/modules/external1 repo/.git/modules/external2
修复
worktree
路径repo/.git/modules/external2/MySub/config
-worktree = ../../../../../external1/MySub +worktree = ../../../../../external2/MySub