[英]How to force git into “merge conflict mode”?
I have a file foo
in branch master
. 我在分支
master
有一个文件foo
。 It needs some work so I create branch bar
where I do some work. 它需要一些工作,因此我在其中创建一些工作的分支
bar
。 Things look satisfactory so I am ready to merge back into master
. 事情看起来令人满意,所以我准备好重新融入
master
。 Just one problem: I want to keep all of the changes I made in branch bar
for future reference, but not all of the changes belong in the master
, not right now anyway. 只是一个问题:我想保留在分支
bar
所做的所有更改以供将来参考,但并非所有更改都属于master
,现在也不是。 But if I do the usual merge, git will not see any conflicts -- since file foo
in master
hasn't been edited -- and will just do the merge. 但是,如果我执行通常的合并,则git不会看到任何冲突-由于尚未编辑
master
文件foo
只会合并。 Is there a way to force git to do this merge as if there were conflicts that I need to resolve? 有没有一种方法可以强制git进行合并,就好像我需要解决冲突一样? Or is there some other way to place only selected changes in
bar
into master
? 还是有其他方法可以将
bar
仅选定的更改放入master
?
There are several options. 有几种选择。 The one that directly answers your question:
直接回答您的问题的人:
git merge --no-commit
will perform the auto-merge to the index and then stop, just as if manual conflict resolution were needed. 将执行自动合并到索引然后停止,就像需要手动解决冲突一样。 Of course there will be no conflict markers and no changes "unstaged" / waiting for resolution, but you can modify the commit to look how you want before you commit.
当然,不会有冲突标记,也没有“未暂存” /等待解决的更改,但是您可以修改提交以在提交之前查看所需的内容。
The biggest problem with that, aside from "it's probably a mess to do", is that as far as git is concerned all changes in bar
are now accounted for in master
. 除了“可能很麻烦”之外,最大的问题是,就git而言,
bar
所有更改现在都在master
。 Since you implied that you might want the remaining changes later, that's not good. 由于您暗示可能以后需要其余更改,所以这不是很好。
What you really want is something like 您真正想要的是
x --- O --- M <--(master)
\ /
A --- B <--(bar)
where O
is the original branch point, A
has the changes that you want now, and B
has the changes you'll want later. 其中
O
是原始分支点, A
具有您现在想要的更改,而B
具有您以后想要的更改。
(Or, if you want to avoid the merge commit, you would want (或者,如果您希望避免合并提交,则需要
x --- O --- A <--(master)
\
B <--(bar)
instead.) 代替。)
How best to get to this depends on what you have now. 如何最好地做到这一点取决于您现在拥有什么。 If
bar
has just a single commit (or, in any event, if you're happy to end up with just one "commit to merge now" and one "commit to save for later"), and if there are no commits on master
after O
, you could do this: 如果
bar
仅有一次提交(或者无论如何,如果您很高兴以一个“现在合并”和一个“以后保存供以后保存”而告终),并且master
节点上没有提交在O
之后,您可以执行以下操作:
Starting with 从...开始
x --- O <--(master)
\
AB <--(bar)
you do 你做
git checkout bar
git reset --mixed HEAD^
(assuming there's really just a single commit on bar
; otherwise, replace HEAD^
with something like the SHA1 value for commit O
or a tag that you've put in place on commit O
). (假设在
bar
上实际上只有一个提交;否则,将HEAD^
替换为诸如O
的SHA1值或在O
上放置的标记之类的东西)。 Now you have 现在你有
x --- O <--(master)(bar)
^HEAD
with all of the original changes from bar
untracked in your working tree. 与所有的从原来的变化
bar
在你的工作树未被跟踪。 Because all of the changes are in a single file, we need to use patch mode to selectively add changes 因为所有更改都在一个文件中,所以我们需要使用补丁程序模式有选择地添加更改
git add -p
# select the changes to merge
git commit
git stash
giving you 给你
x --- O <--(master)
\
A <--(bar)
\ ^HEAD
B <--{stash}
So next 接下来
git checkout master
git merge bar
If you want a merge commit (preserving the topology in which your changes were made on bar
) then pass --no-ff
to the merge
command. 如果要进行合并提交(保留对
bar
更改的拓扑),则将--no-ff
传递给merge
命令。 Otherwise, since we're assuming master hasn't diverged from bar
, you'll just get a fast-forward leaving 否则,由于我们假设master尚未偏离
bar
,您将获得快速前进的机会
x --- O --- A <--(master)(bar)
\ ^HEAD
B <--{stash}
(Conversely, if master
had diverged yet you decide to linearlize history, you would rebase A
onto master
instead of merging...) (相反,如果
master
还没有分出你决定linearlize历史,你会重订A
到master
,而不是合并的......)
Then you can do something like 然后你可以做类似的事情
git branch --delete bar
git stash branch bar
to end at 结束于
x --- O --- A <--(master)
\
B <--(bar)
If I'm guessing it right, you want only selective changes to be merged from bar
into master
. 如果我猜对了,您只希望将选择性更改从
bar
合并到master
。 In that case, you can use cherry-pick
or rebase --onto
to accomplish that, as long as the changes you want to bring in master branch are in atomic commits. 在这种情况下,只要要在master分支中进行的更改都在原子提交中,就可以使用
cherry-pick
或rebase --onto
来实现。 (If they aren't you might need to rewrite history to do that) (如果不是,那么您可能需要重写历史记录才能做到这一点)
>>> git checkout bar
>>> git log --oneline
b00ac1e third
24097f8 second
ade3073 first
# Let's say you want to bring `third` and `second` commit into master but not first
# Use cherry-pick if you have few commits, that you want to transfer
>>> git checkout master
>>> git cherry-pick 24097f8 # sha id of `second` commit
>>> git cherry-pick b00ac1e # sha id of `third` commit
You need to keep the changes that are supposed to be merged into master
and the changes in separate commits than the ones which are not to be merged into master
, but to be kept in bar
: 您需要保留应该合并到
master
的更改,并将更改保存在单独的提交中,而不是不合并到master
中但保留在bar
更改:
o [master]
\
A - B - C - D - E - F [bar]
^^^^^^^^^
to be merged
Note that the commits which are to be merged need to come first. 注意,要合并的提交必须先到。 If this is not the case you need to reorder them using
git rebase -i master bar
. 如果不是这种情况,则需要使用
git rebase -i master bar
对其重新排序。
In order to create a real merge commit (as opposed to fast-forwarding master
to C
) you need to do 为了创建一个真正的合并提交(而不是将
master
快速提交到C
),您需要执行
$ git checkout master
$ git merge --no-ff <hash of commit C>
This should result in 这应该导致
o --------- G [master]
\ /
A - B - C - D - E - F [bar]
By omitting --no-ff
you would get 省略
--no-ff
您将得到
o - A - B - C [master]
\
D - E - F [bar]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.