If I have a bunch of uncommitted changes and want to set it aside while working on something else instead, and then later (f.i. after several days) come back to it and proceed working. What would be the easiest workflow to accomplish this? (So far I have only experience with Mercurial's basic functionality). My usual method was to create a new branch using clone, but there might be better ways.
Shelve changesIn the Commit tool window Alt+0 , right-click the files or the changelist you want to put to a shelf and select Shelve changes from the context menu. In the Shelve Changes dialog, review the list of modified files.
Shelve changes Shelving is temporarily storing pending changes you have not committed yet. This is useful, for example, if you need to switch to another task, and you want to set your changes aside to work on them later. With IntelliJ IDEA, you can shelve both separate files and entire changelists.
There's no such thing as a git shelve command. The term 'shelve' references a commonly understood process that takes some temporary file changes, saves them locally and outside of the current version control system and then returns to those files at some point in the future.
You have a handful options:
Shelve the items. This saves the changes and removes them from the working directory so the branch can continue. It doesn't create a change-set.
hg shelve --all --name "UnfinishedChanges" hg unshelve --name "UnfinishedChanges"
Update/Edit: Newer versions of mercurial may need to use
hg shelve -n "UnfinishedChanges" hg unshelve "UnfinishedChanges"
You can still use --name
as an alternative to -n
, but mercurial doesn't seem to like --name
anymore. Additionally, the --all
is no longer required and mercurial will in fact freak out over it.
Patch queue the items using mq
. This isn't too dissimilar to shelve in some respects, but behaves differently. The end result is the same, changes are removed and can be optionally re-applied later. When pushed, the patches are logical change-sets, when popped they are saved elsewhere and are not part of change-set history.
hg qnew "UnfinishedWork" hg qrefresh hg qpop hg qpush "UnfinishedWork"
Commit them locally, update to the previous change-set and continue working and make use of anonymous branches (or multiple heads). If you then want the changes, you can merge heads. If you don't want the changes, you can strip the change-set.
hg commit -m"Commiting unfinished work in-line." hg update -r<previous revision> hg strip -r<revision of temporary commit>
Commit them to a named branch. The workflow then becomes the same as option 3 - merge or strip when you are ready.
hg branch "NewBranch" hg commit -m"Commiting unfinished work to temporary named branch." hg update <previous branch name>
Personally I use option 3 or 4 as I don't mind stripping change-sets or checking-in partial code (so long as that doesn't eventually get pushed). This can be used in conjunction with the new Phase stuff to hide your local change-sets from other users if need-be.
I also use the rebase
command to move change-sets around to avoid merges where a merge wouldn't add anything to the history of the code. Merges I tend to save for activity between important branches (such as release branches), or activity from a longer-lived feature branch. There is also the histedit
command I use for compressing change-sets where the "chattiness" of them reduces the value.
Patch queues are also a common mechanism for doing this, but they have stack semantics. You push and pop patches, but a patch that is "underneath" another patch in the stack requires that the one on top of it be pushed also.
Warning, as with all these options, if the files have more changes since the temporary changes that you've shelved / queued / branched, there will be merge resolution required when un-shelving / pushing / merging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With