簡體   English   中英

如何合並/挑選單個提交

[英]How to merge/cherry-pick a single commit

我有一個像這樣的分支結構的項目(基於 GitHub)

master:   A - B - C - D
            \
release:      W - X - M
                    /
bugfix:       Y - Z

因此,一旦bugfix被合並, release將有A - W - X - Y - Z - M ,其中 M 是合並提交, Y & Z是來自bugfix分支的原始提交。 到目前為止一切都很正常。

現在,我想做的是讓MYZ一起進入master 但這里有一個警告——我希望WX在 master 中。 為什么? WX是類似“Bump to our hotfix release version”的提交,它們在master中沒有位置。 所以最后,我希望master成為A - B - C - D - Y - Z - M

如果我在Mgit cherry-pick ,我只會得到M並且我會丟失YZ的歷史。 這就是我正在做的事情,但后來我在git blame中失去了功能,並且作者最終被隱藏了(因為 GitHub 提交了由合並它的人而不是原始提交者編寫的合並)。

如果我在Mgit merge ,我會得到我不想要的整個分支,包括WX

如何實現?


讓我再向我的 Y 澄清一下 X:

我們的項目完全基於 GitHub,使用 fork-and-PR 模型(在那里很正常)。

A 之前的內容無關緊要; 我們的發布分支基於 A,然后我們添加了 W 和 X 以進行發布(標簽在 X 上)。

因此,隨機貢獻者 Alice 做了一個來自並針對我們的發布分支的錯誤修復。

release:      W - X
                    \
bugfix:               Y - Z

我們的團隊成員 Bob 將該拉取請求合並到我們的發布分支中。

release:      W - X   - - -  M
                    \       /
bugfix:               Y - Z

重要的是,我,或項目中的任何人,一旦合並就無法觸及錯誤bugfix 它在 Alice 的項目分支上,我們在 Release 分支中有這個:

A - W - X - Y - Z - M

並且由於我們創建了 Release 分支,新的提交( BCD )已添加到我們的 Master 分支中。

現在,這是我的問題的症結所在:我想獲取該拉取請求的整個歷史記錄——來自 Alice 的原始提交( YZ )和來自 Bob 的合並細節(通過合並提交M )——到我們的master分支.

我很高興選擇合並,但由於 GitHub 處理 PR 合並的方式的特殊性,這意味着如果我這樣做,Alice(和她的提交)的所有痕跡都會丟失。 這是我們要避免的。

您的圖表缺少AY之前的歷史記錄(即提交),但通常要做的是將錯誤修復直接合並到所有受影響的分支中。 所以在這里你會git switch master然后git merge bugfix

(我還建議將分支名稱作為實體放入,箭頭指向當前在分支上的最后一個提交,因為這就是名稱在 Git 中的實際工作方式。通過添加更多提交來更新分支只需將箭頭移動到新的最后一次提交。如果您“將提交重置”,則將箭頭向后移動(在 Git 中提交到提交箭頭的方式)到較舊的提交,將較新的提交從末尾刪除分支。)

好的,這不是一個真正的答案,而是原始櫻桃挑選想法的解決方法。

hub pr提供了有關誰提交了 PR 的詳細信息,所以至少,我可以更改 cherry-pick 提交以顯示誰編寫了 PR。 我想這已經足夠了,因為很明顯這永遠不會像我希望的那樣工作。

對於任何好奇的人,這是給 Jellyfin 的,這是我們用來將 PR 從發布分支反向移植回 master 的腳本,並進行了調整以顯示 PR 的作者。 希望那么另一個項目不必對此視而不見。

https://github.com/jellyfin/jellyfin-build/blob/master/backport-prs#L82

首先澄清一下這個說法:

我不希望 W 或 X 在 master 中。 為什么? W 和 X 是類似“Bump to our hotfix release version”之類的提交,在 master 中沒有位置。

通常,並不是您不希望master中的這些提交,而是您不希望master中的這些提交的更改 鑒於此,如果是我(並且我這樣做),我會將release合並回master 有兩種方法可以做到這一點,這樣您就可以完成您想要的,並且仍然可以獲得將整個release分支合並回master的所有其他好處,其中包括:

  • 假設這是一個非常糟糕的一天/一周,並且您在release分支上有 10 個錯誤修復。 你真的想將它們單獨合並回來嗎? (可能不是。)
  • 如果您不需要舊的發布分支,不必保留它們,這很好。 如果您能夠將發布分支合並到master中,則可以刪除它們。 您需要的有關任何先前版本的所有信息都包含在master中。
  • master可以訪問實際發布的提交 ID,以及任何關聯的標簽。 (恕我直言,這是最重要的原因,這也是為什么我希望所有導致發布的提交都以master結尾。)

那么,如何在不拉入標記為WX的提交中的僅版本更改的情況下做到這一點? 這里有2種方法:

  1. 您可以進行兩次合並。 首先,您在X中合並,但您使用-s ours選項放棄更改。 然后你合並到release 除了WX的變化之外,最終結果將release所有內容。 例如:
git switch master
git merge -s ours X # or the tag name you used here
git merge release

請注意, -s ours不應與-X ours (或theirs )混淆,后者是完全不同的東西,是關於自動沖突解決的。 我會認為-s ours合並不尋常,因為它完全忽略了所有合並的更改,因此我建議您在第一次合並時在提交消息中添加評論,說明“合並並忽略發布版本更改”的效果,所以它是明確合並的目的。

  1. 另一種方法是只對release分支進行一次合並,但在提交撤消版本更改之前停止。 這可以在腳本中輕松實現自動化。 例如:
git switch master
git merge release --no-commit
# now the version file changes will be staged, so unstage them:
git reset some-path/some-version-file
# now restore the version file to the version on the master branch:
git restore some-path/some-version-file
# repeat the reset and restore commands for all version files modified in W and X
...
# and finally complete the merge
git commit # or git merge --continue

我個人做這第二個選擇。 (我的腳本撤消了由構建自動更新的 8 個版本文件。)我更喜歡選項 2 的原因是有時我的release分支上有多個構建,所以我需要多次進行雙重合並,在-s ours之間交替-s ours的合並和實際合並將release分支的全部內容返回到master 但是,如果我總是像您描述的那樣在開始時只有 1 個版本的 up-rev,我可能不會像我一樣花時間自動撤消版本文件。

暫無
暫無

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

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