首頁 > 農業

git如何選擇性合併分支?

由 碼農公園1號門 發表于 農業2021-05-17

簡介wangbo@wangbo-VirtualBox:~testgit-demo$ git rebase ——continueApplying: add blank line執行完成以後我們看看分支的時間線形態:重點來了,我們發現 git

git如何選擇性合併

分支就是暫時從主線程式碼離開,去專注於開發一個新特性或者解決一個小 bug,git 建立和切換分支都能在瞬間完成,預設的 git 倉庫,輸入 git branch 可以看到只有一個 master 分支,通常這就是主分支。

wangbo@wangbo-VirtualBox:~/test/git-demo$ git branch* master

假設現在需要開發一個列印的新特功能,分支名稱為 feature_print,從 master 分支離開去新的分支有幾個寫法:

1。 git branch feature_print(或 git branch feature_print master ) && git checkout feature_print(或 git switch feature_print)

2。 git checkout -b feature_print(或 git checkout -b feature_print master)

3。 git switch -c feature_print (或 git switch -c feature_print master)

其中 git switch 是新版本的 git 命令,以前的章節講過 git checkout 用來恢復檔案,checkout 本身是簽出檔案的意思,用來切換分支語義上有點模糊,後連就增加了語義更加明確的 switch 切換,隨時都可以使用 git branch 檢視分支的情況,前面的 * 表示你當前所在的分支。

wangbo@wangbo-VirtualBox:~/test/git-demo$ git branch* feature_print  master

在新的分支下,可以專注於開發列印的功能了,我們新增一個 print。c 檔案提交,從提交日誌上看,工作成果是放到了 feature_print 分支上。

大白話 git 教程-08-分支合併和典型用法

如果想知道兩個分支的變化,可以使用 git diff 分支1 分支2,比如輸入 git diff master feature_print,由於我們當前就在 feature_print 分支上,可以簡化輸入 git diff master 來和 master 分支相比較。

大白話 git 教程-08-分支合併和典型用法

可以非常清楚的看到了新增的列印相關的程式碼,假設列印的功能已經開發完成了,我們需要希望在主幹分支上合併新的列印功能的程式碼,以便下一步的開發或是釋出,首先切換到主分支:

1。 git switch master

2。 git checkout master

wangbo@wangbo-VirtualBox:~/test/git-demo$ git switch masterSwitched to branch ‘master’wangbo@wangbo-VirtualBox:~/test/git-demo$ git branch  feature_print* master

git branch 命令清楚的顯示當前已經在 master 主幹分支了,現在需要將 feature_print 分支的程式碼合併到 master 分支上,怎麼做呢? 有 2 種做法,我們分別來介紹。

第一種: 使用 git merge 指令,預設如果執行 git merge feature_print 就可以,但是這樣不會為這次合併單獨生成一個 commit 節點,為了以後能清楚的看到分支合併的情況,通常會使用一個引數 ——no-ff,也就是使用 git merge ——no-ff feature_print 來執行。

大白話 git 教程-08-分支合併和典型用法

合併完成以後,提示訊息如下:

wangbo@wangbo-VirtualBox:~/test/git-demo$ git merge ——no-ff feature_printMerge made by the ‘recursive’ strategy。 print。c | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 print。c

透過 tig 看看分支時間線的形態,可以清楚的看到了,master 分支合併了 feature_print 分支的情況。

大白話 git 教程-08-分支合併和典型用法

通常很多功能分支或者解決 bug 的分支,我們在合併完成以後,會將它刪除,因為它的程式碼已經被合併到主分支了,以後需要繼續開發或者有 bug 的話可以從主分支再次建立單獨的分支來解決。使用 git branch -d feature_print 來刪除列印功能的分支,使用 tig 檢視一下分支時間線的形態,發現feature_print 分支這個名稱不會再顯示了,但是形態並沒有變化,依靠提交的註釋能夠清楚的知道了合併了 feature_print 分支的程式碼。

大白話 git 教程-08-分支合併和典型用法

分支的時間線形態非常重要,尤其是我們需要回到歷史的時候,實際工作的時候,可能同時有多個分支存在,如果合併後的時間線形態雜亂無章,對我們程式碼的維護會產生非常大的副作用。

上面是理想的 merge 合併的情況,處於 master 分支和 feature_print 分支的程式碼完全是新增的包含關係,也就是沒有修改到重疊的程式碼,如果合併feature_print 分支的時候,master 分支上的列印功能也被修改了,那麼合併就會產生衝突,而 git merge 會直接合並檔案,並且報告衝突的程式碼情況,這時候需要手動修改檔案解決衝突,完成後再次做一次提交。如下圖,master 和 feature_print 都同時修改了同一行程式碼,在 master 分支上檢視區別:

大白話 git 教程-08-分支合併和典型用法

