目录之后的合并转变为子模块 [英] Merging after directory got turned into submodule

查看:220
本文介绍了目录之后的合并转变为子模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