簡體   English   中英

使用單獨的 PR 進行部署推出和回滾:未按預期工作

[英]Using separate PRs for deployment rollout and rollback: not working as expected

我們有這樣的場景,對於 Prod 中的任何應用程序配置更改,我們創建 2 個 PR:1 個用於實現,另一個用於回滾。 我們提前創建這些。 然后,我們對它們進行審查和批准。

window 變更期間沒有人審核PR。所以,我們必須提前創建PR並獲得批准。

比方說,主分支包含一個配置文件 app.properties 具有以下 2 個屬性:test.base.certificate=abcd
測試.base.key=abcd

我們創建實施 PR 如下:

  1. 從 master 創建實現分支。
  2. 使用新值更新屬性,如下所示:
    測試.base.certificate=efgh
    測試.base.key=efgh
  3. 提交更改。
  4. 將更改推送到遠程。

我們創建回滾 PR 如下:

  1. 從 master 創建回滾分支。
  2. 使用新值更新屬性,如下所示。
    測試.base.certificate=efgh
    測試.base.key=efgh
  3. 提交更改。
  4. 恢復到舊的屬性值:
    測試.base.certificate=abcd
    測試.base.key=abcd
  5. 提交更改。
  6. 將更改推送到遠程。

回滾 PR 不會顯示 app.properties 中的任何差異。 這是因為在第 2 次提交后,master 和 rollback 分支中的文件沒有區別。

在產品變更 window 期間,我們首先合並實施 PR 和測試。 如果在測試期間出現任何問題,我們將合並回滾 PR 以還原更改。

我最近不得不第一次執行回滾活動。 合並回滾 PR 后,我觀察到 master 分支中的 app.properties 仍然具有新的屬性值:
測試.base.certificate=efgh
測試.base.key=efgh

在此處輸入圖像描述

從高層次上看,這種方法應該有效。 有誰知道為什么它不起作用? 在這種情況下如何創建回滾 PR?

PS - 我知道 git 還原。 但是,我很好奇為什么上述方法不起作用。

提前致謝!

從高層次上看,這種方法應該有效。

我的猜測是您認為git merge rollback重放了兩個唯一的提交以rollback到當前分支 ( main )。 如果 git 這樣做了,第一次提交將不會做任何事情,因為main已經有了那個改變。 第二次提交會將屬性文件恢復到其舊的 state。這是您所期望的。 但這不是git merge的工作方式。

git merge不重放提交

git merge默認執行的操作稱為三向合並。 正如另一個問題的答案中所解釋的:

您最好尋找 3 路合並算法的描述。 高級描述將 go 是這樣的:

  1. 找到一個合適的合並基礎B - 文件的一個版本,它是兩個新版本( XY )的祖先,通常是最近的這樣的基礎(盡管在某些情況下它必須進一步返回 go ,這是git默認recursive合並的特性之一)
  2. 執行XBYB的差異。
  3. 遍歷兩個差異中標識的更改塊。 如果雙方在同一地點引入相同的變化,則接受其中一個; 如果一個人引入了變化而另一個人不理會那個區域,則在決賽中引入變化; 如果兩者都在一個地方引入了變化,但它們不匹配,則將沖突標記為手動解決。

git 合並文檔的解釋不太詳細,但准確解釋了讓您感到困惑的行為:

對於使用三向合並的策略(包括默認的 ort),如果在兩個分支上都進行了更改,但后來在其中一個分支上恢復,則該更改將出現在合並結果中; 有些人發現這種行為令人困惑。 發生這種情況是因為在執行合並時只考慮頭部和合並基礎,而不考慮單個提交。 因此,合並算法將還原的更改視為根本沒有更改,而是替換更改后的版本。

我相信這樣做的原因有幾個:

  • 99% 的時間,合並是關於平行的開發線,處理不同的事情,你想合並這兩個事情。 因此,您不希望在默認情況下優先考慮在一個分支上所做的更改。 如果rollback是一個功能分支,您不會希望它只是覆蓋impl所做的更改。
  • 99.9% 當開發人員在一個分支上進行更改並隨后撤消它時,其意圖是“假裝我從未那樣做”。 所以大多數時候讓一些人感到困惑的行為確實是人們所期望的。
  • 您可以通過指定不同的合並策略來實現其他行為,例如git merge -s ort -X theirs rollaback ,或使用其他命令,如cherry-pickrebase ,具體取決於您的確切需求。

解決方案 #1: git revert

修復rollback分支並使用git revert

git checkout main
git revert main..IMPL

這是最簡單的。

解決方案 #2:來自impl的分支rollback

如果由於某種原因你必須通過 PR 來做,或者出於任何原因必須有一個rollback分支,那么分支rollback impl ,而不是master

git checkout impl
git checkout -b rollback
git revert main..IMPL

它看起來像這樣:

1 main
 \
  2 impl
   \ 
    3 rollback

合並impl以部署:

1---4 main
 \ /
  2 impl
   \
    3 rollback

合並rollback到回滾:

1---4-------5 main
 \ /       /
  2 impl  /
   \     /
    3----  rollback

不僅app.properties會像您預期的那樣恢復,git 歷史更簡單並且更好地表示發生了什么。 將其與您當前方法的結果進行比較,該方法具有兩個相同的冗余提交(2 和 3),並且在開始時誤導性地分成三個分支。

  2  rollout
 / \
1---5---6 main
 \     /
  3---4  rollback

如果允許fast-forward合並,它看起來會更好。

1 main
 \
  2 impl
   \ 
    3 rollback

部署最終是這樣的:

1---2 main, impl
     \ 
      3 rollback

並像這樣回滾:

    impl 
1---2---3 main, rollback

暫無
暫無

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

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