執行 git merge ——no-ff feature_print 後顯示:

大白話 git 教程-08-分支合併和典型用法

提示有衝突嘗試自動合併,但是自動合併失敗了(如果沒有修改到重疊的程式碼 git 可以自動化的成功合併),需要手動解決檔案的差異了,因為 git 並不知道保留哪個分支的程式碼才是需要保留的,開啟檔案發現長這個樣子,用 === 分割了 2 個分支的程式碼,使用 <<<< 表示當前工作分支, >>>> 表示了被合併的 feature_print 分支。

大白話 git 教程-08-分支合併和典型用法

我們覺得 master 分支新增的換行和 feature_print 分支的 ok 文字都是需要保留的,修改檔案如下:

大白話 git 教程-08-分支合併和典型用法

使用 git status 檢視一下倉庫的狀態:

wangbo@wangbo-VirtualBox:~/test/git-demo$ git statusOn branch masterYou have unmerged paths。  (fix conflicts and run “git commit”)  (use “git merge ——abort” to abort the merge)Unmerged paths:  (use “git add 。。。” to mark resolution) both modified:   print。cno changes added to commit (use “git add” and/or “git commit -a”)

顯示 print。c 的檔案狀態是 both modified,需要暫存提交,執行 git add 。 && git commit -m ‘fix print text’ 後使用 tig 檢視分支形態:

大白話 git 教程-08-分支合併和典型用法

所以 git merge 的缺點就是有衝突的時候,所有檔案都被合併了,沒有給使用者留機會做出選擇,並且單獨生成了一個合併的 commit 提交節點(顯示 M)。如果希望漸進式的合併,就需要使用第二種方法。

第二種: 使用 git rebase 命令,切換到 master 分支上,執行 git rebase feature_print 合併,如果沒有衝突,直接合併成功是最理想的情況,有衝突的情況如下:

大白話 git 教程-08-分支合併和典型用法

git 給了我們三種選擇:

1。 自己解決檔案衝突後執行 git rebase ——continue 後繼續嘗試後面的合併

2。 執行 git rebase ——skip 直接跳過後繼續嘗試合併,回頭再來收拾殘局

3。 執行 git rebase ——abort 放棄本次合併,程式碼切換到 master 為合併前的狀態

這時候我們可以開啟檔案 print。c,修復檔案衝突,執行下面 2 個命令繼續合併:

git add 。git rebase ——continue

continue 後 git 會繼續嘗試合併,如果還有檔案衝突,重複執行這個過程,也可以隨時 git rebase ——abort 放棄,不想立刻解決就執行 git rebase ——skip,直到整個合併完成。

wangbo@wangbo-VirtualBox:~/test/git-demo$ git statusrebase in progress; onto 5a8323aYou are currently rebasing branch ‘master’ on ‘5a8323a’。  (fix conflicts and then run “git rebase ——continue”)  (use “git rebase ——skip” to skip this patch)  (use “git rebase ——abort” to check out the original branch)Unmerged paths:  (use “git restore ——staged 。。。” to unstage)  (use “git add 。。。” to mark resolution) both modified:   print。cno changes added to commit (use “git add” and/or “git commit -a”)wangbo@wangbo-VirtualBox:~/test/git-demo$ git add 。wangbo@wangbo-VirtualBox:~/test/git-demo$ git rebase ——continueApplying: add blank line

執行完成以後我們看看分支的時間線形態:

大白話 git 教程-08-分支合併和典型用法

重點來了,我們發現 git rebase 和 git merge 生成的時間線並不相同,merge 保留了提交歷史和操作過程,rebase 去掉了合併過程的提交更加簡潔,但是合併後的 commit 資訊可能需要修改,比如這個例子的 add blank line 已經不能同時表達文字被更新成 ok 的含義了,應該改為 fix print text 可能更合適(取決於你合併到底保留了什麼樣的程式碼)。

merge 和 rebase 如何選擇呢?

1。 如果需要一個乾淨的時間線形態選擇 rebase,如果希望漸進式的合併使用 rebase,可能會需要更新一次 commit 資訊。

2。 如果需要保留完整的歷史記錄使用 merge,有多個檔案衝突的時候可能比較棘手,但是 commit 資訊都會保留下來。

關於 git 分支還有一些命令需要掌握:

1。 檢視所有為合併的分支 git branch ——no-merged

2。 檢視合併過的分時 git branch ——merged

3。 強行刪除分支 git branch -D 分支名稱

4。 而 git branch -v 可檢視每個分支最後一次提交的情況

特別說明,一般我們不會在 master 分支上直接修改程式碼,本章節為了簡化說明問題(避免太多的分支擾亂你的視線),在 master 上直接修改了程式碼,第 12 節學習科學的分支開發模型,也就是如何更加合理規範的使用 git 分支。

Tags:gitprint分支featuremaster