目录转换为子模块后合并

MvG*_*MvG 15 git version-control merge git-merge git-submodules

我发现使用git子模块时,我经常遇到在包含给定子模块的提交和代表与普通目录相同的代码的提交之间合并的问题.小型复制示例:

# 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^
Run Code Online (Sandbox Code Playgroud)

这已经给出了一个错误:

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
Run Code Online (Sandbox Code Playgroud)

为了避免错误,我首先取消初始化所有子模块:

# 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
Run Code Online (Sandbox Code Playgroud)

如您所见,功能分支与子模块完全无关,修改了不同的文件集.这使整个问题特别烦人.

# Try to merge the feature branch
git checkout master
git merge branch
Run Code Online (Sandbox Code Playgroud)

这再次失败,错误消息我不完全理解:

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.
Run Code Online (Sandbox Code Playgroud)

如果我在git submodule update --init之前做了一个,我会得到同样的错误git merge branch.我a~HEAD在目录树和输出中都没有看到任何地方git status,其内容如下:

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
Run Code Online (Sandbox Code Playgroud)

如果我git add a按照建议行事,我会收到另一个错误:

error: unable to index file a
fatal: updating files failed
Run Code Online (Sandbox Code Playgroud)

如果我git submodules update --init在合并之前做,那么我可以git add a成功.但是如果我忘记这样做,然后在合并后尝试这样做,我会收到以下错误消息:

Submodule 'a' (…/a) registered for path 'a'
Skipping unmerged submodule a
Run Code Online (Sandbox Code Playgroud)

我该如何从这种情况中恢复过来?除了以外的东西git merge --abort,因为我也想把它用于类似的事情git rebase,因为在某些情况下(不知道如何重现)我甚至不能完全中止合并,而是不得不做一个硬重置.

我怎么能首先避免它?是否有一些神奇的设置使git在合并期间使用子模块与目录做正确的事情,这样我就不必手动后处理只修改与子模块无关的文件的合并?

max*_*630 4

不,你不应该添加 a,合并不应该改变它。你应该运行的是

git reset a
Run Code Online (Sandbox Code Playgroud)

所以你忽略了a的“chage”。

PS:显然 git 只是检查目录的存在,所以如果你

git submodule deinit a
rmdir a
Run Code Online (Sandbox Code Playgroud)

合并之前,就会成功。不确定这是否是您想要的。