目录之后的合并转变为子模块 [英] Merging after directory got turned into submodule
问题描述
我发现使用git子模块时,经常会遇到问题合并,这些提交包含给定的子模块和代表与普通目录相同代码的提交。小型复制示例:
#创建一个项目,稍后用作$ b的子项目$ b git init a
cd a
echo aaa> aa
git add -A
git commit -m a1
cd ..
#创建第二个项目,其中包含最初的常规目录
git init b
cd b
mkdir ab
echo aaa> a / aa
echo bbb> b / bb
git add -A
git commit -m b1
#将子目录替换为子模块
git rm -ra
git submodule add .. / aa
git commit -m b2
#尝试从事务子模块状态创建分支
git checkout -b分支HEAD ^
这已经给出了一个错误:
错误:以下未跟踪的工作树文件将被checkout覆盖:
a / aa
请在移动或删除它们,然后才能切换分支。
中止
为了避免这个错误,我首先取消初始化所有子模块:
#创建feature版本,不带子模块
git submodule deinit。
git checkout -b分支HEAD ^
echo abc> b / bb
git commit -a -m b3
如您所见,分支与子模块完全无关,修改了一组不同的文件。这使得整个问题特别恼人。
#尝试合并功能分支
git checkout master
git合并分支
再次失败,错误信息I don' t完全理解:
CONFLICT(文件/目录):有一个名为a的目录科。添加一个〜HEAD
自动合并失败;修复冲突,然后提交结果。
如果我做了一个 git submodule update --init 在
git合并分支
之前。我在任何地方都看不到任何 a〜HEAD
,无论是在我的目录树还是从 git status
的输出中,它的内容如下:
分支主
您有未合并的路径。
(修复冲突并运行git commit)
要提交的更改:
修改:b / bb
未合并路径:
(使用git add< file> ...来标记分辨率)
由我们添加:a
如果我按照建议 git添加一个
,我会得到另一个错误:
错误:无法索引文件
致命:更新文件失败
如果我在合并之前执行 git submodules update --init
,那么我可以执行 git成功添加一个
。但是,如果我忘记这样做,然后在合并后尝试这样做,我收到以下错误消息:
子模块'a'(... / a)为路径'a'注册
跳过未组装的子模块a
我如何从这种情况中恢复过来除了 git merge --abort
以外的东西,因为我想使用它也适用于类似于 git rebase
的情况,并且由于在某些情况下(不知道如何重现),我甚至无法干净地中止合并,只好做而不是重置。
我怎样才能避免它呢?是否有一些魔术设置让git在合并期间对子目录与目录做了正确的事情,这样我就不必手动后处理合并,只会修改与子模块无关的文件了?
$ b $不,你不应该添加一个,合并不应该改变它。你应该运行的是 git reset a
所以你忽略了一个chage。
PS:显然git只是检查existense的目录,所以如果你
git submodule deinit a
rmdir a
合并之前,它会成功。不知道这是你想要的。
I find that working with git submodules, I often encounter problems merging between commits which do contain a given submodules and those which represent the same code as a normal directory. Small reproducing example:
# Create one project, to be used as a subproject later on
git init a
cd a
echo aaa > aa
git add -A
git commit -m a1
cd ..
# Create a second project, containing a as a normal directory initially
git init b
cd b
mkdir a b
echo aaa > a/aa
echo bbb > b/bb
git add -A
git commit -m b1
# Replace directory with submodule
git rm -r a
git submodule add ../a a
git commit -m b2
# Try to create branch from the pre-submodule state of affairs
git checkout -b branch HEAD^
This already gives an error:
error: The following untracked working tree files would be overwritten by checkout:
a/aa
Please move or remove them before you can switch branches.
Aborting
In order to avoid the error, I deinitialize all submodules first:
# Create feature brach starting at version without submodule
git submodule deinit .
git checkout -b branch HEAD^
echo abc > b/bb
git commit -a -m b3
As you can see, the feature branch is completely unrelated to the submodule, modifying a different set of files. Which makes this whole problem particularly annoying.
# Try to merge the feature branch
git checkout master
git merge branch
This fails again, with an error message I don't fully understand:
CONFLICT (file/directory): There is a directory with name a in branch. Adding a as a~HEAD
Automatic merge failed; fix conflicts and then commit the result.
I get the same error if I do a git submodule update --init
before the git merge branch
. I don't see any a~HEAD
anywhere, neither in my directory tree nor in the output from git status
, which reads like this:
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Changes to be committed:
modified: b/bb
Unmerged paths:
(use "git add <file>..." to mark resolution)
added by us: a
If I do git add a
as suggested, I get another error:
error: unable to index file a
fatal: updating files failed
If I do git submodules update --init
just before the merge, then I can do git add a
successfully. But if I forget to do so, and then try doing that after the merge, I receive this error message:
Submodule 'a' (…/a) registered for path 'a'
Skipping unmerged submodule a
How do I recover from this situation? Something other than git merge --abort
, since I'd like to use it for things like git rebase
as well, and since in some scenarios (don't know how to reproduce) I couldn't even abort the merge cleanly, and had to do a hard reset instead.
How can I avoid it in the first place? Is there some magic setting which makes git do the right thing with submodules vs. directories during merges, so that I don't have to manually post-process a merge which only modifies files unrelated to the submodules?
No you should not add a, the merge is not supposed to change it. What you should run is
git reset a
So you ignore the "chage" for a.
PS: apparently git merely checks existense of a directory, so if you
git submodule deinit a
rmdir a
before merging, it will succeed. Not sure if this is what you want.
这篇关于目录之后的合并转变为子模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!