git
鼓勵大量使用分支---"早建分支!多用分支!",這是由於即使建立再多的分支也不會形成存儲或內存開銷,而且分支的做用有助於咱們分解邏輯工做,這樣同樣其實比維護單一臃腫分支要簡單得多!html
正因如此,每一個新功能會建立合併分支,修復 bug
會建立合併分支等等,一段時間後再次回顧整個版本庫的提交歷史就會發現分支錯綜複雜,難以理清!git
雖然"條條大路通羅馬",但錯綜複雜的道路容易讓人迷失方向,若是不使用分支,固然就不存在"分叉問題",因此在某些狀況下咱們但願尋求一種替代方案來解決分支合併帶來的"分叉問題"!github
查看提交歷史: git log --pretty=oneline --graph --abbrev-commit
app
# 查看提交歷史 $ 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
僅僅是簡單的演示項目的提交歷史都已經出現"分叉問題",更況且真實的企業級開發項目呢?若是真的是多分支多人合做開發的話,"分叉現象"將更加明顯,模擬效果圖大概長這樣:this
若是想要一條直路直達羅馬,那咱們必須規劃好路徑,摒棄小道,堅持主幹道.git
的各類 dev
,feature
等分支就是須要治理的一條條分叉小道,而 master
主分支就是咱們的大道.spa
演示項目有三個分支,主幹master
,開發dev
,自定義snow
,目標是將自定義 snow
分支的工做成功整理合併到主幹分支,從而解決"分叉問題",dev
分支與項目演示無關,無需更改.3d
(1). 切換到 snow
分支並提交一個版本(learn git rebase
)code
# 切換到 `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(+) $
(2). 切換到 master
分支也提交一個版本(modify README
)htm
# 切換回 `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(+) $
(3). 切換回 snow
分支,整理提交歷史(git rebase
)到 master
分支ip
# 切換到 `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 $
(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 $
(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
的優點是創造更線性的提交歷史,使得代碼庫的提交歷史變得異常清晰,劣勢是缺失了分支信息,好像從沒存在過該分支同樣.
git rebase master
git rebase <branch>