是一个最可靠的方法,对许多变更集中的每一个使用回退命令,或者有没有办法创建一个大的反转变更集来覆盖一大堆[编辑:非连续的]变更集。
如果一对一,顺序重要吗?(应该从后到先吗?)
如果在此过程中不同子项目之间存在合并,最好的方法会有所不同吗?
根据您的经验,这是否会顺利进行?:-)
是一个最可靠的方法,对许多变更集中的每一个使用回退命令,或者有没有办法创建一个大的反转变更集来覆盖一大堆[编辑:非连续的]变更集。
如果一对一,顺序重要吗?(应该从后到先吗?)
如果在此过程中不同子项目之间存在合并,最好的方法会有所不同吗?
根据您的经验,这是否会顺利进行?:-)
如果您在此过程中没有合并,您可以撤消每个单独的更改(以相反的顺序),或者,如果其中有很多,则使用一个大的反向补丁来完成。
如果您在需要退出的变更集之上有好的变更集,最好在最近的错误变更集之上提交反向补丁,然后将它们重新定位到分支的尖端。
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 .
如果您想退出合并变更集,将会出现问题,请参阅此 wiki 页面以获取更多信息。
在这种情况下,如果可能,请考虑重新进行分支并剥离旧的血统。否则,您可能不得不完全放弃分支,通过移植或移植来挽救好的变更集。
有. --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'
但是,在单独的分支中退出可能会导致后续合并中的[逻辑]冲突。
1 -- A -- 2 -- B -- 3 -- X -- 4
\ \
B' -- A' -- M
如果X
依赖A
or B
,那么M
就会有冲突(至少是逻辑冲突)。
我想出的是不雅的,但完成了工作,尽管我需要退出的更改穿插在其他工作中并且有一些内部分支。这就是我所做的。(欢迎评论和改进。)
得到了所有变更集的列表(然后我用它来生成下面的命令):
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 命令将整个反向变更集压缩到一个变更集中。
现在我有一个单一的变更集,如果我决定在以后将工作放回原处,我应该能够撤消和应用(尽管如果我越过那座桥,我可能会按顺序再次零碎地应用“前向”补丁以获得更好的责备/注释信息)
这就是使用 TortoiseHg 的方法。当然你也可以用命令行做同样的事情。
鉴于这段历史,您不想摆脱变更集 A、B 和 C:
1 -- 2 -- A -- B -- C -- 3 -- 4
第一次更新到第 2 版。
然后重新设置您不想保留的任何后续版本中的第一个 - 在本例中为版本 3。
你的历史现在看起来像这样:
1 -- 2 -- A -- B -- C
\
3 -- 4
现在更新到修订版 4。
最后使用“与本地合并”将修订 C 合并到修订 4。
此时,选择“放弃合并目标(其他)修订版中的所有更改”选项至关重要。
描述可能不是最合乎逻辑的,但这意味着您将旧提示 C 合并回默认分支 - 但没有变更集 A、B 和 C。
结果是:
1 -- 2 -- A -- B -- C --
\ /
3 -- 4
提交,你就完成了。
如果您不想在历史记录中“退出”变更集,您还可以执行其他操作:
克隆您的存储库,但仅限于您不想删除的最后一个变更集。
有关如何执行此操作的示例,请参阅Mercurial: Fix a borked history 。
如果您的存储库是本地存储库,那么这就是您所要做的。
但是,如果错误的变更集已经被推送到中央存储库,您需要服务器访问权限才能删除那里的存储库并用您的克隆替换它。
另外,如果其他人已经从带有错误变更集的回购中拉出,他们需要删除并重新克隆(否则一旦其他人再次推送,错误的变更集就会再次出现在中央回购中)。
因此,这取决于具体情况,此解决方案是否适合您...