简体   繁体   English

产生git合并冲突

[英]Producing a git merge conflict

I'm trying to produce a git merge conflict intentionally. 我试图故意产生git merge冲突。 Here is what I did 这是我所做的

mkdir to-stack
cd to-stack
git init
vi a.txt
Added some text to first line of a.txt 
git add a.txt
git commit -m "Added a line to a.txt"

git checkout -b other
vi a.txt
Updated the text on first line of a.txt to something else
git add a.txt
git commit -m "Updated line 1"

git checkout master
git merge other

Merge happened and the content a.txt in master branch got overwritten to that of from other branch 发生合并,并且master分支中的内容a.txt被其他分支的内容覆盖

I was expecting a Merge conflict to happen when doing the merge. 我期待合并时发生合并冲突。 Since I had changed the same line in other branch 由于我在其他分支中更改了同一行

Can you tell me why Merge conflict didn't happen in above case? 您能告诉我为什么在上述情况下没有发生合并冲突吗?

A merge combines the changes from some common commit, to two different commits (whose relationship is that they both have that common commit in their histories). 合并将更改从某个常见提交更改为两个不同的提交(它们之间的关系是它们在历史记录中都具有该相同的提交)。

That is, consider the following commit graph, where each o or * represents a commit, and every commit's parent is the commit that is found by following its connection leftwards (moving up or down if necessary): 也就是说,考虑以下提交图,其中每个o*代表一个提交,并且每个提交的父级都是通过向左跟随其连接(如有必要,向上或向下移动)找到的提交:

          o   <-- branchA
         /
...--o--*
         \
          o--o   <-- branchB

The first commit that branchA and branchB share is the one marked * . branchAbranchB 共享的第一个提交是标记为*提交。 They also share every earlier commit (to the left of * ), but * is the most interesting such commit. 它们还共享每个较早的提交(在*的左侧),但是*是最有趣的此类提交。 We call this commit the merge base of branchA and branchB . 我们称此提交为branchAbranchB合并基础

When you run: 运行时:

$ git checkout branchA
$ git merge branchB

the git merge step sees that we are on branchA (due to the git checkout command), and that we are asking to merge the tip-most commit of branchB . git merge步骤看到我们 branchA (由于git checkout命令),并且我们要求合并branchB的最尖端提交。 Git then locates this merge base commit, and runs two git diff commands. 然后,Git定位此合并基础提交,并运行两个 git diff命令。

Let's say the hash of commit * is ba5e... , and the tip commit on branchA is commit 1111... with the tip commit of branchB being 2222... . 比方说,提交的哈希值*ba5e... ,和尖端提交上branchA是提交1111...与尖端提交的branchB2222... The two git diff commands are then essentially: 这两个git diff命令实际上是:

$ git diff ba5e 1111

and: 和:

$ git diff ba5e 2222

The first diff tells Git "what we did": what we changed from * to the tip of branchA . 第一个差异告诉Git“我们做了什么”: 我们*更改为branchA的尖端。 The second diff tells Git "what they did": what they changed going from * to the tip of branchB . 第二个差异告诉Git“他们做了什么”:从*branchB的尖端, 它们发生了什么变化。

A merge conflict occurs when some part of "what we did" changes the same line(s) of the same file(s) as some part of "what they did" changes, but the two changes are different. 当“我们所做的事情”的某些部分更改同一文件的同一行时,与“他们所做的事情”的某些部分更改时,发生合并冲突 ,但是这两个更改是不同的。 For instance, if we both change README.txt to change the color of an apple, but we change it from purple to black, and they change it from purple to orange, Git doesn't know which one to take. 例如,如果我们都更改README.txt来更改苹果的颜色,但是我们将其从紫色更改为黑色,然后又将其从紫色更改为橙​​色,则Git不知道要选哪个。

So, let's do just that: 因此,让我们这样做:

mkdir mtest && cd mtest && git init
echo 'for testing' > README.txt
echo 'have a purple apple' >> README.txt
git add README.txt && git commit -m initial

This creates branch master with one file, README.txt . 这将使用一个文件README.txt创建分支master Now let's create two separate branches forking from this one commit, and change the color of the apple in each branch: 现在,让我们从一次提交中创建两个独立的分支,并在每个分支中更改苹果的颜色:

git checkout -b branchA master
sed -i '' s/purple/black/ README.txt
git add README.txt && git commit -m black

git checkout -b branchB master
sed -i '' s/purple/orange/ README.txt
git add README.txt && git commit -m black

Now we simply merge one branch with the other. 现在,我们简单地将一个分支与另一个分支合并。 We are currently on branchB , so we can git merge branchA now. 我们目前在branchB ,因此我们现在可以git merge branchA Once we resolve the conflict and commit, we'll have a merge on branchB . 解决冲突并提交后,将在branchB上进行合并。 Or, we can git checkout branchA first, then git merge branchB . 或者,我们可以先git checkout branchA ,然后git merge branchB We will get the same conflict, but once we resolve it and commit, we'll have a merge on branchA . 我们将得到相同的冲突,但是一旦解决并提交,我们将在branchA上进行合并。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM