水银—恢复到旧版本并从那里继续
我在本地使用 Mercurial 进行项目(这是唯一的存储库,无需向/从其他任何地方推/拉)。
迄今为止,它有一个线性的历史。然而,我现在正在做的事情我现在意识到是一种糟糕的方法,我想回到开始之前的版本并以不同的方式实现它。
我对 Mercurial 中的 branch
/ revert
/ update -C
命令有点困惑。基本上我想恢复到版本 38(目前为 45),并让我的下一次提交以 38 作为父版本并从那里继续。我不在乎修订版 39-45 是否会永远丢失或最终陷入自己的死胡同。
我需要哪个命令/命令集?
I'm using Mercurial locally for a project (it's the only repo there's no pushing/pulling to/from anywhere else).
To date it's got a linear history. However, the current thing I'm working on I've now realized is a terrible approach and I want to go back to the version before I started it and implement it a different way.
I'm a bit confused with the branch
/ revert
/ update -C
commands in Mercurial. Basically I want to revert to version 38 (currently on 45) and have my next commits have 38 as a parent and carry on from there. I don't care if revisions 39-45 are lost for ever or end up in a dead-end branch of their own.
Which command / set of commands do I need?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
以下是有关命令的备忘单:
hg update
更改您的工作副本父修订版,并更改文件内容以匹配此新的父修订版。这意味着新的提交将从您更新到的修订版继续进行。hg revert
仅更改文件内容并保留工作副本父版本。当您决定不想在工作副本中保留对文件所做的未提交的更改时,通常可以使用hg revert
。hgbranch
启动一个新的命名分支。将命名分支视为分配给变更集的标签。因此,如果您执行hg Branch red
,那么以下变更集将被标记为属于“红色”分支。这可能是组织变更集的好方法,特别是当不同的人在不同的分支上工作并且您稍后想要查看变更集的来源时。但您不想在您的情况下使用它。如果您使用
hg update --rev 38
,那么变更集39-45将成为死胡同——我们称之为悬空头。当您推送时,您会收到警告,因为您将在推送到的存储库中创建“多个头”。警告之所以存在,是因为留下这样的头脑有点不礼貌,因为他们建议有人需要进行合并。但就您而言,您可以继续执行hg Push --force
因为您确实希望将其挂起。如果您尚未将修订版 39-45 推送到其他地方,那么您可以将它们保密。非常简单:使用
hg clone --rev 38 foo foo-38
您将获得一个新的本地克隆,最多仅包含修订版 38。您可以继续在foo-38
中工作code> 并推送您创建的新(好的)变更集。您的foo
克隆中仍将保留旧的(错误的)修订版本。 (您可以随意重命名克隆,例如,将foo
重命名为foo-bad
并将foo-38
重命名为foo< /code>。)
最后,您还可以使用
hg revert --all --rev 38
然后提交。这将创建一个看起来与修订版 38 相同的修订版 46。然后,您将从修订版 46 继续工作。这不会以与hg update
相同的显式方式在历史记录中创建分叉,但是另一方面,你不会因为有多个头而受到抱怨。如果我与其他人合作,他们已经根据修订版 45 完成了自己的工作,我会使用hg revert
。否则,hg update
更加明确。Here's the cheat sheet on the commands:
hg update
changes your working copy parent revision and also changes the file content to match this new parent revision. This means that new commits will carry on from the revision you update to.hg revert
changes the file content only and leaves the working copy parent revision alone. You typically usehg revert
when you decide that you don't want to keep the uncommited changes you've made to a file in your working copy.hg branch
starts a new named branch. Think of a named branch as a label you assign to the changesets. So if you dohg branch red
, then the following changesets will be marked as belonging on the "red" branch. This can be a nice way to organize changesets, especially when different people work on different branches and you later want to see where a changeset originated from. But you don't want to use it in your situation.If you use
hg update --rev 38
, then changesets 39–45 will be left as a dead end — a dangling head as we call it. You'll get a warning when you push since you will be creating "multiple heads" in the repository you push to. The warning is there since it's kind of impolite to leave such heads around since they suggest that someone needs to do a merge. But in your case you can just go ahead andhg push --force
since you really do want to leave it hanging.If you have not yet pushed revision 39-45 somewhere else, then you can keep them private. It's very simple: with
hg clone --rev 38 foo foo-38
you will get a new local clone that only contains up to revision 38. You can continue working infoo-38
and push the new (good) changesets you create. You'll still have the old (bad) revisions in yourfoo
clone. (You are free to rename the clones however you want, e.g.,foo
tofoo-bad
andfoo-38
tofoo
.)Finally, you can also use
hg revert --all --rev 38
and then commit. This will create a revision 46 which looks identical to revision 38. You'll then continue working from revision 46. This wont create a fork in the history in the same explicit way ashg update
did, but on the other hand you wont get complains about having multiple heads. I would usehg revert
if I were collaborating with others who have already made their own work based on revision 45. Otherwise,hg update
is more explicit.如果稍后您提交,您将有效地创建一个新分支。然后,您可能会继续仅在该分支上工作,或者最终将现有分支合并到其中。
If later you commit, you will effectively create a new branch. Then you might continue working only on this branch or eventually merge the existing one into it.
我刚刚遇到一种情况,需要在完成提交和推送后将一个文件恢复到以前的版本。其他答案未涵盖用于指定这些修订的简写语法,因此这里是执行此操作的命令
-2
将使用-1
恢复到上次提交之前的版本只会恢复当前未提交的更改。I just encountered a case of needing to revert just one file to previous revision, right after I had done commit and push. Shorthand syntax for specifying these revisions isn't covered by the other answers, so here's command to do that
That
-2
will revert to the version before last commit, using-1
would just revert current uncommitted changes.恕我直言,
hg strip -r 39
更适合这种情况。它需要启用 mq 扩展,并且与 Martin Geisler 推荐的“克隆 repo 方法”具有相同的限制:
如果变更集以某种方式发布,它(可能)会在某个时间点返回到您的存储库,因为您只更改了本地存储库。
IMHO,
hg strip -r 39
suits this case better.It requires the mq extension to be enabled and has the same limitations as the "cloning repo method" recommended by Martin Geisler:
If the changeset was somehow published, it will (probably) return to your repo at some point in time because you only changed your local repo.
使用
hg update -r REV
后,答案中并不清楚如何提交该更改以便您可以推送。如果您只是尝试在更新后提交,Mercurial 不会认为有任何更改。
我必须首先对任何文件进行更改(例如在自述文件中),以便 Mercurial 识别出我进行了新的更改,然后我可以提交该更改。
然后如上所述创建了两个头。
为了在推动之前摆脱另一个头,我按照无操作合并步骤来解决这个问题情况。
然后我就可以推动了。
After using
hg update -r REV
it wasn't clear in the answer about how to commit that change so that you can then push.If you just try to commit after the update, Mercurial doesn't think there are any changes.
I had to first make a change to any file (say in a README) so Mercurial recognized that I made a new change, then I could commit that.
This then created two heads as mentioned.
To get rid of the other head before pushing, I then followed the No-Op Merges step to remedy that situation.
I was then able to push.
上面的答案非常有用,我学到了很多。但是,根据我的需要,简洁的答案是:
其中
${1}
是修订版本号或分支名称。这两行实际上是 bash 脚本的一部分,但如果您想手动执行,它们可以单独工作。如果您需要向发布分支添加热修复,但需要从默认构建(直到我们正确使用 CI 工具并能够从分支构建,然后也取消发布分支),这非常有用。
The answers above were most useful and I learned a lot. However, for my needs the succinct answer is:
where
${1}
is the number of the revision or the name of the branch. These two lines are actually part of a bash script, but they work fine on their own if you want to do it manually.This is useful if you need to add a hot fix to a release branch, but need to build from default (until we get our CI tools right and able to build from branches and later do away with release branches as well).
我会安装 Tortoise Hg(Mercurial 的免费 GUI)并使用它。然后,您只需右键单击您可能想要返回的修订版本 - 所有提交消息都在您眼前 - 并“恢复所有文件”。使得在文件集的版本之间来回滚动变得直观且容易,如果您想要确定问题首次出现的时间,这非常有用。
I'd install Tortoise Hg (a free GUI for Mercurial) and use that. You can then just right-click on a revision you might want to return to - with all the commit messages there in front of your eyes - and 'Revert all files'. Makes it intuitive and easy to roll backwards and forwards between versions of a fileset, which can be really useful if you are looking to establish when a problem first appeared.