git 入門教程之變基合並


git 鼓勵大量使用分支---"早建分支!多用分支!",這是因為即便創建再多的分支也不會造成存儲或內存開銷,並且分支的作用有助於我們分解邏輯工作,這樣一樣其實比維護單一臃腫分支要簡單得多!

正因如此,每個新功能會創建合並分支,修復 bug 會創建合並分支等等,一段時間后再次回顧整個版本庫的提交歷史就會發現分支錯綜復雜,難以理清!

雖然"條條大路通羅馬",但錯綜復雜的道路容易讓人迷失方向,如果不使用分支,當然就不存在"分叉問題",所以在某些情況下我們希望尋求一種替代方案來解決分支合並帶來的"分叉問題"!

回顧提交歷史

查看提交歷史: git log --pretty=oneline --graph --abbrev-commit

# 查看提交歷史
$ git log --pretty=oneline --graph --abbrev-commit
* e60c8ad (HEAD -> dev, origin/master, origin/HEAD, master) fix bug about issue-110
* 3fe94c0 fast forward
*   22fbef7 git merge --no-ff dev
|\  
| * 44d68f6 git checkout -b dev
|/  
*   3b8f434 fix conflict
|\  
| * 0fe95f8 git commit c2
* | 0949cc3 git commit c3
|/  
* 5c482cd git commit c1
* 413a4d1 see https://snowdreams1006.github.io/git/usage/branch-overview.html
* 9c30e50 learn git branch
* b3d8193 see https://snowdreams1006.github.io/git/usage/remote-repository.html
* 8e62564 add test.txt
* 9b196aa Initial commit

僅僅是簡單的演示項目的提交歷史都已經出現"分叉問題",更何況真實的企業級開發項目呢?如果真的是多分支多人合作開發的話,"分叉現象"將更加明顯,模擬效果圖大概長這樣:

git-branch-multiple.png

整理提交歷史

如果想要一條直路直達羅馬,那我們必須規划好路徑,摒棄小道,堅持主干道.git 的各種 dev,feature等分支就是需要治理的一條條分叉小道,而 master 主分支就是我們的大道.

演示項目有三個分支,主干master,開發dev,自定義snow,目標是將自定義 snow 分支的工作成功整理合並到主干分支,從而解決"分叉問題",dev 分支與項目演示無關,無需更改.

(1). 切換到 snow 分支並提交一個版本(learn git rebase)

# 切換到 `snow` 分支
$ git checkout snow
Switched to branch 'snow'

# 追加新內容到 `test.txt` 文件
$ echo "learn git rebase" >> test.txt

# 提交到版本庫
$ git commit -am "learn git rebase"
[snow 7d21e80] learn git rebase
 1 file changed, 1 insertion(+)
$ 

git-branch-rebase-snow.png

(2). 切換到 master 分支也提交一個版本(modify README)

# 切換回 `master` 分支
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

# 追加新內容到 `README.md` 文件
$ echo "learn git ,share git" >> README.md

# 提交到版本庫
$ git add README.md
$ git commit -m "modify README"
[master 3931d48] modify README
 1 file changed, 1 insertion(+)
$ 

git-branch-rebase-master.png

(3). 切換回 snow 分支,整理提交歷史(git rebase)到 master 分支

# 切換到 `snow` 分支
$ git checkout snow
Switched to branch 'snow'

# 改變基礎版本(父版本),簡稱"變基"
$ git rebase master
HEAD is up to date.

# 當前提交歷史線
$ git log --pretty=oneline --graph --abbrev-commit
* e92f068 (HEAD) rebase
* 72f4c01 fix confict about happy coding
* 3931d48 (master) modify README
* e60c8ad (origin/master, origin/HEAD, dev) fix bug about issue-110
* 3fe94c0 fast forward
*   22fbef7 git merge --no-ff dev
|\  
| * 44d68f6 git checkout -b dev
|/  
*   3b8f434 fix conflict
|\  
| * 0fe95f8 git commit c2
* | 0949cc3 git commit c3
|/  
* 5c482cd git commit c1
* 413a4d1 see https://snowdreams1006.github.io/git/usage/branch-overview.html
* 9c30e50 learn git branch
* b3d8193 see https://snowdreams1006.github.io/git/usage/remote-repository.html
* 8e62564 add test.txt
* 9b196aa Initial commit
$ 

git-branch-rebase.png

(4). 切換回 master 主干分支再次變基合並 snow 分支

# 切換回 `master` 分支
$ git checkout master
Warning: you are leaving 2 commits behind, not connected to
any of your branches:

  e92f068 rebase
  72f4c01 fix confict about happy coding

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> e92f068

Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

# 改變父版本為 `snow` 分支指向的版本  
$ git rebase snow
First, rewinding head to replay your work on top of it...
Applying: modify README
$

git-branch-rebase-back-master.png

(5). 整理分支完成,最終主干分支是一條直線

# 查看提交歷史線
$ git log --pretty=oneline --graph --abbrev-commit

# `modify README` 是 `master` 分支提交的版本
* dcce09c (HEAD -> master) modify README

# `learn git rebase` 是 `snow` 分支提交的版本
* 7d21e80 (snow) learn git rebase
*   a06a866 fix conflict
|\  
| * e60c8ad (origin/master, origin/HEAD, dev) fix bug about issue-110
* | ab846f9 learn git stash
* | 93227ba Happy coding
|/  
* 3fe94c0 fast forward
*   22fbef7 git merge --no-ff dev
|\  
| * 44d68f6 git checkout -b dev
|/  
*   3b8f434 fix conflict
|\  
| * 0fe95f8 git commit c2
* | 0949cc3 git commit c3
|/  
* 5c482cd git commit c1
* 413a4d1 see https://snowdreams1006.github.io/git/usage/branch-overview.html
* 9c30e50 learn git branch
* b3d8193 see https://snowdreams1006.github.io/git/usage/remote-repository.html
* 8e62564 add test.txt

這一次我們沒有使用 git merge 而是采用 git rebase 方式完成了分支的合並,優點是提交歷史更清晰,缺點是丟失了分支信息.

小結

git rebase 變基合並分支,實際上就是取出一系列的提交版本並“復制”到目標版本,從而形成一條新的提交歷史線.
比如我們想要把 bugFix 分支里的工作直接移到 master 分支上,移動以后會使得兩個分支的功能看起來像是按順序開發,但實際上它們是並行開發的,這就是 git rebase 的作用.

git rebase 的優勢是創造更線性的提交歷史,使得代碼庫的提交歷史變得異常清晰,劣勢是缺失了分支信息,好像從沒存在過該分支一樣.

  1. 將目標分支上的工作成果轉移到到主干分支 : git rebase master
  2. 主干分支接收已轉移好的目標分支工作成果 : git rebase <branch>


免責聲明!

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



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