我有一个项目,我最初使用子模块来处理某些相关代码。事实证明,子模块并不适合这个项目(并且它们在实践中很难使用),因此我将每个子模块转换为子树(使用新的git-subtree
功能)。
在我的工作存储库中,我已经成功删除了每个子模块,并将旧的子模块存储库添加为子树。没问题。
当我转到另一个克隆并尝试从第一个克隆拉出时,我从合并步骤中收到以下错误:
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
这似乎是因为sub/
中的文件从未真正存在于主存储库中,当Git应用补丁更新.gitmodules
时,它不会删除目录子模块文件。处理下一次提交时,Git尝试在sub/
中创建新文件, 现在是主存储库的一部分,所有这些文件都与{{1}中仍然存在的文件冲突}}。
我找到的解决方法是在sub/
之前使用rm -rf sub
,这可以避免此问题。
我的问题是,是否有任何命令行开关我可以使用git pull
说“覆盖工作目录中恰好存在的任何文件”?更好的是git merge
查看现有文件内容的功能,如果内容与它要创建的文件完全相同,则禁止显示错误消息并继续。
更新:我已经创建了演示此问题的Git存储库,以准确显示我正在谈论的内容。重现:
git merge
这会导致错误消息
$ git clone https://github.com/ghewgill/q14224966.git
$ cd q14224966
$ git submodule init
$ git submodule update
$ git merge origin/branch
答案 0 :(得分:9)
我知道您的问题特定于合并,但我在合并git子模块时遇到了类似的问题。我认为这个解决方案可以解决您的问题,即使它没有直接解决合并问题。
我发现通过强行检查你要合并的分支,然后回到master,一切都与子模块一致。
为了让你的例子更有效:
$ 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 merge -s subtree origin/branch
。它适用于您的示例,但是当涉及多个子模块时,我有意外的结果。不过,你可能会有更好的运气。
答案 1 :(得分:1)
你不能得到git-merge
(或任何其他命令)强制破坏它认为不知道的文件,不。 git非常努力地不做任何事情完全不可逆转。
但是对于许多子模块,可以使用git submodule foreach
使您的删除更容易,更安全:
$ git submodule foreach 'rm -rf $toplevel/$path'
Entering 'sub'
$ git merge origin/branch
Updating a231acd..6b4d2f4
Fast-forward
...
答案 2 :(得分:1)
(警告:我从未使用过子树,我不知道你的实际回购是多么复杂,所以这些解决方案可能实际上并不适合你。)
从你的样本回购开始,我发现两个似乎都有效的解决方案,虽然它们产生不同的提交树:
使用git merge -s resolve origin/branch
~/q14224966[master]> git reset --hard origin/master
HEAD is now at a231acd add submodule
~/q14224966[master]> touch other.c && git add . && git commit -m "New commit."
[master bc771ac] New commit.
0 files changed
create mode 100644 other.c
~/q14224966[master]> git merge -s resolve origin/branch
Trying really trivial in-index merge...
error: Merge requires file-level merging
Nope.
Trying simple merge.
Simple merge failed, trying Automatic merge.
Adding sub/Makefile
Adding sub/README
Adding sub/src/main.c
Merge made by the 'resolve' strategy.
.gitmodules | 3 ---
sub | 1 -
sub/Makefile | 1 +
sub/README | 1 +
sub/src/main.c | 1 +
5 files changed, 3 insertions(+), 4 deletions(-)
delete mode 160000 sub
create mode 100644 sub/Makefile
create mode 100644 sub/README
create mode 100644 sub/src/main.c
~/q14224966[master]> ls
README main.c other.c sub/
~/q14224966[master]> cd sub/
~/q14224966/sub[master]> ls
Makefile README src/
~/q14224966/sub[master]> git status
# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.
#
nothing to commit (working directory clean)
~/q14224966/sub[master]> cd ..
~/q14224966[master]> git status
# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.
#
nothing to commit (working directory clean)
以下是生成的提交树:
使用rebase而不是合并:
~/q14224966[master]> git reset --hard origin/master
HEAD is now at a231acd add submodule
~/q14224966[master]> touch other.c && git add . && git commit -m "New commit."
[master ae66060] New commit.
0 files changed
create mode 100644 other.c
~/q14224966[master]> git rebase origin/branch
First, rewinding head to replay your work on top of it...
Applying: New commit.
~/q14224966[master]> ls
README main.c other.c sub/
~/q14224966[master]> cd sub/
~/q14224966/sub[master]> ls
Makefile README src/
~/q14224966/sub[master]> git status
# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.
#
nothing to commit (working directory clean)
~/q14224966/sub[master]> cd ..
~/q14224966[master]> git status
# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.
#
nothing to commit (working directory clean)
以下是生成的提交树:
答案 3 :(得分:0)
尝试了
git fetch --all
git reset --hard origin / master
但它不起作用。
您可以使用“我们的”合并策略:
git merge -s our our-master
您也可以使用git-stash保存更改,然后使用git-stash来恢复它们。