簡體   English   中英

合並時避免在另一個Git分支中恢復提交的影響

[英]Avoid the effects of a revert commit in another Git branch while merging

使用git流程。 我們有一個不熟悉Git的同事昨天意外地合並了發展成師。

開發有很多功能,我們的下一個版本將啟動,需要恢復合並。 這創建了一個撤消所有更改的提交。 當我們將master合並回develop時,revert commit會刪除我們的功能生成的代碼。

在保留新功能的同時,能夠與master的修補程序同步開發的最佳方法是什么?

- 編輯 - 只是為了澄清,恢復是一個恢復 IE git revert -m 1 <sha> ,因為提交已經被推送到遠程存儲庫。

發布之后,我已經提出了一個可能的解決方案,通過分支主控並恢復還原,但是我很好奇是否有其他可能性可以最小化沖突。

選項1:硬重置和強制推動

如果這是可以做到的非快進強制更新到你的master分支在上游資源庫,然后代替恢復的合並develop成為master ,你可以簡單地做一個硬復位master

# On master branch, do a hard reset back to the commit before the merge
git reset --hard <commit of master before the merge>

# Force push to upstream ONLY IF IT'S OK WITH OTHER DEVELOPERS
git push <remote> master --force

執行硬重置和強制推送的一個可能的缺點是,如果其他開發人員已經完成了合並提交的工作(即已經在其上進行了提交),那么他們將需要在頂部重做相同的工作master的重置頭。 這可能是也可能不是他們的困難/昂貴的任務。

選項2:還原還原

我用快速測試回購測試了這個。 我必須強調它可能會起作用 ,我並非100%確信沒有任何我不考慮的情況。 因此,請務必先在本地使用您的repo的備份克隆進行測試。 如果您選擇在實際回購中使用此產品,請自行承擔風險。

此外,這可能不是最簡單/最簡單的解決方案。 然而,它優於硬重置選項的優點是它不會迫使開發人員必須在重置master分支之上重做工作。

好了,所有這一切的出路,有一兩件事你可以嘗試做的是合並masterdevelop ,然后恢復從合並的復歸developmaster ,然后合並developmaster ,當你准備好了。 在命令中:

# Coworker accidentally merges develop into master before it's ready
git merge --no-ff develop

# You revert the merge in the master branch (this creates commit "ABCDEFG"
git revert -m 1 <sha of merge commit>

# You want to merge fixes from master into develop
git checkout develop
git merge --no-ff master

# But now all that work in develop is reverted, so revert the revert "ABCDEFG"
git revert ABCDEFG

# When you're ready to merge develop into master...
git checkout master
git merge --no-ff develop

這是我用來在測試倉庫中測試它的一系列命令:

mkdir practice
cd practice/
git init

touch readme.txt
git add practice.txt
git commit -m "Add practice.txt"

git checkout -b develop

touch feature1.txt
git add feature1.txt
git commit -m "Add feature 1"

touch feature2.txt
git add feature2.txt
git commit -m "Add feature 2"

git checkout master

touch hotfix1.txt
git add hotfix1.txt
git commit -m "Fix issue 1"

git merge --no-ff develop

# Creates commit "ABCDEFG" that reverts the merge
git revert -m 1 head
git checkout develop
git merge --no-ff master
git revert ABCDEFG
git checkout master
git merge --no-ff develop

您可以在git revert官方Linux Kernel Git文檔中閱讀有關“還原恢復”技術的更多信息:

-m parent-number

--mainline parent-number

通常,您無法還原合並,因為您不知道合並的哪一側應被視為主線。 此選項指定主線的父編號(從1開始),並允許恢復相對於指定父級的更改。

還原合並提交聲明您永遠不會希望合並帶來的樹更改。 因此,以后的合並只會帶來由不是先前還原的合並的祖先的提交引入的樹更改。 這可能是也可能不是你想要的。

有關詳細信息,請參閱revert-a-faulty-merge How-To

如果您完全想要了解這種技術是如何工作的,那么強烈建議如何恢復錯誤合並的鏈接,這並不難理解,實際上它有點有趣且令人着迷。

我的團隊發生了類似的事情。 我實際上已經有一個相對簡單的解決方案,我只找到了這個帖子,因為我正在研究防止這種情況發生的方法(仍然沒有解決方案)。

這是我如何修復它,假設子分支(“develop”)在與master“bad”merge(commit M2)之前被更新(commit M1):

問題狀態

           ... <-- Work after revert that needs merged to develop
            |
            R  <-- Revert Bad Merge
            |
            A  <-- Commits after merge,
            |    /   but before revert 
           ... </    and needs merged to develop
            |
           M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

步驟1

# Get latest from both parent and child branches locally

git checkout master
git pull
git checkout develop
git pull


# Merge all code from before revert in master branch to develop
# (not necessary if "bad" merge into master was immediately reverted)

git merge A

第1步之后的狀態:

           ... <-- Work after revert that needs merged to develop
   M3       |
   | \____  R  <-- Revert Bad Merge
   |      \ |
   |        A  <-- Commits after merge,
   |        |    /   but before revert
   |       ... </    and needs merged to develop
   |        |
   |       M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

第2步 - 重要部分!

# Use "ours" strategy to merge revert commit to develop.
# This doesn't change any files in develop. 
# It simplly tells git that we've already accounted for that change.

git merge R -s ours

在第2步之后說明

   M4
   | \____  ... <-- Work after revert that needs merged to develop
   M3     \ |
   | \____  R  <-- Revert Bad Merge
   |      \ |
   |        A  <-- Commits after merge,
   |        |    /   but before revert
   |       ... </    and needs merged to develop
   |        |
   |       M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

第3步

# Merge as normal, from the tip of master to develop.
# This should now be an "easy" merge, with only "real" conflicts.
#  (Those that have changed in both branches)
#
# Note: I've had issues using origin master to merge from latest on remote, 
#   so instead I just ensure I've pulled the latest from master locally and 
#   merge from there

git merge master

在第3步之后說明

   M5
   | \_____
   M4      \
   | \____  ... <-- Work after revert that needs merged to develop
   M3     \ |
   | \____  R  <-- Revert Bad Merge
   |      \ |
   |        A  <-- Commits after merge,
   |        |    /   but before revert
   |       ... </    and needs merged to develop
   |        |
   |       M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

現在,使用最新的master更新了develop ,而無需解決重復或無意義的合並沖突。 未來的合並也將表現得正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM