Is there an hg equivalent of `git stash save -p` that can split chunks into smaller chunks?
Asked Answered
K

2

5

I want to commit only some of the modifications I made to my files and my preferred way to do this is to shelve/stash away the changes I don't want to commit. This allows me to test the changes I will commit before actually commiting them.

The problem I am having is that when I use the "shelve" tool in tortoisehg I can't find any way to split a chunk into two smaller chunks. For example, I have a chunk that looks like this:

@@ -1,1 +1,2 @@
-hallo world
+hello world
+something else

I would like to shelve away the "something else" so I can commit just the "hallo->hello" fix. However, since tortoisehg is seeing this a single chunk I can either shelve both or none of the changes.

I also tried using the shelve extension via the command line but from what I understood from the documentation it does not offer the feature to shelve away only parts of the files.

Keef answered 8/11, 2015 at 15:53 Comment(0)
H
7

You can accomplish your goal from the command line. There are interactive versions of hg commit, hg revert, and hg shelve, and they have low-level options to hack a patch together if needed; you can use them with the -i (or --interactive) command line option.

This means that you can build up a commit with hg commit -i and hg commit --amend -i. If you have the evolve extension installed, you can use hg uncommit to pull changes out of the commit again; if not, you can use hg revert -r .~1 or hg revert -i -r .~1 a file and use hg commit --amend -i again to fix it up.

In order to select individual lines from a patch, you have two options. You can use e to edit the patch (but see below for a more convenient option).

You can then use hg shelve to shelve the remaining changes.


You can in principle also do this with hg shelve -i, however, there's a big caveat; if you edit patches for hg shelve -i, then Mercurial's merge mechanism will get confused and not process the change cleanly, but dump you in a merge tool in order to resolve this apparent conflict (which means lots of extra work to resolve it). Hence why I strongly recommend using hg commit -i and hg commit --amend -i if you want to manipulate things at the line level (hg shelve -i works fine if you don't edit the patches).


For added convenience (that prevents you from editing patches), you can also enable the experimental crecord option by adding the following to your hgrc file:

[experimental]
crecord = true

This will enable a terminal-based hunk editor for hg commit -i, hg revert -i, and hg shelve -i that allows you to select individual lines and hunks (internally, that works roughly the same way as editing patches). Use the ? key to get help in that editor; use f to unfold/fold individual hunks and the space key to select hunks/lines.

Note that line-based selection for this tool in conjunction with hg shelve -i comes with the same caveats as editing patches; i.e. use hg commit -i and hg commit --amend -i instead if you want to do line-based selection. Also, line-based selection for hg revert -i will still revert the entire hunk. (There's a reason why this option is still marked as experimental.)

Hostel answered 8/11, 2015 at 20:27 Comment(0)
H
0

I don't know a command to do this, but if you are using tortoiseHg, you can do that by selecting modified sections (checkboxes) in the commit preview area.

See Mercurial cherry picking changes for commit

Hautboy answered 8/11, 2015 at 16:30 Comment(1)
The problem I have is that there is a single checkbox and that chunk contains both of the changes. How do I turn one checkbox into two checkboxes?Keef

© 2022 - 2024 — McMap. All rights reserved.