Search code examples
mercurialmercurial-revsets

Mercurial revset selecting up to a bookmark


If I have this changesets in my repository

A --> B --> C --> D
      *

B is bookmarked and D is at the tip - how do I create a revset that will select everything between B and D but not B.

Specifically I'm trying to squash C and D in to B, something like :

hg strip -r "bookmark:." -k

except this line will also delete the commit B which I want to keep.


Solution

  • I'm not entirely clear whether you want to squash C and D, creating a new commit C', or whether you want to squash B, C, and D, creating a new commit B', which will keep the original bookmark.

    For the first:

    hg rebase -s 'children(bookmark)' -d bookmark --collapse -m <msg>
    

    You need to specify a commit message with either the -m or the -l option, or you'll get dropped into the editor.

    For the second:

    hg rebase -s bookmark -d bookmark^ --collapse -m <msg>
    

    For a revset to specify all descendants of a revision, excluding the revision itself, use the following revset:

    children(bookmark)::
    

    Note that a non-linear history at this point can create unexpected results (in particular, the use of children() here assumes only a single child revision).

    Remember to enable the rebase extension in your hgrc file for this.