合併與變基
我們正在開發某個專案,為了實現某個專案,我們建立了分支task_113
,正在這個分支上開展工作。這個時候收到反饋說有個很嚴重的bug需要立即處理。這個時候,你應該立即切換到線上分支,為這個bug建立新的分支issue_005
,並在這個分支上修復它。在測試通過後,切換到線上分支來合併issue_005
,最後將改動推到線上。然後切換回task_113
上繼續做新的需求。
merge 合併
開始在task 113上工作:
在沒開始做任務前,我們倉庫的結構如上。現在我們開始建立task_113分支:
$ git checkout -b task_113 Switched to a new branch 'task_113'
這個時候我們的git倉庫結構如下:
這個時候我們在當前分支上做了些工作,並且提交到了版本庫後,我們的git結構如下:
收到緊急問題issue 005
這個時候我們收到反饋的bug後,我們立即切到master分支上,從master分支建立新的issue_005
分支開始解決線上的bug:
在切換到master之前,需要確認所有修改已經提交到版本庫中。
# 切換到master分支 git checkout master Switched to branch 'master' # 建立issue_005分支處理bug git checkout -b issue_005 Switched to a new branch 'issue_005'
下面的圖是我們現在git倉庫的狀態: 當issue_005分支上的修改測試完成後,我們需要到master上將其合併。
git checkout master Switched to branch 'master' git merge issue_005 Updating 04132ad..86e4899 Fast-forward about.html | 1 + 1 file changed, 1 insertion(+)
Fast-forward: 表示的是在合併兩個分支的時候,如果順著一個分支走下去能夠到達另一個分支,那麼Git在合併兩者的時候,只會簡單的將指標向前推進(指標右移),因為這種情況沒有需要解決的分歧,這就叫做快進。
這個緊急問題處理完成後,我們就可以將issue_005這個分支刪除,因為我們再也用不上它了。刪除完成後,我們繼續回到task_113分支上繼續我們的工作:
git branch -d issue_005 Deleted branch issue_005 (was 86e4899). git checkout task_113 Switched to branch 'task_113' git commit -a -v -m 'update index.html[task 113]' [task_113 76e0e88] update index.html[task 113] 1 file changed, 1 insertion(+)
這個時候我們再來看看我們的倉庫結構:
合併分支
task_113的需求我們已經完成了,並且測試通過,這個時候我們應該開始將它合併到master上準本釋出到線上環境了。
git checkout master Switched to branch 'master' git merge task_113 Merge made by the 'recursive' strategy. index.html | 2 ++ 1 file changed, 2 insertions(+)
這次的合併並沒有像上次合併那樣,出現Fast-forward
。因為master分支所在提交併不是task_113分支所提交的直接祖先,在這種情況下,Git會使用兩個分支末端所指的快照(c4和c5)以及這兩個分支的共同祖先c2來一個簡單的三方合併。合併過後的倉庫結構為:
這個時候我們再把task_113分支刪除了就好了。我們再看看git log --graph
的結果:
從上圖可以看出,和我們畫的結構圖完全一致,接下來我們再介紹下另外一種方法變基
變基
上圖是我們當前專案結構,如果這個時候用合併的方式來整合分支的話,最終結構為: 整合分支最容易的方法就是合併分支。它會把兩個分支的最新快照以及二者之間共同祖先(如果能過快進的話,則直接快進)進行三方合併來生成新的快照。
而變基則是提取出C4中引入的補丁和修改,在C3的基礎上應用一次。可以使用rebase命令將提交的某一分支上的所有修改都移至另一分支上。
$ git checkout experiment $ git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command
這個時候我們回到master上,進行一次快進合併:
git merge work Updating 3462092..ece0ba5 Fast-forward work.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 work.html
合併過後,我們的倉庫結構為:
還是用git log --graph來看看最後的結構:
其實變基和合並一樣,最終都生成了一次新的提交,但是使用變基我們讓提交歷史變得更加簡介,你可以看到經過變基的分支的歷史記錄中,儘管開發工作是並行的,但是它們看起來就好像是穿行一樣,提交歷史是一條直線沒有分叉。在簡單的專案中,可能有點分叉也沒什麼,但是在一個多人維護的大型專案中,分叉多了專案的維護工作就會變得越來越複雜。
一般情況下我們用變基也就是為了確保向遠端分支推送時能夠保持提交歷史的簡潔:當我們在github上修復別人專案的bug時,我們首先在自己的分支裡開發,當開發完成後,你需要將你的程式碼變基到origin/master上,然後再向主專案提交修改。這樣的話,該專案的維護者就不再需要進行整合工作,而是快速合併即可。
變基的風險
使用變基的時候一定要記住一條規則:不要對在你的倉庫外有副本的分支執行變基。
變基操作本質上是丟棄一些現有的提交,然後相應的建一些內容一樣但實際不同的提交。如果你將提交推送到遠端倉庫上,而其他人也從該倉庫拉取提交併基於你的分支建立了新的分支做後續工作,這個時候你用git rebase命令重新整理了提交再此推送,其他人不得不再次將它們手頭的工作與你的提交進行整合,如果他們還要拉去並整合他們修改過的提交,整個開發工作就會變得異常的混亂。想想去年美國因為同事頻繁使用git push -f
推送到遠端分支而被同事槍擊的新聞吧,這樣你就能記住這條規則了。
相關文章
- git 入門教程之變基合併Git
- Git,互動式變基,合併多個commitGitMIT
- 【BIM】基於BIMFACE的空間拆分與合併
- 賬戶變動合併提交方案
- 生成表格與合併表格
- OceanBase子表分裂與合併
- Hive列合併與元素蒐集Hive
- TypeScript基礎(一)——交替合併字串TypeScript字串
- Hbase-原理-region合併和hfile的合併(大合併、小合併)
- 資料檔案合併與拆分
- 命令列中的拆分與合併命令列
- Git 分支 - 分支的新建與合併Git
- NumPy 陣列迭代與合併詳解陣列
- 使用TortoiseGit操作分支的建立與合併Git
- 基於代理服務的介面合併方案
- PHP 圖片的合併,微信小程式碼合併,文字合併PHP微信小程式
- 請求合併與拆分在併發場景中應用
- 影片合併分割軟體如何合併影片
- opencv 影像的 ROI、通道的拆分與合併OpenCV
- JS 物件合併與克隆方法的分類與比較JS物件
- 石子合併
- 合併果子
- [非專業翻譯] Mapster - 拷貝與合併
- 前端效能優化 --- 資源合併與壓縮前端優化
- 併發與多執行緒基礎執行緒
- 圖片合併成PDF,兩個PDF的合併
- 【java】Aspose.Words 合併單元格2種情況(橫向合併,縱向合併)Java
- ffmpeg合併影片
- 區間合併
- PHP合併PDFPHP
- 合併區間
- git合併分支Git
- hbase region 合併
- mysql 索引合併MySql索引
- AUTOCAD——合併命令
- RxJava 合併操作RxJava
- 合併陣列陣列
- 合併查詢