mercurial

In Mercurial, can obsolete changesets be forced to become not obsolete?


In Mercurial changesets with a successor are marked obsolete.

Can this marker be (forcefully) removed somehow?

After using hg strip to remove the successor, the original changeset is still marked as obsolete and extinct). hg evolve refuses to re-create the successor.

Edit: New solution: hg undo see answer below


Solution

  • The most current or maybe even "bleeding edge" approach to this seems to be using:

    hg rewind

    or its alias

    hg undo

    I say "bleeding edge" because although this command is released and seems to work, I can't find much documented about it, though the hg command line help does include it (below). It may still be considered experimental (as of 2022).

    hg rewind seems potentially intended to replace hg touch.


    Here's an example of it in use:

    % hg rebase --dest=25707 --source=26017 
    rebasing 26017:5c78e2af32cb "message 1"
    rebasing 26018:f156002253b3 "message 2"
    ...
    [command completed successfully Fri Apr 29 09:07:15 2022]
    
    % hg rewind
    rewound to 33 changesets
    (33 changesets obsoleted)
    working directory is now at 0ad018a90b93
    

    The net effect of these commands were to leave things exactly equivalent to where I started. The rewind took about as long as the rebase.


    Built in help states the following:

    % hg undo --help
    hg rewind [--as-divergence] [--exact] [--keep] [--to REV]... [--from REV]...
    
    aliases: undo
    
    rewind a stack of changesets to a previous state
    
        This command can be used to restore stacks of changesets to an obsolete
        state, creating identical copies.
    
        There are two main ways to select the rewind target. Rewinding "from"
        changesets will restore the direct predecessors of these changesets (and
        obsolete the changeset you rewind from). Rewinding "to" will restore the
        changeset you have selected (and obsolete their latest successors).
    
        By default, we rewind from the working directory parents, restoring its
        predecessor.
    
        ...
    
    
    % hg --version
    Mercurial Distributed SCM (version 5.9.2)
    ...
    

    Importantly, the help also includes the following cautions:

    Current rough edges:

    • fold: rewinding to only some of the initially folded changesets will be problematic. The fold result is marked obsolete and the part not rewinded to are "lost". Please use --as-divergence when you need to perform such operation.

    • 'hg rewind' might affect changesets outside the current stack. Without --exact, we also restore ancestors of the rewind target, obsoleting their latest successors (unless --as-divergent is provided). In some case, these latest successors will be on branches unrelated to the changeset you rewind from. (We plan to automatically detect this case in the future)


    Some Mercurial developer-oriented notes about rewind are: