1. 程式人生 > >git分支管理--rebase&merge詳解

git分支管理--rebase&merge詳解

[TOC] - 在平時開發中我們因為版本管理的因素,我們可能同時開發多個功能。我們是通過分支來管理的。不同的分支對應不同的功能不同的時間上線。 # 分支合併 ## git merge --squash [分支名] - git merge --squash 和 git merge是不同的。後者是直接將其他的提交記錄合併進來。而前者是內容的合併。 - 這裡的分支名可以是遠端的也可以是本地的分支 + origin dev : 遠端dev + dev : 本地dev - 現在我們dev分支上開發了某個功能。並提交至遠端倉庫中。我們現在打算合入master分支中。 - dev 和 master 兩個分支已經很久沒有合併了。此時合併可能會有衝突 - dev程式碼提交遠端 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090320345-1823918878.jpg) - 現在我們在另外一臺機器上進行遠端分支合併請求 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090320553-724682210.jpg) - 執行完squash我們看到有兩個檔案衝突。我們需要解決衝突。我們通過`git status`也可以看到這兩個檔案衝突 `both modified` ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090320762-1066776894.jpg) - 解決衝突也很方便,我們只需要去認為分析兩個檔案內容取捨問題,然後進行重新提交就行了。比如說現在分析20190423trace.txt檔案 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090320933-688031712.jpg) - 加入我們認為dev提交過來的只有hello zfxx是有效的。那麼我們留下他就行了。 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090321134-436769594.jpg) - 然後一系列提交推送就行了 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090321360-1474372333.jpg) - 提交完之後我們先看看master上日誌記錄 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090321651-239913984.jpg) - 然後看看另外一臺機器的dev提交記錄 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090321884-151091866.jpg) - 我們發現dev提交的test甚至之前的commit並沒有在master裡面。這就是squash與merge的不同之處了 - squash是將其他分支內容合併和重新進行一次提交封裝。這樣方便我們對主分支的管理。dev分支開發可能會隨心所欲的進行提交已經對提交日誌的細小記錄。但是對於主分支根本不關心這些或者需要進行一些提交資訊的規則定義。這時候我們可以squash先合併內容然後在重新一次性提交 ### 注意點 - squash 後當前分支執行git status 會看到合併過來的檔案在暫存區中我們需要commit 、 push 到遠端 ## git rebase [分支名] - 我們先基於master分支切除一個名為rebase_dev分支 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090322116-1001707455.jpg) ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090322305-153048028.jpg) - 此時rebase_dev 和 master是完全一樣的。 - 現在我們在rebase_dev 分支上修改一個檔案並commit。我們在看看commit log如何 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090322572-520299073.jpg) - 我們的rebase_dev分支的head節點已經走到了054de46這個commit了。這個commit就是我們剛才提交的commit - 8ad6924這個commit 後面括號內容表示是基於遠端master、遠端head、本地master為基點的。這也能說明現在本地master和遠端master一致。且遠端master在最新節點上。 - 此時我們在本地master提交內容並進行推送再看看log ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090322886-946670507.jpg) - 這個時候master和rebase_dev兩個分支分別向前推進了2步。 - 我們先來整理下master推進了兩個commit. rebase_dev推進了兩個分支 ### git rebase - git rebase 命令實際上是將rebase_dev分支快取到.git/rebase目錄下 - 然後將rebase_dev基點即8ad6924移動到當前master的head節點。 - 然後將.git/rebase檔案中的兩個commit分別更新到rebase_dev上。所以這裡涉及到更新是會發生衝突。我們上面rebase_dev推進了兩個commit就會進行兩次更新。如果遇到衝突git rebase就會停止操作。 - 我們此時需要解決衝突並將檔案重新加入快取區git add [檔名]. - 然後執行git rebase --continue ### git rebase --abort - 在上面我們何如了第一個commit後,突然不想rebase此次操作了。我們可以git rebase --abort停止。此時當前分支回到rebase之前狀態。即基點在8ad6924。且自己的兩個commit還在。 - 現在我們執行在rebase_dev分支上執行git rebase master 後看看效果 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090323172-1638243180.jpg) - 圖中大意是重新設定基點,並將儲存在./git/rebase中的patch進行新增到當前分支上。 - 首先合併第一個commit patch, 裡面涉及改動了trace.txt。我們有三種方式進行合併。git自動已經幫我們合併了,就是我們常見的衝突形式。我們也可以通過`git am --show-current-patch`檢視衝突細節。當我們已經認定解決衝突後我們git add 重新新增或者git rm刪除檔案。然後執行`git rebase --continue` 進行放行至下一個commit。或者執行`git rebase --skip`跳過當前的commit.實際上就是丟棄該commit。或者執行`git rebase --abort`停止當前rebase回到之前狀態 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090323368-2132710106.jpg) - skip之後我們看到applying rebase V2 ,說明開始何如第二個patch 即commit了。此時也出現了衝突。這個時候第一個commit已經被我們拋棄了。不會對我們產生影響的。 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090323561-192297380.jpg) - 我們執行`git rebase --abort`停止了當前的基點改變。我們檢視原始檔發現沒有衝突也沒有被主分支內容改動。 - 下面我們git rebase master將內容合併進來。 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090323746-1007233045.jpg) - 我們一頓操作下來最後提示我們合併成功了。只是我在處理合並的時候將自動合併資訊留下來了。我們看看最終的檔案 ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090323971-2101575530.jpg) ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090324234-659049741.jpg) - 我們檢視log發現。master日誌在rebase_dev之前。且rebase_dev兩個commit id發生了變化。這也說明我們基點移動到master上且rebase_dev的commmit是重新新增到rebase_dev分支上的。 ### git rebase -i - 這個時候我看了rebase_dev和master的四個commit 有點不順眼,我們也可以把這四個commit合併。 - 執行`git rebase -i HEAD~4` ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090324563-542905115.jpg) - 彈出的視窗我們可以發現前四行使我們的commit倒敘排列的。下面也有關於引數的解釋,將該四個commit合併到最後一個commit上。及702de33 。 看看常用的兩個。後面的我也不明白後面再補補吧 |縮寫|關鍵字|作用| |---|---|---| |p|pick|use commit 使用該提交,如上所示四個都pick,即沒有合併| |r|reword|使用該commit,但是從新編寫提交資訊| ![](https://img2020.cnblogs.com/blog/1002125/202103/1002125-20210315090324766-1271275932.jpg) - 我們發現四條commit合併成一條了。這樣有利於我們對commit提交資訊的管理。 ## git merge [分支名] - git merge 到這裡其實已經沒啥好說的。上面的對比已經梳理完畢了。主要和git rebase的區別。git merge 適合主分支