There may be a time when your realize that the changes you just made (uncommitted changes), need to be on separate branch. That happend to me in my new workplace few days ago. My new workplace use branching extensively to ensure code review process is taking place. Every feature or defect is done on separate branch. After work completed, the developer initiates a pull request via bitBucket so that there is another developer who approves the changes before merged into main trunk. So, for my first changes i forgot and i completed my changes on the main trunk just to later learn it has to be on a separate branch. The Shelving feature in Mercurial came to rescue me. I was surprised to learn that a task that can become time consuming and challenging was accomplished so easy thanks to shelving feature. This post will cover how to install Shelve extension and then use this feature to move some uncommitted changes into a different branch.
Install Extension – hgshelve
You may not need this because some IDE like IntelliJ comes with the extention – hgshelve preinstalled and configured, however, if you are like me who likes command line mercurial hg then we have to install.
1. Clone the extension – hgshelve
>hg clone ssh://hg@bitbucket.org/tksoh/hgshelve
2. Configure the extension – hgshelve
To do so, update your global mercurial config .hgrc file section ‘extensions’ in your home directory as follows:
[extensions]
hgshelve=/path_to_dir_cloned_above_step_1/hgshelve.py
This completes the installation and configuration of the extension – hgshelve. Now, you are able to take advantage of the power that shelving brings to you
Using Shelve
1. Shelve Uncommitted Changes
First, i shelve my uncommitted changes while on the main branch by executing command:
>hg shelve --name DE4653_DE3847_Shelved
Once started, mercurial will be asking to confirm each change that adding to shelve something like:
>$ hg shelve my_dir/my_file.ext
>examine changes to 'my_dir/my_file.ext'? [Ynsfdaq?]
The options – [Ynsfdaq?] stand for:
y - shelve this change
n - skip this change
s - skip remaining changes to this file
f - shelve remaining changes to this file
d - done, skip remaining changes and files
a - shelve all changes to all remaining files
q - quit, shelveing no changes
? - display help</pre>
If you like to see every change added to this shelve then select ‘Y’ or ‘a’ for shelving all of the changes without confirming each
This shelves the changes and i am safe to change branches
Verify Shelved Changes
1. To verify your changes has been shelved, run:
>hg shelve --list
DE4653_DE3847_Shelved
This would list all of the shelved changes. In our case, there is only one
2. Another way to ensure changes has been shelved is to run ‘hg status’. If changes shelved, this should return nothing
3. If you doing for the first time and you are afraid of losing, then look at .hg/shelve directory in application dir (precisely, mercurial working directory). There you should find text files containing the changes per each shelving. You can back those up. You can email to your friend developer to finish, perhaps, in situations where you have shelved uncommitted changes and you are unable to complete because you going out town. Or email to yourself to finish at home. By putting these text files in your home computer .hg/shelve folder, makes those available to unshelve and finish
Unshelve Changes
2. Create New Branch. To create new branch, run command:
>hg branch DE4653_DE3847
This not only creates new branch, it also automatically puts you in the new branch. To verify what branch you are at any time, run ‘hg branch’
3. Unshelve Changes
When ready, to unshelve your changes, run:
>hg unshelve --name DE4653_DE3847_Shelved
This takes our uncomitted changes shelved previously and adds to our working directory. To verify you can run ‘hg st’ or ‘hg shelve –list’. The latter will return nothing in our case because after unshelving the shelvDE4653_DE3847_Shelved is destroyed.
Now, we are able to commit the new changes in the separate appropriate branch, so we can create pull request , thus, accomplishing our goal.
4. Nudge Changes
Not related shelving, however part of the exercise – putting your changes on separate branch. The last step after unshelleving the changes and committing, perhaps, is to push your branch with the unshelled changes into the central repo. This allows others to code review and approve pull request(i.e. bitbucket)
The general ‘hg push’ method will push all branches in your local repo that you may not want. You only need to push your new branch. For that purpose, use ‘hg nudge’ that is a push command but only for the branch you are on at the given moment. Before that works you need to update .hgrc – mercurial global configuration in home directory as follows:
...
[alias]
nudge = push --rev .
Afterwards, make sure you are in the proper branch and call method:
>hg nudge
This pushes just unshelved changes as separate branch into centra repo
Bug – Added Files Unable Shelve
It turns out that for newest current version of the ‘hgshelve’ extension there is bug which prevents to shelve any files that has been added to working directory and has status ‘A’.
The best solution i found is to use a different mercurial extension – hgattic that contains the shelve feature but does not have the bug. Make sure you grab it from the repo version that works with the newest version of mercurial https://bitbucket.org/sinbad/hgattic/
Everything applies the same way except the commands are named slight different. It also add some extra goodies about all of which you can learn from hgattic wiki
Useful Links: