iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 27
0
自我挑戰組

Experience of a backend novice系列 第 27

git遇到衝突了怎麼辦?別緊張,解衝後就好了。

Day twenty seven
git遇到衝突了怎麼辦?別緊張,解衝後就好了。
Don't panic when there is a conflict. Just solve it.

Hello everyone. It's Ray.
大家好,我是Ray。

Did you sleep soundly last night? It seems that it's turning cold. A bit cold in the morning, and a bit hot at noon. So difficult to pick a right cloth.
昨晚大家睡得好嗎?最近天氣似有轉涼的跡象啊!早上有點涼,中午熱到爆,衣服實在很難穿啊...

Take care!
希望各位保重龍體阿!

Today I'm going to share 'conflict'
今天要來跟大家分享'衝突'!

When we use git merge to merge two branches, git has its own way to determine whether there is a conflict.
當我們使用git合併兩個分支時,git有自己的一套演算法來判斷會不會產生衝突。

Basically, if you add a new description in a file on A branch, and add a new description in the same file on B branch. In this case, basically it's not so ambiguous, so git doesn't need to decide what it should add and what it should delete, and therefore a conflict may not occur even though it triggers a three-way merge.
基本上,如果你在A分支上的一個檔案新增一行,在B分支上的一個檔案刪掉一行,前提是這兩個分支上都分別有這兩個檔案,在這樣的情況下,基本上因為比較沒有模糊地帶,就是在合併的時候,git不需要去判斷這一行該刪去還是新增。 所以基本上在這樣的情況之下,就算是三路合併(three-way merge),也不會有衝突產生。

In another case, when two branches possess a common file, and we revise the same line on this file on both branches(maybe it doesn't require the same line, however, git has its own way to decide whether there is a confict, in my general rule of thumb, it's very possible to trigger confict when we revise two lines that are very close to each other), and in this case when we try to merge them, git will confuse which branch should be taken as the file version for the new commit. In this case, we need to manually keep what we want and remove what we don't want.
另外一種情況,兩個分支分別擁有一個共同的檔案,而兩個分支分別在同一個檔案的同一行code做了修改(也不一定要同一行,基本上git有自己判定的一個基準,我個人測試是兩個檔案修改的code越靠近的話越有可能會觸發git衝突),在這樣的情況之下,當我們進行合併時,git會不知道該以哪一邊的為準,這時候就需要我們手動的去刪掉我們想刪掉的,留下我們想留下的。

Per the progress yesterday, git should probably look like image below:
延續昨天的進度,目前git看起來大概如下:

Currently we know the file 'fileOnlyExistingInMeatBranch.html' are possessed by both vegetable branch and meat branch.
目前可以知道,'fileOnlyExistingInMeatBranch.html'這個檔案同時存在於vegetable branch以及meat branch,且有著相同的內容。

Now we are going to add a new description "it's a description only existing in vegetable branch", and add another description "a description only existing in meat branch", and then merge two branches. In my general rule of thumb, a confict would occur.
現在我們將在vegetable branch上的這個檔案新增一行敘述"it's a description only existing in vegetable branch", 然後再meat branch 的這個檔案裡頭新增一行敘述"a description only existing in meat branch",再來我們合併兩個分支,未看先猜,會有衝突產生。

英文:

  • let's add a description <p> it's a description only existing in vegetable branch in the file 'fileOnlyExistingInMeatBranch' in vegetable branch.
  • git commit -am 'a description only existing in vegetable branch'
  • git checkout meat branch
  • let's add a description <p>a description only existing in meat branch in the file 'fileOnlyExistingInMeatBranch' in meat branch.
  • git commit -am 'a description only existing in meat branch'
  • git merge vegetable
  • git status

中文:

  • 新增敘述在'vegetable branch'上的'fileOnlyExistingInMeatBrahch'裡,敘述為<p> it's a description only existing in vegetable branch</p>
  • git commit -am 'a description only existing in vegetable branch'
  • git checkout meat branch
  • 新增敘述在'meat branch'上的'fileOnlyExistingInMeatBranch'裡,敘述為<p> a description only existing in meat branch</p>
  • git commit -am 'a description only existing in meat branch'
  • git merge vegetable
  • git status

As what we guessed, a conflict would occur as follows:
如同我們所猜測的,一個衝突將會產生,我們遇到狀況如下圖:

The file highlighted in green 'fileOnlyExistingInVegetableBranch' didn't exist in meat branch, so it shows that once the commit succeeds, this file would be added in newly produced commit.
綠色的新檔案'fileOnlyExistingInVegetableBranch'原本就不存在於meat branch,所以這邊提示如果merge成功此檔案將會被列入commit。

As what we guessed, there is a conflict in the file 'fileOnlyExistingInMeatBranch.html', and as highlighted in red, both branch have modified this file.
如我們猜測,檔案'fileOnlyExistingInMeatBranch.html'裡頭發生了衝突,紅色字串提示,兩個分支共同修改這個檔案。

So far, our git should look like image below:
目前git看起來大概如下圖:

Through the image above we could see that both branches revised the file 'fileOnlyExistingInMeatBranch', so a conflict occurred. Let's go into this file and take a look:
由上圖可以看到,兩個分支都修改了'fileOnlyExistingInMeatBranch'這個檔案,所以產生了衝突。讓我們進到這個檔案看看:

In the file causing conflict, git shows the origin of conflicts for us with =====. Those above ===== represents HEAD, which is pointing to meat branch. Those below ====== represents vegetable branch.
在發生衝突的檔案中,git為我們列出了衝突的來源,以======做區隔,以上的為HEAD,代表目前HEAD所指向的meat branch,以下的為vegetable branch.

Now let's keep whatever we want and delete the rest. I personally prefer meat, so let's remove vegetable.
現在讓我們手動來留下我們想留下的,我個人比較喜歡吃肉,那就把vegetable的移除吧

We only keep teh description on meat branch as image above:
我們只留下meat branch上的那行敘述,如上圖。

Enter:
輸入:
git add fileOnlyExistingInMeatBranch
git merge --continue
:wq
git log --oneline

As image below, the merge has completed.
如上圖,merge已經完成。

And then we go into 'fileOnlyExistingInMeatBranch' to take a look as follows:
接著到檔案'fineOnlyExistingInMeatBranch'裡去看看,如下:

In the commit that git created for merging two branches, the content is exactly what we manually revised and kept when solving conflict. Until now, we've fix the conflict and complete the merge.
在git為了merge兩個branch而產生的新的commit中,這個檔案裡的內容正是我們剛剛在解除衝突中留下的最終版本,到這邊我們已經成功地完成解除衝突並且完成了這次的merge。

It's turning cold lately. Bundle up guys!
天冷風寒,大家注意保暖啊!

See you tomorrow.
我們明天見!


上一篇
Git merge,三路合併的概念
下一篇
操縱歷史的魔術師- git rebase
系列文
Experience of a backend novice30

尚未有邦友留言

立即登入留言