Git 系列教程(12)- 分支的新建與合並


實際工作場景

可能會遇到的工作流

  1. 開發某個網站

  2. 為實現某個新的用戶需求,創建一個分支

  3. 在這個分支上開展新工作

正在此時,你突然接到一個電話說有個很嚴重的問題需要緊急修補,你將按照如下方式來處理:

  1. 切換到你的線上分支(production branch)

  2. 為這個緊急任務新建一個分支,並在其中修復它

  3. 在測試通過之后,切換回線上分支,然后合並這個修補分支,最后將改動推送到線上分支

  4. 切換回你最初工作的分支上,繼續工作

 

新建分支

首先,我們假設你正在你的項目上工作,並且在 master 分支上已經有了一些提交。一個簡單的提交歷史。

為了解決問題,想要新建一個分支並同時切換到那個分支上,你可以運行一個帶有 -b 參數的 git checkout 命令

$ git checkout -b iss53
Switched to a new branch "iss53"

 

它是下面兩條命令的簡寫

$ git branch iss53
$ git checkout iss53

創建一個新分支指針。

創建一個新分支指針

在 iss53 分支上修改東西並提交,該分支就會不斷的向前推進,因為已經 checkout 到該分支 (也就是說,HEAD 指針指向了 iss53 分支)

$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
`iss53` 分支隨着工作的進展向前推進。

緊急插入一個問題待修復

突然緊急插入一個問題需要修復,它可以不用和 iss53 分支混在一起,操作步驟
  1. git status 檢查 iss53 分支下的工作區和暫存區是否有沒提交的修改,不然會阻止 git 切換分支
  2. 切換至 master 分支
  3. 再新建一個 hotfix 分支並切換到它上,進行修復問題工作
$ git checkout master

Switched to branch 'master'

這個時候,Git 會讓工作目錄的內容會和 master 分支上最后一次提交時的內容保持一致,它會自動添加、刪除、修改工作目錄的文件

 

為了修復問題,新建一個分支在上面工作直到問題修復成功

$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
 1 file changed, 2 insertions(+)

基於 `master` 分支的緊急問題分支(hotfix branch)。

合並修復問題的分支到 master 分支上

問題修復成功后,可以將 hotfix 分支合並回 master 分支來部署到線上

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

 

什么是 fast-forward?

  1. 待合並的分支 hotfix 所指向的提交 C4 是你所在的提交 C2 的直接后繼, 因此 Git 會直接將指針向前移動
  2. 換句話說,當試圖合並兩個分支時, 如果順着一個分支走下去能夠到達另一個分支,那么 Git 在合並兩者的時候, 只會簡單的將指針向前推進(指針右移),因為這種情況下的合並操作沒有需要解決的沖突

現在,最新的修改已經在 master 分支所指向的提交快照中,可以提交發布修復了

`master` 被快進到 `hotfix`。

刪除 hotfix 分支,回到 iss53 分支繼續工作

問題解決后,刪除臨時分支,因為不再需要它,而且 master 分支也指向同一個位置了

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).

 

回到 iss53 分支繼續工作,繼續提交

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)

繼續在 `iss53` 分支上的工作。

 

注意

  • 在 hotfix 分支上所做的工作並沒有包含到 iss53 分支
  • 中如果你需要拉取 hotfix 所做的修改,可以使用 git merge master 命令將 master 分支合並入 iss53 分支,或者也可以等到 iss53 分支完成其使命,再將其合並回 master 分支

 

分支 iss53 合並

iss53 分支上工作已完成,回到 master 分支合並 iss53 的東西

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

Merge made by the 'recursive' strategy. 通過遞歸策略合並

  • 因為,master 分支所在提交並不是 iss53 分支所在提交的直接祖先,Git 不得不做一些額外的工作
  • 出現這種情況的時候,Git 會使用兩個分支的末端所指的快照(C4 和 C5)以及這兩個分支的公共祖先(C2),做一個簡單的三方合並
一次典型合並中所用到的三個快照。
 

合並提交

和之前將分支指針向前推進所不同的是,Git 將此次三方合並的結果做了一個新的快照並且自動創建一個新的提交指向它,它的特別之處在於他有不止一個父提交

一個合並提交。

既然修改已經合並進來了,就不再需要 iss53 分支了

$ git branch -d iss53

 

 

遇到沖突時的分支合並

  • 如果在兩個不同的分支中,對同一個文件的同一個部分進行了不同的修改,Git 就沒法干凈的合並它們
  • 假設對 iss53 分支修改的內容和 hotfix 分支的修改都涉及到同一個文件的同一處,在合並它們的時候就會產生合並沖突
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

 

注意

  • 此時 Git 做了合並,但是沒有自動地創建一個新的合並提交
  • Git 會暫停下來,要手動解決合並產生的沖突
  • 使用 git status 命令來查看那些因包含合並沖突而處於未合並(unmerged)狀態的文件
$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

任何因包含合並沖突而有待解決的文件,都會以未合並狀態標識出來

 

沖突標識

Git 會在有沖突的文件中加入標准的沖突解決標記,可以快速定位並解決沖突

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

 

HEAD 所指示的版本

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>

這也是 master 分支下的文件內容,也是沖突的部分內容

 

iss53 分支的版本

<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

這是 iss53 分支下的文件內容,和 master 分支的內容沖突了,此時你必須二選一保留一個

 

保留 iss53 分支的版本

<div id="footer">
please contact us at email.support@github.com
</div>

<<<<<<< , ======= , 和 >>>>>>> 這些行需要刪除哦

在解決了所有文件里的沖突之后,對每個文件使用 git add 命令來將其標記為沖突已解決

 

圖形化工具解決沖突

如果你想使用圖形化工具來解決沖突,你可以運行 git mergetool,該命令會為你啟動一個合適的可視化合並工具,並帶領你一步一步解決這些沖突:

$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html

Normal merge conflict for 'index.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (opendiff):

 

通過 git status 查看合並后的狀態

$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   index.html

 

通過 git commit 提交合並后的內容

Merge branch 'iss53'

Conflicts:
    index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#    .git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#    modified:   index.html
#

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM