最可靠的方法是逐个使用,对许多变更集中的每一个使用backout命令,或者是否有办法创建一个大的反转变更集来覆盖一大堆 [编辑:非-contiguous] 变更集。
如果一个接一个,订单是否重要? (一个人应该排在第一位吗?)
如果沿途不同子项目之间有合并,那么最佳方法会有所不同吗?
这会让您的体验顺利吗? : - )
答案 0 :(得分:9)
如果您没有合并,您可以退出每个单独的更改(按相反的顺序),或者,如果有很多更改,请使用一个大的反补丁。
如果你需要退出的变更集上面有好的变更集,那么最好在最近的不良变更集之上提交反补丁,然后将它们重新定位到分支的顶端。
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。
在这种情况下,如果可能的话,考虑重新做分支并剥离旧的血统。否则,你可能不得不完全放弃分支机构,通过移植或移植来挽救好的变革集。
答案 1 :(得分:5)
--collapse
有rebase
个选项。
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'
但是,在单独的分支中退出可能会导致后续合并中出现 [logical] 冲突。
1 -- A -- 2 -- B -- 3 -- X -- 4
\ \
B' -- A' -- M
如果X
取决于A
或B
,则M
将发生冲突(至少是逻辑冲突)。
答案 2 :(得分: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
及其fold命令将整组反向变更集压缩为一个变更集。
现在我有一个单一的变更集,如果我决定在以后重新开始工作,我应该可以撤销并应用(虽然如果我跨过那座桥,我可能会逐步应用“前进”补丁再次为了获得更好的责备/注释信息)
答案 3 :(得分:1)
这就是你用TortoiseHg做的方法。 当然,您也可以使用命令行执行相同的操作。
鉴于这段历史,你不想摆脱变革集A,B和C:
1 -- 2 -- A -- B -- C -- 3 -- 4
首次更新到修订版2。
然后重新修改你不想保留的任何后续版本中的第一个 - 在本例中修订版本3.
您的历史现在看起来像这样:
1 -- 2 -- A -- B -- C
\
3 -- 4
现在更新到revison 4.
最后使用“与本地合并”将修订版C合并到修订版4中。
此时,选择“放弃合并目标(其他)修订版中的所有更改”选项至关重要。
描述可能不是最符合逻辑的,但它意味着您将旧提示C合并回默认分支 - 但没有更改集A,B和C.
结果是:
1 -- 2 -- A -- B -- C --
\ /
3 -- 4
承诺并且你已经完成了。
答案 4 :(得分:0)
如果您不想在历史记录中“退出”更改集,您还可以执行其他操作:
复制您的存储库,但最多只能删除您不想删除的最后一个变更集。
有关如何执行此操作的示例,请参阅Mercurial: Fix a borked history。
如果您的存储库是本地存储库,那就是您需要做的全部工作 但如果坏的变更集已被推送到中央存储库,则需要服务器访问权限才能删除存储库并将其替换为克隆。 另外,如果其他人已经从不良变更集中撤出了回购,他们需要删除并重新克隆(否则,只要其中一个人再次推送,坏的变更集就会再次出现在中央仓库中。) 所以这取决于具体情况,这个解决方案对你来说是否合适......