2

I often find myself in the situation that I need to switch to work on a different change before the one that I am currently working on is done. I want to find out if there's a way, in Mercurial, that I can save/commit my unfinished change, which is not available for others (ie. not clonable/pushable/pullable).

tamakisquare
  • 16,659
  • 26
  • 88
  • 129
  • possible duplicate of [Hg (Mercurial): any way to "set aside" the working copy for later?](http://stackoverflow.com/questions/6158419/hg-mercurial-any-way-to-set-aside-the-working-copy-for-later) – Wooble Jun 11 '12 at 13:39
  • 3
    @Wooble Similar, but not quite the same as this question stipulates that change-sets are not accessible to other people. – Adam Houldsworth Jun 11 '12 at 13:42

3 Answers3

4

Mercurial phases may be the answer to this.

Starting with Mercurial v2.1, you can configure mq changesets to automatically be marked secret. secret changesets are ignored by incoming/pull and outgoing/push commands.

To enable this behavior, you need to add the following to your config:

[mq]
secret = True

Once enabled, it behaves as follows:

$ hg qpush --all
applying my-patch
now at: my-patch

$ hg phase -r .
16873: secret

$ hg outgoing
comparing with https://www.mercurial-scm.org/repo/hg
searching for changes
no changes found (ignored 1 secret changesets)
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Tim Henigan
  • 60,452
  • 11
  • 85
  • 78
  • Thanks Tim. `phases` is new to me. I took a quick look and it looks like what I need. Let me dive into it to find out. – tamakisquare Jun 11 '12 at 14:16
  • 1
    @ahmoo It's worth noting here that the underlying mechanism in use here is Mercurial Queues, all it lets you do is avoid popping the queue item before attempting a push. If you need lots of independent changes, this again may not work out very well. – Adam Houldsworth Jun 11 '12 at 14:18
  • @AdamHouldsworth - appreciate your explanation of how the underlying mechanism works. – tamakisquare Jun 11 '12 at 14:26
  • 3
    There's no need to use the `mq` extension to use `phases`. You can just use the `hg phase` command to mark a revision as secret. You'd need to work in a different branch to be able to release the more urgent change. – Steve Kaye Jun 12 '12 at 07:10
  • @SteveKaye is right. `mq` is not necessary to set `secret` phase. I simply use `hg phase -v --force --secret ` to mark a changeset as `secret` and all its descendants, by default, will be in `secret` phase as well. – tamakisquare Jun 13 '12 at 09:51
  • 1
    Or, put `[phases]` and then `new-commit=secret` in the configuration. This will make new changesets in `secret` phase, by default. – tamakisquare Jun 13 '12 at 09:57
2

Take a look at the Shelve Extension. This gives you the basics and might be more than enough for what you need.

There is also the Mercurial Queues Extension, but I find this can be a little odd to work with.

As a final alternative, you could always commit your changes onto another branch so that they don't affect mainline development, but I think these may still be visible.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
  • Thanks Adam. I think the Shelve Extension would be the better fit but, according to pmezard (Patrick Mézard) on the Mercurial IRC, the extension is not 100% reliable, so I think I will stay away. If you were me, would you use mq or branch? (I have never used either one) – tamakisquare Jun 11 '12 at 13:49
  • Btw, pmezard (Patrick Mézard) mentioned that there's plan to add shelving to the core Mercurial in the future revisions. – tamakisquare Jun 11 '12 at 13:51
  • 1
    @ahmoo I tend to not use Shelve so I can't comment on the reliability. I would use patch queues for small sets of changes that go temporarily off branch. The only consideration with this is if you have multiple queue items, they behave like a stack collection. – Adam Houldsworth Jun 11 '12 at 13:53
  • stack collection meaning that I can retrieve only the last item I put into the queue? – tamakisquare Jun 11 '12 at 14:02
  • Stack may have been the wrong way to describe it. Its more contiguous. If you have made change A in the patch queue, then make change B when A is applied whenever you want to use B it will also import A. – Adam Houldsworth Jun 11 '12 at 14:04
  • I see. You are saying that the changes in the patch queue may not be independently applied. Am I getting it right? – tamakisquare Jun 11 '12 at 14:07
  • 1
    @ahmoo Yes that's right. I should have said it behaves like a queue (which on retrospect is a little obvious). Basically, in order to get to an item to apply, it has to go through and apply anything in the queue ahead of it. If you intend to have lots of independent changes then MQ will not work very well for you, however I don't see why you need to be in that situation - I tend to largely favour branches / anonymous branches and very rarely find myself in the situation of needing to temporarily house my changes to move onto another stream. – Adam Houldsworth Jun 11 '12 at 14:12
  • FYI, queue entries can be reordered, but they can fail to apply if one patch relies on another to work. – Mark Tolonen Jun 11 '12 at 19:46
1

You can clone your repo to a new place to work on new changes. That way your pending changes are kept on your local machine and never pushed. Of course, this depends on the size of your repo. If it's too big, cloning becomes a little prohibitive.

As others have suggested, you can mark your unavailable changes to be on a private branch. When you push, you can push an explicit branch using the -b argument. So, if your private branch is TimPrivateBranch, and other changes are on default:

 hg push -b default

TimPrivateBranch stays on your local computer. Of course, this requires you to remember the -b argument every time you push.

When you're done with your private branch, just merge back into default:

hg up default
hg merge TimPrivateBranch
Aaron Jensen
  • 25,861
  • 15
  • 82
  • 91
  • 2
    You could use `hg phase -s -f TimPrivateBranch` to prevent `TimPrivateBranch` from being pushed without having to remember to use the `-b` argument. When you're done you then use `hg phase -d TimPrivateBranch` followed by the merge to allow it to be pushed again. – Steve Kaye Jun 12 '12 at 07:08
  • Also, you don't need to work on a named branch if you do this because you don't need to use the `-b` argument to exclude it. If you use an anonymous branch you use the first changeset of the branch to mark the branch as secret and the last changeset of the branch to mark it as draft again. – Steve Kaye Jun 12 '12 at 07:15