2012-05-21 65 views
15

最可靠的方法是逐一執行,對每個變更集使用backout命令,或者是否有辦法創建一個大的反轉變更集以涵蓋大量的[編輯:非連續]變更集。在mercurial中退出多個變更集的最佳方法是什麼?

如果一個接一個,訂單是否重要? (是否應該繼續前進?)

如果沿途的不同子項目之間有合併,最佳方法會有所不同嗎?

這是否會在您的體驗中順利進行? :-)

+0

我看到可能相關的不同命令。 diff -r可以進行多次修改,但我對確切的語義感到困惑。導出-r需要多個變更集。退出只需一個。我不確定每個 –

+0

出口的優缺點都沒有 - 反向標誌,我的錯誤在那裏。 –

回答

5

rebase--collapse選項。

Helgianswer可升級成:

1 -- A -- 2 -- B -- 3 -- C -- 4 -- 5 
          \ 
          C' -- B' -- A' 

$ hg update --clean C 
$ hg backout --rev C --message "Backed out changeset: C" 
$ hg backout --rev B 
$ hg commit --message "Backed out changeset: B" 
$ hg backout --rev A 
$ hg commit --message "Backed out changeset: A" 
$ hg rebase --collapse --source C' --dest 5 
$ hg commit --message "Backed out C, B, A" 

這將導致以下

1 -- A -- 2 -- B -- 3 -- C -- 4 -- 5 -- C'B'A' 

然而,在單獨的分支回退可能導致[邏輯]衝突隨後的合併。

1 -- A -- 2 -- B -- 3 -- X -- 4 
        \   \ 
         B' -- A' -- M 

如果X取決於AB,然後M會有衝突(至少邏輯衝突)

+1

這很好,不僅僅是--collapse。使用單獨的退格(last-to-first)允許非連續的變更集。由於這可能會在複雜的情況下完成,所以我認爲我會贊成簡單的合併而不是重新合併。具有相反變更集的分支可以是摺疊的(使用各種方法中的任何一種)或不折疊。從Helgi的回答中還有一個重複的警告是,如果有任何合併逆轉,你不能使用退出。 [「處理不良合併的唯一安全方法是放棄分支。」](http://mercurial.selenic.com/wiki/Backout#Backout_of_a_Merge_Changeset) –

+0

我應該添加'diff --reverse'作爲用在我自己的答案中,也不適合合併。鑑於兩者都不會與合併工作,我認爲退出/提交比我的解決方案更方便。 –

+0

@JoshuaGoldberg簡單地合併單個退出的結果是,正如你所提到的那樣,你不能退出你的退出合併。所以對我來說,最好是'rebase'他們.. –

8

如果你一路上沒有合併,你可以退出每個單獨的改變(以相反的順序),或者如果有很多改變,用一個大的反向修補程序來完成。

如果您在需要退出的變更集之上有很好的變更集,最好在最近的不良變更集之上提交反向修補程序,然後將它們重新分配到分支的頂端。

1 -- 2 -- A -- B -- C -- 3 -- 4 
        \ 
         C'B'A' 

$ hg up C 
$ hg diff -r C:2 > backout.diff 
$ hg import --no-commit backout.diff 
$ hg ci -m "Backout A, B, C" 
$ hg up 4 
$ hg rebase -s C'B'A -d . 

如果要背出合併變更,看到this wiki page以獲取更多信息就會出現問題。

在這種情況下,如果可能的話,考慮重新進行分支並剝離舊的血統。否則,您可能必須完全放棄該分支,通過移植或移植挽救好的變更集。

+0

這是否適用於非連續的變更集?我得到的印象不會,從缺乏明確的支持http://stackoverflow.com/questions/5435567/mercurial-diff-multiple-changesets-at-same-time即,如果我會發生什麼說'hg diff -r'關鍵字(xyz)''關鍵字選擇一堆與項目xyz相關的非連續變更集? –

+0

@JoshuaGoldberg:不,它會吐出個別差異。然而,你可以像'hg diff -r「100:90」-I src/subdir'這樣做來將你的差異縮小爲一組文件或目錄。您可以指定多個'-I'或'-X'(不包括)。 – Helgi

0

如果您不希望歷史記錄中的「退出」變更集,您還可以執行其他操作:
對您的存儲庫進行克隆,但只限於最後一個您不想獲取的變更集擺脫。

查看Mercurial: Fix a borked history舉例說明如何做到這一點。

如果您的存儲庫是本地存儲庫,那就只需要這麼做。
但是如果壞的更改集已經推送到中央存儲庫,那麼您需要服務器訪問權來刪除那裏的存儲庫並將其替換爲您的克隆。
另外,如果其他人已經從不良變更集的回購倉庫中取出,他們需要刪除並重新克隆(否則只要其中一個人再次推入,那麼不良變更集就會再次出現在中央倉庫中)。
因此,這取決於這種解決方案是否適合您...

4

我想出的是不雅,但完成了工作,儘管我需要退出的變化是穿插在其他工作,並有一些內部分支。這就是我所做的。 (評論和改進是受歡迎的。)

得到的所有的變更(我隨後用於生成以下命令)的列表:

hg log -r 'keyword(xyz)' --template '{rev}\n' 

生成每個變更集的貼劑:

hg diff -p -U 8 --reverse -c 15094 > 15094.rev.patch 
hg diff -p -U 8 --reverse -c 15095 > 15095.rev.patch 
... 

然後,應用每個反向修補程序。這裏的順序問題,最後以誠爲先:

hg import -m "reversing changeset 15302" 15302.rev.patch 
hg import -m "reversing changeset 15292" 15292.rev.patch 
... 

這個過程是爲合併未通過自動走到哪裏,我不得不從它的名爲.rej文件中手動更改應用到文件打斷好幾次,然後手動提交,然後在提取已停用的導入之前進行提交。

最後(在另一個克隆中......我提到過我是在一個克隆中完成的?)我使用hg histedit -o及其摺疊命令將整套反向變更集壓縮到一個變更集中。

現在我已經有了一個變更集,如果我決定在晚些時候重新開始工作,我應該能夠進行反向和應用(儘管如果我跨過這個橋,我可能會應用「前進」補丁零碎以獲得更好的責備/註釋信息)

+0

來自'help diff':「diff可能會產生意想不到的結果,合併......」它只會將差異值提供給一個父代,因此與退出操作一樣,此過程對於合併而言並不好。 –

1

這是如何與TortoiseHg做到這一點。 當然你也可以在命令行中做同樣的事情。

有了這樣的歷史,在這裏你wan't擺脫變更A的,B和C:

1 -- 2 -- A -- B -- C -- 3 -- 4 

首先更新到版本2

然後重訂的第一任後續版本的你wan't保持 - 在這種情況下,修訂3

你的歷史,現在看起來是這樣的:

1 -- 2 -- A -- B -- C 
     \ 
     3 -- 4 

現在更新到修訂時4

最後使用「本地合併」,將修訂版C合併到修訂4.

在這一點上是至關重要的,你選擇選項「放棄從合併目標的所有更改(其他)修訂「。

說明可能不是最合理的,但它意味着您將舊的提示C合併回默認分支 - 但沒有更改集A,B和C.

結果是:

1 -- 2 -- A -- B -- C -- 
     \   /
     3 -- 4 

提交,即可大功告成。

+0

這是有幫助的,但在一個很多情況下這種策略將不可用---如果這些更改已被推動。在這種情況下,Rebase不是一個選項。不過,對於本地更改很有用,謝謝你的想法。 –

+0

是的,你是對的:推遲更改後它不起作用。 –

相關問題