Git 回复合併提交指南:範例說明

我們可以通過合並有問題的代碼來妥協一個應用程序,這可能是因為意外地將未完成的代碼集成到主分支,或是忽略了自動測試中溜過的關鍵錯誤。

在本文中,我將指導您使用git revert來安全地撤消合並,確保提交歷史保持完整並保護項目的完整性。

git revert如何工作》

我們可以將git revert視為Git的撤消命令版本。然而,git revert命令不會刪除提交或跳回到分支的前一個狀態。相反,它會創建一個新的提交,以撤消特定提交的更改。

撤消帶有哈希值的提交<commit_hash>的語法是:

git revert <commit_hash>

我們可以使用git log命令一起列出提交及其哈希標識符。git log的輸出會從最新的提交列出到最舊的提交,如下所示:

例如,要撤消實現減法函數的提交,我們將使用以下命令:

git revert 7ba24a3e62d4d37182428ccfaa070baa222b1151

使用git revert,我們可以撤消特定提交的更改,而不影響提交歷史。

請注意git revert並不是神奇的,並且根據提交歷史,它可能會導致需要手動解決的衝突。

使用git revert優於手動更改的優勢

如果我們可能需要手動解決衝突,為什麼git revert還是有用的呢?難道直接手動撤銷更改不是更簡單嗎?我們來看看它的優勢:

  • 保留歷史:git revert會創造一個新的提交,這個提交會撤銷指定提交的更改,同時保留整個提交歷史。這有助於保持更改和撤銷的透明歷史。
  • 原子性撤銷:它確保撤銷是原子性和一致的。當我們手動刪除並提交更改時,存在人為錯誤的風險。
  • 衝突感知:它確保如果我們有依賴原始提交的任何整合或更改,我們會通過衝突得到警示。這可能看起來不方便,但它能夠防止意外的副作用。
  • 元數據:由git revert創建的新的提交包括了元數據和提交信息,這些信息會描述被撤銷的内容,有助於未來的理解。沒有git revert,這種上下文可能會丟失。

在不同情況下撤銷合併

在這一部分,我們學習如何撤銷合併。為了舉例,我們假設我們正在將名為feature的分支合併到main分支,並從main分支執行命令:

git merge feature

我們在這裡學到的可以應用於任何兩個分支,只需適當地替換分支名稱即可。

將一個沒有相關提交的合並回退

《git merge》命令不總是創建一個新的提交。只有當《main》分支與《feature》分支分歧時,才會創建提交。因為《git revert》需要一個提交來進行操作,所以我們在這種情況下無法使用它。

當在《main》上創建了新的提交,而這些提交不是《feature》分支的祖先時,《main》和《feature》分支會分歧。換句話說,在創建《feature》後,《main》上創建了新的提交。

如果分支沒有分歧,當我們在《main》分支上運行命令《git merge feature》時,Git會使用快進來合並。這意味著它將《main》分支的《HEAD》移動到《feature》分支的《HEAD》。

我們可以通過查看《git merge》的结果來觀察這一點:

要撤銷這樣的合並,我們只需將《main》分支的《HEAD》移動回原位。為此,我們:

  1. 使用《git reflog》來识别前一個《HEAD》
  2. 使用 git reset --hard <previous_head>HEAD 重置為前一個版本,將 <previous_head> 替換為前一個 HEAD

git reflog 的輸出將會類似這樣:

我們可以通過查看寫有 “checkout: moving from feature to main” 的行來確定前一個 HEAD(它寫著 featuremain,因為這是我們分支的名稱)。

在這個例子中,前一個頭是 fe59838。要將主分支的 HEAD 移回這個位置並撤銷合併,我們可以使用以下命令:

git reset --hard fe59838

撤銷具有相關提交的合併

如果 main 分支和 feature 分支已經分歧,那麼當我們合併兩個分支時,會創建一個新的提交,這個提交被稱為合併提交。

合併提交將一個分支的更改應用到另一個分支上。在這個例子中,將 feature 分支的更改應用到 main 分支。

要撤銷 main 分支上的更改,我們在合併提交上使用 git revert。這將創建一個新的提交,撤銷合併帶到 main 分支的更改,從而將主分支的狀態恢復到合併前的狀態。

首先,我們需要確定合併提交的哈希值。我們可以使用 git log 指令:

因為合併提交有兩個父代,所以 git revert 的語法略有不同。我們需要使用 -m 1 選項來指定我們想對 main 分支的更改進行回退:

git revert -m 1 b8dab2c8611e324ed0d273133987415350e6d10d

當回退提交時的衝突解決

有時在回退提交時可能會出現衝突,特別是如果被回退的提交與代碼庫中後續的更改發生衝突。在這種情況下:

  1. Git 將中斷回退:我們需要手動解決衝突。Git 將標記發生衝突的文件並要求介入。
  2. 解決衝突:我們打開每個發生衝突的文件,解決 Git 標記的衝突,並保存更改。
  3. 將解決的文件添加到索引:git add <file-path>
  4. 繼續回退: git revert --continue

結論

使用 git revert 來撤消合併提交可以確保每個更改和糾正都記錄在提交歷史中。

此外,了解在適當的情況下使用 git resetgit revert 的差異,可以讓我們做出更好的決策,尤其是在考慮合作工作流程或僅限本地變更的情況下。

您可以在下方的常見問題解答部分閱讀更多有關這個主題的內容。如果您想進一步學習 Git,我推薦以下資源:

Source:
https://www.datacamp.com/tutorial/git-revert-merge