Mercurial > evolve
changeset 1058:00bc31523074
uncommit: add a --rev argument
The uncommit command now taks a --rev argument. This lets restore the file
content in the current commit to another revision (instead of just is parent
content). This still does not touch the working directory content.\
This allow the longly awaited:
hg uncommit --hidden --rev 'precursors(.)'
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Fri, 15 Aug 2014 00:46:23 -0700 |
parents | edfb9a0ad085 |
children | d1baf69b935c |
files | README hgext/evolve.py tests/test-tutorial.t tests/test-uncommit.t |
diffstat | 4 files changed, 71 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/README Thu Aug 14 15:26:55 2014 -0700 +++ b/README Fri Aug 15 00:46:23 2014 -0700 @@ -57,6 +57,10 @@ Changelog ========= +4.2.0 -- + +- uncommit: add a --rev argument + 4.1.0 -- 2014-08-08 - amend: add -D/--current-date option
--- a/hgext/evolve.py Thu Aug 14 15:26:55 2014 -0700 +++ b/hgext/evolve.py Fri Aug 15 00:46:23 2014 -0700 @@ -1859,25 +1859,45 @@ _alias, commitcmd = cmdutil.findcmd('commit', commands.table) return commitcmd[0](ui, repo, *pats, **opts) -def _commitfiltered(repo, ctx, match): + +def _touchedbetween(repo, source, dest, match=None): + touched = set() + for files in repo.status(source, dest, match=match)[:3]: + touched.update(files) + return touched + +def _commitfiltered(repo, ctx, match, target=None): """Recommit ctx with changed files not in match. Return the new node identifier, or None if nothing changed. """ base = ctx.p1() - m, a, r = repo.status(base, ctx)[:3] - allfiles = set(m + a + r) - files = set(f for f in allfiles if not match(f)) - if files == allfiles: + if target is None: + target = base + # ctx + initialfiles = _touchedbetween(repo, base, ctx) + if base == target: + affected = set(f for f in initialfiles if match(f)) + newcontent = set() + else: + affected = _touchedbetween(repo, target, ctx, match=match) + newcontent = _touchedbetween(repo, target, base, match=match) + # The commit touchs all existing files + # + all file that needs a new content + # - the file affected bny uncommit with the same content than base. + files = (initialfiles - affected) | newcontent + if not newcontent and files == initialfiles: return None # Filter copies - copied = copies.pathcopies(base, ctx) + copied = copies.pathcopies(target, ctx) copied = dict((src, dst) for src, dst in copied.iteritems() if dst in files) - def filectxfn(repo, memctx, path): - if path not in ctx: + def filectxfn(repo, memctx, path, contentctx=ctx, redirect=newcontent): + if path in redirect: + return filectxfn(repo, memctx, path, contentctx=target, redirect=()) + if path not in contentctx: raise IOError() - fctx = ctx[path] + fctx = contentctx[path] flags = fctx.flags() mctx = memfilectx(repo, fctx.path(), fctx.data(), islink='l' in flags, @@ -1943,6 +1963,7 @@ @command('^uncommit', [('a', 'all', None, _('uncommit all changes when no arguments given')), + ('r', 'rev', '', _('revert commit content to REV instead')), ] + commands.walkopts, _('[OPTION]... [NAME]')) def uncommit(ui, repo, *pats, **opts): @@ -1956,6 +1977,10 @@ The --include option specifies patterns to uncommit. The --exclude option specifies patterns to keep in the commit. + The --rev argument let you change the commit file to a content of another + revision. It still does not change the content of your file in the working + directory. + Return 0 if changed files are uncommitted. """ @@ -1976,13 +2001,18 @@ oldphase = old.phase() updatebookmarks = _bookmarksupdater(repo, old.node()) + + rev = None + if opts.get('rev'): + rev = scmutil.revsingle(repo, opts.get('rev')) + # Recommit the filtered changeset tr = repo.transaction('uncommit') newid = None if (pats or opts.get('include') or opts.get('exclude') or opts.get('all')): match = scmutil.match(old, pats, opts) - newid = _commitfiltered(repo, old, match) + newid = _commitfiltered(repo, old, match, target=rev) if newid is None: raise util.Abort(_('nothing to uncommit'), hint=_("use --all to uncommit all files"))
--- a/tests/test-tutorial.t Thu Aug 14 15:26:55 2014 -0700 +++ b/tests/test-tutorial.t Fri Aug 15 00:46:23 2014 -0700 @@ -446,11 +446,16 @@ The --include option specifies patterns to uncommit. The --exclude option specifies patterns to keep in the commit. + The --rev argument let you change the commit file to a content of another + revision. It still does not change the content of your file in the working + directory. + Return 0 if changed files are uncommitted. options: -a --all uncommit all changes when no arguments given + -r --rev VALUE revert commit content to REV instead -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns
--- a/tests/test-uncommit.t Thu Aug 14 15:26:55 2014 -0700 +++ b/tests/test-uncommit.t Fri Aug 15 00:46:23 2014 -0700 @@ -336,3 +336,25 @@ [8] touncommit $ hg uncommit aa 1 new unstable changesets + +Test uncommiting agains a different base + + $ hg cat b --rev . + b + b + $ hg cat b --rev .^ + b + $ hg cat b --rev 0 + b: no such file in rev 07f494440405 + [1] + $ hg uncommit --rev 0 b + $ hg cat b --rev . + b: no such file in rev 5b27f6b17da2 + [1] + +Test uncommiting precursors + + $ hg uncommit --hidden --rev 'precursors(.)' b + $ hg cat b --rev . + b + b