課程目標

  • 學會處理 git 衝突

課程內容

這課來學一下 commit 彼此有衝突,而 git 沒辦法自動合併的情況吧

先挑一個資料夾,把 my-work-1.html 裡面隨意加上幾行內容

<p>我的第一個網頁檔案</p>
<p>new content a</p>
<p>new content b</p>
<p>new content c</p>

接著

git add my-work-1.html

git commit -m 'new content abc'

git push

順利送出!

然後去另一個資料夾,把 my-work-1.html 裡面隨意加上幾行內容

<p>我的第一個網頁檔案</p>
<p>new content x</p>
<p>new content y</p>
<p>new content z</p>

接著

git add my-work-1.html

git commit -m 'new content xyz'

git push

結果失敗了!一如預期,被 git 喊停了

To github.com:howtomakeaturn/my-first-testing-repo.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:howtomakeaturn/my-first-testing-repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

預期之中,這時應該 pull 對吧?

git pull
remote: Enumerating objects: 14, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 8 (delta 3), reused 8 (delta 3), pack-reused 0
Unpacking objects: 100% (8/8), 792 bytes | 79.00 KiB/s, done.
From github.com:howtomakeaturn/my-first-testing-repo
   d999c25..2cf01f4  main       -> origin/main
hint: Pulling without specifying how to reconcile divergent branches is
hint: discouraged. You can squelch this message by running one of the following
hint: commands sometime before your next pull:
hint:
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
Auto-merging my-work-1.html
CONFLICT (content): Merge conflict in my-work-1.html
Automatic merge failed; fix conflicts and then commit the result.

在前一課,我們 pull 之後,會被 git 自動把雲端版本、跟本機你剛改過的版本,合併在一起,然後在終端機編輯器內,請你打一段小訊息,備註這次合併

這次,卻沒有進入終端機編輯器內,而是跳出一串訊息!

注意看最後幾行!

Auto-merging my-work-1.html
CONFLICT (content): Merge conflict in my-work-1.html
Automatic merge failed; fix conflicts and then commit the result.

這就是 commit 衝突的情況:兩個 commit 都有改到同樣檔案,雖然先後時間不同,但是 git 不敢直接用新的蓋掉舊的!

git status 看一下

Unmerged paths:
  (use "git add <file>..." to mark resolution)
    both modified:   my-work-1.html

清楚寫出了:both modified,兩邊都修改過!

打開 my-work-1.html 看一下

<p>我的第一個網頁檔案</p>
<<<<<<< HEAD
<p>new content x</p>
<p>new content y</p>
<p>new content z</p>
=======
<p>new content a</p>
<p>new content b</p>
<p>new content c</p>
>>>>>>> 2cf01f4f63f5ea9040610495688f08032761a170

看起來很嚇人,其實,只是 git 怕你看不清楚,用一種誇飾法,列出衝突的地方而已!

HEAD 段落,是你剛提交的 commit 部份

2cf01f4f63f5ea9040610495688f08032761a170 的部份呢?則是剛剛從 github 抓下來的 commit 代號!

要如何處理衝突呢?其實,你就決定一下,衝突這幾行,到底要怎麼合併就可以了,然後把 git 誇飾法的地方刪掉

比方說,我決定讓行數交錯呈現吧

<p>我的第一個網頁檔案</p>
<p>new content a</p>
<p>new content x</p>
<p>new content b</p>
<p>new content y</p>
<p>new content c</p>
<p>new content z</p>

改完之後

git add my-work-1.html
git commit -m 'handle conflict'

手動合併的 commit,我個人通常習慣訊息就寫 handle conflict

git push

大功告成!這就是所謂的 git 衝突處理

課後作業

接續前一課的作業

在上一次的作業,我們嘗試了兩個資料夾,同時 push 送出 commit,導致 git 比對 github 上的雲端版本時,發現有衝突,請你先 pull 再 push 的情況

上次的情況比較單純,因為雖然有衝突,但是 git 一看就知道影響不大,所以 pull 時自動處理了衝突,把事情都安排好了

這次的作業,我們要模擬「遇到衝突,而且 git 無法自動處理衝突」的情況


請按照以下步驟,送出 commit

第一步

at-home 資料夾,打開檔案 about.html 的內容,原本是

<h1>我是誰</h1>
<p>我是XXX,目前在自學網頁開發</p>

請改成

<h1>我是誰</h1>
<p>我是XXX,目前在自學網頁開發,目標是成為厲害的前端工程師</p>

然後送出 commit,接著 git push 出去

你會看到 github 上面就被更新了

第二步

at-laptop 資料夾,假設你今天出門工作,忘記先 pull 了,也忘記檔案其實你已經改好了

打開檔案 about.html 的內容,依然是

<h1>我是誰</h1>
<p>我是XXX,目前在自學網頁開發</p>

請改成

<h1>我是誰</h1>
<p>我是XXX,目前在自學網頁開發,目標是成為厲害的軟體工程師</p>

然後送出 commit,接著 git push 出去

這時 git 會請你先更新,於是你輸入 git pull

你會發現 git 表示遇到衝突,無法自動合併,請你處理!

原來有一邊是寫「前端工程師」,另一邊是寫「軟體工程師」

git 無法自動判斷你到底是想要以哪個為準!(其實用哪個都可以吧!)

請處理這個 conflict 衝突,處理完之後 push 到 github 上面

完成以上任務,你就完成這次的課程目標了!


交作業的方法:

可以把 github 專案連結,貼到留言區


歡迎將作業成果,在下方留言,跟大家分享,讓大家給你一些回饋!

可以將每課學到的觀念、關鍵字,丟到網路上去搜尋、研究一下!

發問請在「討論專區」為主,或者分享學習筆記、寫學習心得!

貼文都會出現在個人檔案頁面,成為學習歷程、部落格紀錄!

未來面試時,分享給面試官看,會讓人知道你的積極程度!

按讚的人:

共有 14 則留言