Bo2SS

Bo2SS

4 Git多人單分支集成協作時的常見場景

場景:模擬兩個人維護同一個 Git 分支。

先在Github 倉庫裡基於 master 創建一個新的分支 feature/add_git_cmds ,點擊 Create branch 即可:

image

創建成功後,回到本地,在本地拉取兩個庫,模擬兩個人開發。

image

別忘了給兩個人設置不同的 user~

我們先看一下 Git 倉庫的全局配置( --global ):

image

我們讓 git_learning_A 使用默認的全局用戶配置,給 git_learning_B 設置局部用戶配置( --local ,優先級高於全局配置):

image

(配置可參考1 Git 基礎 --03 | 使用 git 之前需要做的最小配置

最後在兩個本地倉庫裡,都基於遠端feature/add_git_cmds 分支創建相關聯的本地分支。

命令: git checkout -b feature/add_git_cmds origin/feature/add_git_cmds ,該命令會基於後面的遠端分支創建名為前者的本地分支,跟蹤遠端分支,並切換到新建的分支上來。

image

在兩個本地倉庫上都進行同樣的操作。

至此,模擬了兩個人同一倉庫的同一分支上開發的場景,接下來針對 5 種情況一一進行試驗🧪吧!

34 | 不同人修改了不同文件如何處理?#

結論先行:直接 merge 即可。

git_learning_A:修改 readme.md 文件,並推送到遠端。

image

git push 很順利。

查看遠端倉庫:

image

查看提交記錄的作者,對應 git_learning_A 使用的全局用戶配置:

image


git_learning_B:修改另一個文件 xxx/css.x,推送之前需要先拉取,再嘗試推送。

先修改文件,假設直接推送,看看會發生什麼?

image

前面的步驟和 git_learning_A 的類似,但是在 git push 時發生了意外,是不是似曾相識?報錯和上一章中提到的一模一樣:3 Git 與 GitHub 的簡單同步 --33 | 把本地倉庫同步到 GitHub

❌: git push -f 強行推送。

✅:先拉取,再合併,再推送。

git fetch

image

可以看到最新 commit 的 hash 值從 d7d648a 更新到了 192a3b3。

在分支說明上發現當前分支和遠端分支的狀態為:ahead 1(本地有更新我沒有推送到遠端), behind 1(遠端有更新我沒有合入到本地),那麼先進行合入。

git merge origin/feature/add_git_cmds

執行後會彈出 commit 信息的編輯,默認即可,或適當添加說明。

image

:wq 保存退出,可以看到 merge 成功以及修改的記錄。

image

藍線可以看到目前 ahead 2,也就本地多了兩個 commit,還沒有推送到遠端;

紅框即 ahead 的 2 條 commit 記錄。

這時候查看本地的 readme.md 和 xxx/css.x 文件,都是修改後的樣子,接下來直接 push 即可。

git push

image

推送成功!不同人在不同文件上進行協同辦公還是很方便的,所以協同辦公時以這種方式進行是不是很高效呢?再看看其他情況吧~

35 | 不同人修改了同文件的不同區域如何處理?#

結論先行:直接 merge 即可。

⚠️:先創造有不同區域的環境,在任一倉庫的 readme.md 文件中添加多行,再推送,兩個倉庫保持同步。readme.md 文件修改如下:

image

因為上一節中的文件都是 1 行,無法做到修改不同區域。


git_learning_A:修改 readme.md 的第 4 行,直接推送。

image


git_learning_B:修改 readme.md 的第 7 行,先 pull,再推送。

image

git pull 過程中,彈出 commit 信息的編輯後, :wq 保存退出,即合併成功。

⚠️:這裡直接 pull 會提示,沒有明確的 pull 策略是不推薦的。

1)可以手動配置 pull 的默認策略

2)或者在 git pull 命令後加入選項,如 --rebase--no-rebase--ff-only

3)或者使用 git fetch 後,再選擇合併策略


這時候查看本地的 readme.md 文件,符合預期,接下來直接 push 即可:

image

這種方式下的協同辦公也是比較順利的,Git 有能力自動進行合併~

36 | 不同人修改了同文件的同一区域如何处理?#

結論先行:在 merge 時會出現衝突,需要自行解決。

git_learning_A:修改 readme.md 的第 1 行,直接推送。

image

⚠️:別忘了先進行 git pull ,因為剛才 git_learning_B 做的更新還沒有同步。


git_learning_B:同樣修改 readme.md 的第 1 行,先 pull,手動解決衝突,再推送。

image

這次我們 git pull 帶了選項 --no-rebase ,表示通過 merge 的方式進行拉取。

緊接著, 產生衝突了,需要我們自己解決衝突,再進行提交。

vim readme.md ,打開產生衝突的文件 :

image

產生衝突的位置有明顯的標記,HEAD 與 === 之間代表本地的代碼,hash 值與 === 之間代表合入的代碼。

我們需要修改這部分代碼,並刪去這些特殊標記,可以這樣修改:(實際開發中,記得和相關人員交流後再進行修改❗️)

image

:wq 保存退出後,通過 git status 查看倉庫狀態:

image

紅框中,上者表示進行合併;下者則表示取消合併,回到合併前的狀態。

這裡我們實踐一下上者。⚠️:此時修改還在工作區,我們需要先添加到暫存區,再提交。

先進行添加和提交,再進行推送:

image

PS: -am 包含了添加和提交兩個操作。


這次我們發現 Git 沒有那麼智能,也不需要那麼智能,因為它肯定不知道誰的代碼應該被保留。

37 | 同時變更了文件名和文件內容如何處理?#

結論先行:直接 merge 即可。

git_learning_A:修改 xxx/css.x 的文件名為 xxx/css2.x。

image

還記得 git mv 命令嗎?可跳轉1 Git 基礎 --06 | 給文件重命名的簡便方法回顧。


git_learning_B:修改 xxx/css.x 中的內容(並不知道文件名已經修改)。

image

Cool~Git 可以自動解決這樣的問題。查看合併情況:

image

可以看到不僅文件名修改過來了,文件裡的修改也被保留了。

本質上,這裡修改的是同文件的不同區域~

38 | 把同一文件改成了不同的文件名如何處理?#

結論先行:在 merge 時會出現衝突,需要自行解決。

git_learning_A:修改 xxx/css2.x 的文件名為 xxx/cssA.x。

image


git_learning_B:修改 xxx/css2.x 的文件名為 xxx/cssB.x。(並不知道文件名已經修改)。

image

發生衝突了~

查看文件情況:

image

可以看到 Git 的做法是同時保留了兩個修改了文件名的文件,並且兩個文件的內容沒有區別。

通過 git status 也很清晰的告訴了我們文件名變更的情況,以及可以怎麼做。

image

git rm 不需要的文件, git add 最後決定要的文件,提交,推送,即可!

看了這幾種場景下的 Git 協同辦公,是不是對解決衝突不再恐懼了呢?

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。