`git merge -s our`是否正常合并?

时间:2015-04-24 13:37:47

标签: git merge

git中,如果我使用不同的合并策略将提交合并到两个分支中,那么预期的行为是什么,然后我将这两个分支合并在一起?

我想知道哪些分支的实际更改最终会在结果分支中出现,以及原因。

我对git merge -s ours与正常合并提交的行为特别感兴趣。

我做了一个快速的实验,在这个过于简单的例子中,由于git merge -s ours而导致跳过提交的分支(如“出现在日志中,但补丁被省略”)总是获胜(这是我想要的行为,但我不确定我是否可以依赖它(假设文件中的相同行没有进一步的潜在冲突编辑)。

$ git init
Initialized empty Git repository in /sandbox/foo/.git/
$ echo  "qwerty"> foo.txt
$ git add foo.txt
$ git commit -m "Initial commit"
[master (root-commit) 1f58b74] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 foo.txt
$ git checkout -b CLEAN_SLATE
Switched to a new branch 'CLEAN_SLATE'
$ git checkout -b FEAT_BRANCH_A
Switched to a new branch 'FEAT_BRANCH_A'
$ git checkout -b FEAT_BRANCH_B
Switched to a new branch 'FEAT_BRANCH_B'
$ git checkout -b ODD_COMMIT_BRANCH
Switched to a new branch 'ODD_COMMIT_BRANCH'
$ echo "asdf">> foo.txt
$ git add -u
$ git commit -m "Odd commit"
[ODD_COMMIT_BRANCH ba8aab3] Odd commit
 1 file changed, 1 insertion(+)
$ git checkout FEAT_BRANCH_A
Switched to branch 'FEAT_BRANCH_A'
$ # skip over odd commit in branch A
$ git merge -m "Merge -s ours of ODD_COMMIT_BRANCH" -s ours ODD_COMMIT_BRANCH
Merge made by the 'ours' strategy.
$ # include odd commit in branch B
$ git checkout FEAT_BRANCH_B 
Switched to branch 'FEAT_BRANCH_B'
$ git merge -m "Normal merge of ODD_COMMIT_BRANCH" ODD_COMMIT_BRANCH
Updating 1f58b74..ba8aab3
Fast-forward (no commit created; -m option ignored)
 foo.txt | 1 +
 1 file changed, 1 insertion(+)
$ git checkout master                                          
Switched to branch 'master'                                                                               
$ # experiment one: First merge A, then B                      
$ git merge -m "Merge FEAT_BRANCH_A" FEAT_BRANCH_A
Updating 1f58b74..0c15b0c
Fast-forward (no commit created; -m option ignored)
$ git log --graph --oneline
*   0c15b0c Merge -s ours of ODD_COMMIT_BRANCH
|\  
| * ba8aab3 Odd commit
|/  
* 1f58b74 Initial commit
$ cat foo.txt
qwerty
$ git merge -m "Merge FEAT_BRANCH_B" FEAT_BRANCH_B
Already up-to-date.
$ git log --graph --oneline
*   0c15b0c Merge -s ours of ODD_COMMIT_BRANCH
|\  
| * ba8aab3 Odd commit
|/  
* 1f58b74 Initial commit
$ cat foo.txt
qwerty
$ # gives qwerty, so A wins.
$ # experiment two: First merge B, then A
$ git reset --hard CLEAN_SLATE
HEAD is now at 1f58b74 Initial commit
$ git merge -m "Merge FEAT_BRANCH_B" FEAT_BRANCH_B
Updating 1f58b74..ba8aab3
Fast-forward (no commit created; -m option ignored)
 foo.txt | 1 +
 1 file changed, 1 insertion(+)
$ git log --graph --oneline
* ba8aab3 Odd commit
* 1f58b74 Initial commit
$ cat foo.txt
qwerty
asdf
$ git merge -m "Merge FEAT_BRANCH_A" FEAT_BRANCH_A
Updating ba8aab3..0c15b0c
Fast-forward (no commit created; -m option ignored)
 foo.txt | 1 -
 1 file changed, 1 deletion(-)
$ git log --graph --oneline
*   0c15b0c Merge -s ours of ODD_COMMIT_BRANCH
|\  
| * ba8aab3 Odd commit
|/  
* 1f58b74 Initial commit
$ cat foo.txt
qwerty
$ # still gives qwerty, so A still wins.
$ 

2 个答案:

答案 0 :(得分:2)

在您的第二个实验中,FEAT_BRANCH_A“获胜”的原因与ours合并策略关系不大;合并是快进,因此根本不考虑分支之间的差异。

如果您使用--no-ff执行最终合并以强制进行三向合并而不是快进,则结果树是相同的,但为什么您获得相同的树仔细研究。三向合并的 merge-base ba8aab3 Odd commit(也是HEAD),git观察到ba8aab3和{{1}之间的差异是:

FEAT_BRANCH_A

这种差异的产生是因为您之前使用过diff --git a/foo.txt b/foo.txt index 0a93b8c..19f0805 100644 --- a/foo.txt +++ b/foo.txt @@ -1,2 +1 @@ qwerty -asdf 策略,但是git不知道这一点,因为没有记录有关用于生成合并提交的策略的信息。 ours只在你的实验中“获胜”,因为这就是三向差异对git的看法。

总结一下:当立即使用该策略时, 总是依赖FEAT_BRANCH_A的行为。如果你正在进行正常的三向合并,结果取决于差异所说的内容,而快进将只是快进(除非用-s ours抑制)。

答案 1 :(得分:1)

要查看合并正在使用的更改,请执行git diff A...Bgit diff B...A(三个点)。这将显示B(resp。A)与合并基础之间的差异。合并基础的制作方式无关紧要。您的合并策略确定如何协调当前差异,这是其自身相关性的结束。如果您根据对称差异检查图表,这有助于理解结果。