在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.
$
答案 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...B
和git diff B...A
(三个点)。这将显示B
(resp。A
)与合并基础之间的差异。合并基础的制作方式无关紧要。您的合并策略确定如何协调当前差异,这是其自身相关性的结束。如果您根据对称差异检查图表,这有助于理解结果。