将Git子模块转换为子树后合并错误 [英] Merge error after converting Git submodule to subtree

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

问题描述

我有一个项目,我最初使用一些从属代码的子模块。事实证明,子模块并不适合这个项目(并且它们在实践中很难使用),所以我将每个子模块转换为子树(使用新的 git-subtree

在我的工作存储库中,我已成功删除每个子模块,并将旧子模块回购作为子树添加。没有问题。



当我转到另一个克隆并尝试从第一个克隆中拉出时,我从合并步骤中收到以下错误:

  error:以下未跟踪的工作树文件将被合并覆盖:
sub / .gitignore
sub / Makefile
$ / b $ b $ /
$ /
$ /
$ /
$ /
$ ... / pre>

看起来这是因为 sub / 中的文件从未真正存在于第一个主存储库中当Git应用修补程序更新 .gitmodules 时,它不会删除包含子模块文件的目录。当处理下一个提交时,其中Git试图创建 sub / 现在是主存储库的一部分的新文件,所有这些文件冲突还有 sub / 中仍然存在的文件。



我发现的解决方法是在 git pull <之前使用 rm -rf sub / code>,这可以避免这个问题。



我的问题是,是否有任何命令行开关可用于 git merge 表示覆盖刚好存在于工作目录中的任何文件?更妙的是, git merge 会查看现有文件的内容,如果内容与它要创建的文件完全相同,则可以禁止错误消息并继续。



更新:我已经创建了Git存储库来演示此问题,以准确显示我在说什么。重现:

  $ git clone https://github.com/ghewgill/q14224966.git 
$ cd q14224966
$ git submodule init
$ git submodule update
$ git merge origin / branch

这应该导致错误消息:

 错误:以下未跟踪的工作树文件将被合并覆盖: 
sub / Makefile
sub / README
sub / src / main.c
请在合并前移动或移除它们。
正在取消


解决方案

合并,但我有合并git子模块类似的问题。我认为这个解决方案可以解决你的问题,即使它不直接解决合并问题。



我发现通过强行检出想要合并的分支,然后回到主模块,所有的子模块都可以运行。



让你的例子能够运行:

  $ git clone https://github.com/ghewgill/q14224966.git 
$ cd q14224966
$ git submodule init
$ git submodule update
$ git checkout -f origin / branch
$ git checkout master
$ git merge origin / branch

这是可行的,因为它基本上为你做 rm -rf 步骤。当然,这有点迂回,如果你只有一个子模块就像你的例子那样,也许不值得。但是我发现在一个有许多子模块的项目中工作时,这是一个非常节省的时间。

另外,正如在评论中指出的那样,如果您想避免对工作树进行更改,您可以使用以下命令:

  $ git clone https://github.com/ghewgill/q14224966.git 
$ cd q14224966
$ git submodule init
$ git submodule update
$ git reset origin / branch
$ git reset --hard master

它的工作方式大致相同,但避免检查过程中的其他文件。我没有机会在野外使用它,但它似乎是一个合理的方法。

还有 $ git合并-s子树起源/分支。它适用于你的例子,但是当涉及多个子模块时,它会产生意想不到的结果。不过,你可能会有更好的运气。

I have a project where I was originally using submodules for some dependent code. It turns out that submodules are not really appropriate for this project (and they are hard to use in practice), so I am converting each submodule to a subtree (using the new git-subtree feature).

In my working repository, I have successfully removed each submodule and have added the old submodule repo as a subtree. No problem with this.

When I go to another clone and attempt to pull from the first one, I get the following error from the merge step:

error: The following untracked working tree files would be overwritten by merge:
        sub/.gitignore
        sub/Makefile
        sub/README
        sub/src/main.c
        ... and so on for all files in sub/
Aborting

It seems that this is because the files in sub/ never really existed in the main repository in the first place, and when Git applies the patch to update .gitmodules it doesn't remove the directory with the submodule files. When processing the next commit, where Git tries to create the new files in sub/ that are now part of the main repository, all those files conflict with the still-existing files in sub/.

The workaround I have found is to use rm -rf sub before git pull, which avoids this problem.

My question is, is there any command line switch I can use with git merge that says "Overwrite any files that happen to exist in the working directory"? Even better would be a feature where git merge would look at the contents of the existing file, and if the contents are identical to the file it was going to create anyway, suppress the error message and continue.

UPDATE: I have created Git repositories that demonstrate this problem, to show exactly what I'm talking about. To reproduce:

$ git clone https://github.com/ghewgill/q14224966.git
$ cd q14224966
$ git submodule init
$ git submodule update
$ git merge origin/branch

This should result in the error message

error: The following untracked working tree files would be overwritten by merge:
    sub/Makefile
    sub/README
    sub/src/main.c
Please move or remove them before you can merge.
Aborting

解决方案

I know your question was specific to merge, but I've had similar problems with merging git submodules. I think this solution will work with your problem, even if it's not directly addressing the merge question.

I've found that by forcibly checking out the branch you want to merge, then going back to master, everything works out with submodules.

To get things working in your example:

$ git clone https://github.com/ghewgill/q14224966.git
$ cd q14224966
$ git submodule init
$ git submodule update
$ git checkout -f origin/branch
$ git checkout master
$ git merge origin/branch

This works because it's basically doing your rm -rf step for you. Granted, this is a bit roundabout, and maybe not worth doing if you only have the one submodule like your example does. But I've found it to be quite the timesaver when working in a project with many submodules.

Also, as has been pointed out in the comments, if you want to avoid making changes to the work tree, you can use this:

$ git clone https://github.com/ghewgill/q14224966.git
$ cd q14224966
$ git submodule init
$ git submodule update
$ git reset origin/branch
$ git reset --hard master

This works in roughly the same way, but avoids checking out other files in the process. I haven't had a chance to use this in the wild, but it seems like a sound method.

There's also $ git merge -s subtree origin/branch. It works with your example, but I've had unexpected results with it when more than one submodule is involved. You might have better luck, though.

这篇关于将Git子模块转换为子树后合并错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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