D6005: uncommit: added interactive mode and modified fixdirstate(issue6062)

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Thu Mar 7 14:04:15 EST 2019

martinvonz added a comment.

  As I said a while ago on IRC, it feels like `_fixdirstate()` should not need an `interactive` flag, and it should not even need to be specifically for uncommit. It feels like it should work the same for any case where we move to a different commit without changing the working copy, such as uncommit, unamend, amend, fix (though we may want optimized code paths for some of them). So I took this patch and tried the most naive attempt at unifying the interactive version with the non-interactive version, namely to just drop the code for the interactive path (see patch below). Surprisingly, all tests pass :) So maybe you can just apply the below patch and clean it up (drop the `if True`), or maybe you need to add tests.
    diff --git a/hgext/uncommit.py b/hgext/uncommit.py
    --- a/hgext/uncommit.py
    +++ b/hgext/uncommit.py
    @@ -109,59 +109,10 @@ def _fixdirstate(repo, oldctx, newctx, m
         oldctx to a copy of oldctx not containing changed files matched by
    -    ctx = repo['.']
         ds = repo.dirstate
         ds.setparents(newctx.node(), node.nullid)
         copies = dict(ds.copies())
    -    if interactive:
    -        # In interactive cases, we will find the status between oldctx and ctx
    -        # and considering only the files which are changed between oldctx and
    -        # ctx, and the status of what changed between oldctx and ctx will help
    -        # us in defining the exact behavior
    -        s = oldctx.status(ctx, match=match)
    -        for f in s.modified:
    -            # These are files which are modified between oldctx and ctx which
    -            # contains two cases: 1) Were modified in oldctx and some
    -            # modifications are uncommitted
    -            # 2) Were added in oldctx but some part is uncommitted (this cannot
    -            # contain the case when added files are uncommitted completely as
    -            # that will result in status as removed not modified.)
    -            # Also any modifications to a removed file will result the status as
    -            # added, so we have only two cases. So in either of the cases, the
    -            # resulting status can be modified or clean.
    -            if ds[f] == 'r':
    -                # But the file is removed in the working directory, leaving that
    -                # as removed
    -                continue
    -            ds.normallookup(f)
    -        for f in s.added:
    -            # These are the files which are added between oldctx and ctx(new
    -            # one), which means the files which were removed in oldctx
    -            # but uncommitted completely while making the ctx
    -            # This file should be marked as removed if the working directory
    -            # does not adds it back. If it's adds it back, we do a normallookup.
    -            # The file can't be removed in working directory, because it was
    -            # removed in oldctx
    -            if ds[f] == 'a':
    -                ds.normallookup(f)
    -                continue
    -            ds.remove(f)
    -        for f in s.removed:
    -            # These are files which are removed between oldctx and ctx, which
    -            # means the files which were added in oldctx and were completely
    -            # uncommitted in ctx. If a added file is partially uncommitted, that
    -            # would have resulted in modified status, not removed.
    -            # So a file added in a commit, and uncommitting that addition must
    -            # result in file being stated as unknown.
    -            if ds[f] == 'r':
    -                # The working directory say it's removed, so lets make the file
    -                # unknown
    -                ds.drop(f)
    -                continue
    -            ds.add(f)
    -    else:
    +    if True:
             s = newctx.status(oldctx, match=match)
             for f in s.modified:
                 if ds[f] == 'r':

  rHG Mercurial


To: taapas1128, #hg-reviewers
Cc: pulkit, martinvonz, mercurial-devel

More information about the Mercurial-devel mailing list