在做其他事情时,我如何搁置一堆未提交的更改


98

如果我有一堆未提交的更改,并且想在进行其他操作时将其搁置一旁,然后稍后(几天后上网)回到它并继续工作。最简单的工作流程是什么?(到目前为止,我只对Mercurial的基本功能有经验)。我通常的方法是使用克隆创建一个新分支,但是可能会有更好的方法。

Answers:


133

您有几种选择:

  1. 搁置物品。这样可以保存更改并将其从工作目录中删除,以便分支可以继续。它不会创建变更集。

    hg shelve --all --name "UnfinishedChanges"
    
    hg unshelve --name "UnfinishedChanges"
    

    更新/编辑:可能需要使用较新版本的Mercurial

    hg shelve -n "UnfinishedChanges"
    hg unshelve "UnfinishedChanges"
    

    您仍然可以使用--name来代替-n,但汞似乎已--name不再受欢迎。另外,--all不再需要它,事实上,水银会吓坏它。

  2. 修补程序使用将项目排队mq。在某些方面,这并没有太大的相似之处,但行为有所不同。最终结果是相同的,更改已删除,以后可以有选择地重新应用。推送时,修补程序是逻辑变更集,弹出时,修补程序将保存在其他位置,并且不属于变更集历史记录。

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. 在本地提交它们,更新到以前的变更集,然后继续工作并利用匿名分支(或多个头)。如果随后需要更改,则可以合并磁头。如果您不想更改,则可以删除更改集。

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. 将它们提交到一个命名分支。然后,工作流程与选项3相同-准备好后合并或剥离。

    hg branch "NewBranch"
    hg commit -m"Commiting unfinished work to temporary named branch."
    hg update <previous branch name>
    

我个人使用选项3或4,因为我不介意删除变更集或检入部分代码(只要最终不会被推送)。可以将其与新的阶段材料结合使用,以便在需要时向其他用户隐藏您的本地更改集。

我还使用该rebase命令来移动更改集,以避免合并,因为合并不会在代码的历史记录中添加任何内容。我倾向于保存重要分支(例如发行分支)之间的活动或寿命较长的功能分支中的活动的合并。我还有histedit一条用于压缩变更集的命令,其中变更的“个性”降低了该值。

修补程序队列也是执行此操作的常用机制,但是它们具有堆栈语义。您可以推送和弹出补丁,但是位于堆栈中另一个补丁“下方”的补丁需要同时推送其顶部的补丁。

警告,与所有这些选项一样,如果文件自搁置/排队/分支的临时更改以来具有更多更改,则取消搁置/推送/合并时将需要合并分辨率。


感谢您的出色回答和有用的示例。您是否知道是否也可以使用hg书签?
Erik

@Erik可能,但是我没有使用它的经验。
亚当·霍尔兹沃思

2
书签可用于帮助选项3-您可以使用书签来标记为存储更改而创建的修订。他们不能独自完成任务。
史蒂夫·凯

选项--all无法识别。无论如何,搁置所有更改是一种默认行为。
naXa

@naXa嗨,队友,如果我的命令之一略有失误(也许是因为版本已更改),请随时编辑答案,如有必要,我会批准它:-)
Adam Houldsworth,

23

就个人而言,我不喜欢到目前为止发布的任何答案:

  1. 我不喜欢克隆分支,因为我希望每个项目只有一个目录。同时在不同目录上工作会完全弄乱我的编辑器最近文件的历史记录。我总是最终更改错误的文件。所以我不再这样做了。
  2. 我使用shelve快速修复程序(只是将我未提交的更改移到另一个分支,如果我意识到自己输入的是错误的)。您在谈论几天,我几天都不会搁置某些东西。
  3. 我觉得mq对于这样一个普通的情景来说太复杂了

我认为最好的方法是简单地提交更改,而不是在开始这些更改并从那里开始之前返回到变更集。有一些小问题,让我举例说明:

假设您拥有变更集A。比开始变更。此时,您需要将其搁置一段时间。首先,提交您的工作:

hg ci -m "Working on new stuff"

如果需要,您可以添加书签,以方便以后再次使用。我总是为我的匿名分支创建书签。

hg bookmark new-stuff

在进行这些修改之前,请返回变更集

hg update A

从这里开始,工作并生成变更集C。现在您有了2个头(B和C),当您尝试推送时会被警告。您可以通过指定分支的头来仅推送一个分支:

hg push -r C

或者,您可以将new-stuff分支的阶段更改为秘密。秘密变更集不会被推送。

hg phase -r new-stuff --secret --force

感谢您的详细回答!我真的很喜欢阅读人们的工作流程以解决那些(普通的)问题。
Erik

我认为这mq是一个有点太复杂,只是这种情况,但它的用途,包括这一个足够宽的范围,即同时投资是值得的时间成为精通它。
2014年

12

要保留本地未提交的更改,对我来说最简单的方法就是将它们另存为补丁文件。

hg diff > /tmp/`hg id -i`.patch

以及当您需要返回到以前的状态时:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch

我要脱衣/tmphg id -i它也可以在Windoze上使用。
anatoly techtonik

并且hg up在那里不需要。
anatoly techtonik

1
@techtonik如果我将补丁应用到另一个修订版,将会发生什么?特别是如果修改了修补文件。
mapcuk

Mercurial会尝试将其合并,无论如何您都必须处理冲突。
anatoly techtonik

6

您可以多次克隆您的仓库。我倾向于有一个根克隆,然后从那里有多个孩子。例:

  • MyProject.Root
  • MyProject.BugFix1
  • MyProject.BugFix2
  • MyProject.FeatureChange1
  • MyProject.FeatureChange2

这4个子项均从根克隆,然后从根推入/拉出。然后,根从网络/互联网上某个位置的主存储库中推入/拉出。根充当您的个人暂存区。

因此,就您而言,您只需克隆一个新的存储库即可开始工作。将您的“搁置式”工作留在另一个回购中。就这么简单。

唯一的缺点是磁盘空间的使用,但是如果您担心这一点,您还是根本不会使用DVCS;)哦,这确实会污染您的Visual Studio“最近的项目”列表,但是可惜。

[编辑以下评论]:-

总结一下……您在做什么完全正常。我认为当满足以下条件时,这是最好的工作方式:1)它是短暂的2)您不需要与其他开发人员合作3)所做的更改无需在提交前离开PC /推送时间。


有没有不使用分支的原因吗?这就是它们的用途,并且比回购克隆要快得多。
亚当·霍尔兹沃思

在我的问题中,我指出以下几点:我通常的方法是使用克隆创建一个新分支,但是可能会有更好的方法。
Erik

1
@AdamHouldsworth,从技术上讲,这是分支……只是短暂的分支。为短暂的工作创建命名分支是完全愚蠢的。它滥用了名为分支的目的,该分支用于长期的工作故事。
nbevans 2012年

@NathanE如果您认为短期工作的命名分支是“完全愚蠢的”,那么还有匿名分支,搁置或补丁队列等其他轻量级选项。在我看来,面对其他选择,重新克隆同样是愚蠢的-一个潜在的好处是在两个VS实例中打开两组代码,但是我很少这样做,因此使用克隆当然不会不为我服务。只是为了澄清,我不是拒绝投票的人。
亚当·霍尔兹沃思

@NathanE它们也不是“长期的工作故事”所独有的,如果您遵循持续的集成,它们只是擅长的。直接来自文档:“如果开发线发生分歧,就会产生分支”,如果您搁置一项工作以从事其他工作,那么对我来说这听起来像是分歧,无论它有多长寿。
亚当·霍尔兹沃思
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.