Git-合並基本觀念與成功合並

2024年2月6日 23点热度 0人点赞

由於 Git 是一種分佈式版本控制系統 (DVCS),過程中會不斷的進行分支與合並,無論是有意的合並 (git merge) 或無意的合並 (git pull),總之使用 Git 版控分支合並的動作確實經常發生。

關於合並的基本觀念

當你在 Git 工作目錄下建立分支時,可以讓你的系統依據不同的需求分別進行開發,又不互相影響。例如你原本穩定的系統可以放在 master 分支中進行開發,而當要修正錯誤時則額外建立一個bugfix分支來改正軟件錯誤,等 Bugs 修正後,再通過合並的方式將 bugfix 分支上的變更重新套用到 master 上面,這就是一種主要的使用場景。

一般來說,大傢都是以一個主要或預設分支進行開發 (master),然後再依據需求建立分支 (bugfix),最後則是將兩個分支合並成一個。事實上,執行合並動作時,是將另一個分支合並回目前分支,然後再手動將另一個分支給移除,這樣才符合兩個分支合並成一個的概念。

實際上,也經常有機會將三個、四個或更多的分支合並到其中一個分支。例如你除了主要分支 (master) 外,還額外建立了除錯用的分支 (bugfix) 與新增功能 (feature) 的分支,當開發到一定程度後,你可以決定要不要將這個兩個分支一起合並回主要分支 (master)。

在 Git 使用合並時,有一個重要的觀念是合並的動作必須發生在同一個倉庫中。在任何一個 Git 倉庫中,都必須存在一個 Initial Commit (初始版本),而所有其他版本都會跟這個版本有關系,這個關系我們稱為在分支線上的可追蹤(the tracked object on the branch heads),所以你不能將一個倉庫的特定分支合並到另一個毫不相幹的倉庫的某個分支裡。

合並的時候,如果兩個分支當中有修改到相同的文件,但隻要修改的行數不一樣,Git 就會自動幫你套用 / 合並這兩個變更。但如果就這麼剛好,你在兩個分支裡面改到同一個文件同一行,那麼在合並的時候就會引發沖突事件。當合並沖突發生時,Git 並不會幫你決定任何事情,而是將解決沖突的工作交給來負責,且這些發生沖突的文件也都會被標示為 unmerged 狀態,合並沖突後你可以用 git status 指令看到這些狀態。

體驗一場成功的合並

簡單來說,成功的合並就是沒有發生沖突的合並。用一個簡單的例子說明合並的過程與指令的用法:

mkdir git-merge-demo
cd git-merge-demo
git init
echo . > a.txt
git add .
git commit -m "Initial commit (a.txt created)"
echo 1 > a.txt
git add .
git commit -m "Update a.txt!"

接著我們通過 git checkout -b feature 建立一個 feature 分支,並同時把工作目錄給切換到 feature 分支進行開發,然後建立一個內容為 2b.txt 文件:

git checkout -b feature
git branch
echo 2 > b.txt
type b.txt
git add .
git commit -m "Add b.txt!"

註意:在切換分支之前,請隨時查看並保持工作目錄的狀態是幹凈的,不要有任何文件異動中的狀態。

以下是兩個分支的內容:

  • • 主要分支:master:擁有 a.txt 其內容為 1
  • • 功能分支:feature (目前所在分支),擁有 a.txt 其內容為 1 (此文件是從 master 分支繼承過來的) 還有b.txt其內容為 2

現在要做 3 件事:

  1. 1. 將工作目錄切換回 master 主要分支
  2. 2. 將 a.txt 的內容新增一行 NEW LINE 在第二行 (第一行不動)
  3. 3. 將 a.txt 的異動加入索引,並commit版本
git status
git checkout master
echo "NEW LINE" >> a.txt
type a.txt
git status
git add .
git commit -m "Update a.txt: append NEW LINE"

當下兩個分支的內容:

  • • 主要分支:master (目前所在分支),擁有a.txt其內容有兩行,第一行為 1,第二行是 NEW LINE,這裡沒有 feature 分支的變更,也就是沒有 b.txt 文件。
  • • 功能分支:feature,擁有 a.txt 其內容為 1 (這是從 master 分支繼承過來的,在 feature 沒動過)還有 b.txt 其內容為 2 (這是 feature 新建立的文件)。

用 SourceTree 可以查看較為漂亮的 commit graph (版本圖):

由於兩個分支都有在建立 feature 分支後都做過異動,不過你可能會發現到,這兩個分支當中,從分支點開始,所做的修改並沒有互相沖突,隻要是這種狀況,合並並不會發生問題。接下來我們就來執行合並動作 (git merge)。

  1. 1. 合並之前,先看清楚自己在哪個分支
  2. 2. 合並之前,請確保工作目錄是幹凈的
  3. 3. 合並時請用 git merge [另一個分支] 來將另一個分支的變更合並回來
  4. 4. 合並成功後,可以利用 git log 查看版本記錄,可以發現 合並的過程會自動建立一個新版本
git branch
git status
git merge feature
git log --oneline

看看合並後的分支狀況,用 SourceTree 的 commit graph 來看:

最後來看看合並後的文件內容,確實如我們預期的把兩個分支中的變更都給合並了:

這就是一場成功的合並