为什么 Mercurial 会合并工作副本中已提交的更改?
我已经使用 Mercurial 几个星期了,不明白为什么当 Mercurial 合并两个存储库中已提交的更改时,它会在工作副本中进行合并?
当然,合并可以在不使用工作副本的情况下进行,从而无需搁置更改等。
似乎没有必要涉及工作副本。我错过了什么吗?
I've been using Mercurial for a few weeks now and don't understand why when Mercurial comes to merge committed changes from two repositories it does it in the working copy?
Surely the merge could happen without the use of the working copy removing the need to shelf changes etc.
It just doesn't seem necessary to involve the working copy. Am I missing something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如HgInit的“合并”一章中提到的:
此类检查可能包括合并中的冲突,用户必须检查:
因此,您需要一个工作目录(合并视图)才能完全解决合并问题。
As mentioned in the chapter "Merge" of HgInit:
Such check can include conflicts in merge, that the user has to review:
So you need a working directory (a view for the merge) in order to resolve fully a merge.
我没有编写 Mercurial,所以我不能说他们为什么这样做,但以下是该决定的一些积极结果:
如果您确实想要进行合并,并且工作目录中有一些您无法忍受提交的内容,请不必费心搁置,只需执行以下操作:
在同一个文件上系统克隆几乎是瞬时的,并在幕后使用硬链接,因此它几乎不占用临时工作副本以外的空间。
I didn't write Mercurial, so I can't say why they did it that way, but here are some of the positive results of that decision:
If you really want to do a merge and have stuff in your working dir that you can't bear to commit don't bother with shelve just do:
On the same file system clone is near instantaneous and uses hardlinks under the covers so it takes up almost no space past that of the temporary working copy.
每个存储库只有一个工作副本,根据定义:
除非您的文件系统源自薛定谔的猫,否则您不能同时拥有同一文件的两个版本,因此您不能拥有两个工作副本。
尽管如此,理论上确实可以使用临时克隆(根据@Ry4an)之类的东西来充当合并的工作副本,解决那里的冲突,提交,然后使其消失。您将获得一个漂亮的合并变更集和完整的工作副本。
我可以想到几种方法来实现这一点:
我强烈推荐#4,就像我几乎会做的那样所有工作流程场景。我花了好几天的时间才理解 MQ,但一旦我这样做了,我就再也不用回头了。
在 MQ 工作流程中,您的工作副本始终是当前补丁。因此,对于合并情况,您可以执行以下操作:
hg qrefresh
hg qpop -a
hg update -r
hg merge [-r<合并第二个父级>]
hg commit
hg update qparent
hg qgo <工作副本补丁>
你不'不必弹出#2 中的所有补丁。每当我需要处理真正的变更集时,我总是这样做,以避免将它们与补丁混淆。
解决方案 #3 实际上与 #4 相同,因为根据定义,补丁是临时变更集(这实际上是理解 MQ 所需的唯一内容)。只是不同的命令:
hg commit -A
hg update -r
hg merge [-r]
hg commit
hg update -r<工作副本变更集父级>
hg revert -a -r<工作副本变更集>
hg strip < ;工作副本变更集>
如果您想保留工作副本变更集并继续提交,只需在#5 中更新即可。
从你的问题来看,你似乎已经知道#4,但不喜欢搁置。我认为搁置很好,因为合并是一项与编码(更改工作副本)根本不同的任务,并且搁置使上下文切换明确且安全。
There is only one working copy per repository, by definition:
Unless your file system descends from Schrödinger's cat, you cannot have two versions of the same file at the same time, thus you cannot have two working copies.
Nevertheless, it's indeed theoretically possible to use something like a ephemeral clone (per @Ry4an) to act as the working copy of a merge, resolve conflicts there, commit, then make it disappear. You'd get a beautiful merge changeset and your intact working copy.
I can think of several ways to achieve this:
I would strongly recommend #4, as I would for almost all workflow scenarios. It took me a few good days to grok MQ, but once I did I've never had to turn back.
In an MQ workflow, your working copy is always the current patch. So for the merge situation you would do:
hg qrefresh
hg qpop -a
hg update -r<merge first parent>
hg merge [-r<merge second parent>]
hg commit
hg update qparent
hg qgo <working copy patch>
You don't have to pop all patches in #2. I always do that whenever I need to deal with real changesets to avoid mixing them up with patches.
Solution #3 is really the same as #4, since a patch is a temporary changeset by definition (this is really the only thing you need for understanding MQ). It's just different commands:
hg commit -A
hg update -r<merge first parent>
hg merge [-r<merge second parent>]
hg commit
hg update -r<working copy changeset parent>
hg revert -a -r<working copy changeset>
hg strip <working copy changeset>
If you want to keep the working copy changeset and continue to commit, simply update to it in #5.
From your question it seems like you already know #4 but don't like shelving. I think shelving is good because merging is a fundamentally different task than coding (changing working copy), and shelving makes the context switch explicit and safe.