git发散重命名

pab*_*blo 13 git version-control

我想知道你如何在Git中处理这样的情况:

  • 从master创建分支task001
  • master:修改foo.c并将其重命名为bar.c
  • task001:修改foo.c并将其重命名为moo.c
  • 合并task001到master

Git告诉我的是:

CONFLICT (rename/rename): Rename "foo.c"->"bar.c" in branch "HEAD" rename "foo.c"->"moo.c" in "task001"
Automatic merge failed; fix conflicts and then commit the result.
Run Code Online (Sandbox Code Playgroud)

我该怎么解决?我的意思是,一旦名称冲突得到解决,我仍然希望合并这两个文件.

谢谢.

Mar*_*air 13

我最初理解你的问题意味着与你在评论中澄清的内容不同,但原始答案可能有用,所以我将其作为第一部分,但在下面添加一个替代方案:

1.只是解决冲突,所以你只有分歧的moo.c和bar.c

在这里,我假设你想要的结果是,bar.c并且moo.c在每个分支的变化中,在合并版本中.我会通过解决索引中的冲突和提交来解决这个问题.您描述的情况如下所示:

$ git log --pretty=oneline --graph --decorate master task001
* fce127471ab5d1ef55b1d16412a75a7129782517 (task001) Rename to a different file on task001
* 8edbc1357a3c0484dc077f6f7ce43de91d21e794 A small change on the task001 branch
| * d10e9020d147a4bbd3688744823380322bf37718 (HEAD, master) Rename on master to bar.c
| * f952617645456a551df07f219bfdc95e00c8ac9b Added a small change in master
|/  
* e8602eef46af744defd4fb4073ecdb6a7afbfd28 Initial version of foo.c
Run Code Online (Sandbox Code Playgroud)

如果我再合并task001到master,它产生的,你看到了同样的错误:

$ git merge task001 
CONFLICT (rename/rename): Rename "foo.c"->"bar.c" in branch "HEAD" rename "foo.c"->"moo.c" in "task001"
Automatic merge failed; fix conflicts and then commit the result.
Run Code Online (Sandbox Code Playgroud)

然后git status会告诉你问题的摘要:

$ git status
# On branch master
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   added by us:        bar.c
#   both deleted:       foo.c
#   added by them:      moo.c
#
no changes added to commit (use "git add" and/or "git commit -a")
Run Code Online (Sandbox Code Playgroud)

现在您只需要使用git add并git rm解决冲突:

$ git add bar.c
$ git rm --cached foo.c
foo.c: needs merge
moo.c: needs merge
rm 'foo.c'
$ git add moo.c
$ git status
# On branch master
# Changes to be committed:
#
#   new file:   moo.c
#
Run Code Online (Sandbox Code Playgroud)

(我用于--cached删除,foo.c因为它不再在工作副本中,并且--cached意味着命令只查看索引 - 否则会出现关于foo.c不存在的错误.)

然后你只需提交结果:

$ git commit
[ save the prepopulated commit message ]
Run Code Online (Sandbox Code Playgroud)

而且你已经解决了冲突并且已经bar.c和moo.c合并版本一起解决了.

(我顺便提一下,git merge -s resolve在这里描述的简单示例情况对我有用,但我希望这通常更有用.)

2.将bar.c和moo.c合并回一个文件

从您下面的评论中可以看出,您真正想要的是将这些文件再次合并为一个文件,并将两个分支中的文件更改合并.如果你想让git的合并策略来帮助你,那么每个分支上的文件在合并之前必须具有相同的路径,因此在合并之前你需要至少重命名其中一个.假设你想要调用合并文件,当然quux.c你也可以foo.c再次调用它.然后,您可以执行以下步骤,在合并之前重命名每个分支上的文件:

# Rename the file on master:

$ git checkout master
Already on 'master'
$ git mv bar.c quux.c
$ git commit -m "Rename bar.c to quux.c on branch master"
[master f9b3f49] Rename bar.c to quux.c on branch master
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename bar.c => quux.c (100%)

# Rename the file on task001:

$ git checkout task001 
Switched to branch 'task001'
$ git mv moo.c quux.c
$ git commit -m "Rename moo.c to quux.c as well on branch task001"
[task001 c71ad89] Rename moo.c to quux.c as well on branch task001
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename moo.c => quux.c (100%)

# Switch back to master, and merge in task001:

$ git checkout master
Switched to branch 'master'
$ git merge task001
Run Code Online (Sandbox Code Playgroud)

如果更改没有冲突,那么此时合并应该Just Work.在我尝试的例子中他们确实发生了冲突,所以我需要编辑文件,git add文件并提交结果:

Renaming foo.c->quux.c
Auto-merging quux.c
CONFLICT (content): merge conflict in quux.c
Automatic merge failed; fix conflicts and then commit the result.
$ emacs -nw quux.c 
$ git add quux.c
$ git commit
[master 8baa7cb] Merge branch 'task001'
$ ls
quux.c
Run Code Online (Sandbox Code Playgroud)


Abi*_*ern -2

解决这个问题的简单方法首先中止当前合并

git merge --abort
Run Code Online (Sandbox Code Playgroud)

现在,决定要使用的文件版本并使用合并策略(使用标志 -s)

您是分支管理员。如果您想保留在 master 中设置的名称,请使用此命令

git merge -s ours task
Run Code Online (Sandbox Code Playgroud)

如果您想使用任务中的版本

git merge -s theirs task
Run Code Online (Sandbox Code Playgroud)