Mercurial > evolve
comparison hgext/evolve.py @ 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 | cfe1b9d3e5d9 |
children | 742c1ce79a96 |
comparison
equal
deleted
inserted
replaced
1056:edfb9a0ad085 | 1058:00bc31523074 |
---|---|
1857 opts['message'] = repo['.'].description() | 1857 opts['message'] = repo['.'].description() |
1858 _resolveoptions(ui, opts) | 1858 _resolveoptions(ui, opts) |
1859 _alias, commitcmd = cmdutil.findcmd('commit', commands.table) | 1859 _alias, commitcmd = cmdutil.findcmd('commit', commands.table) |
1860 return commitcmd[0](ui, repo, *pats, **opts) | 1860 return commitcmd[0](ui, repo, *pats, **opts) |
1861 | 1861 |
1862 def _commitfiltered(repo, ctx, match): | 1862 |
1863 def _touchedbetween(repo, source, dest, match=None): | |
1864 touched = set() | |
1865 for files in repo.status(source, dest, match=match)[:3]: | |
1866 touched.update(files) | |
1867 return touched | |
1868 | |
1869 def _commitfiltered(repo, ctx, match, target=None): | |
1863 """Recommit ctx with changed files not in match. Return the new | 1870 """Recommit ctx with changed files not in match. Return the new |
1864 node identifier, or None if nothing changed. | 1871 node identifier, or None if nothing changed. |
1865 """ | 1872 """ |
1866 base = ctx.p1() | 1873 base = ctx.p1() |
1867 m, a, r = repo.status(base, ctx)[:3] | 1874 if target is None: |
1868 allfiles = set(m + a + r) | 1875 target = base |
1869 files = set(f for f in allfiles if not match(f)) | 1876 # ctx |
1870 if files == allfiles: | 1877 initialfiles = _touchedbetween(repo, base, ctx) |
1878 if base == target: | |
1879 affected = set(f for f in initialfiles if match(f)) | |
1880 newcontent = set() | |
1881 else: | |
1882 affected = _touchedbetween(repo, target, ctx, match=match) | |
1883 newcontent = _touchedbetween(repo, target, base, match=match) | |
1884 # The commit touchs all existing files | |
1885 # + all file that needs a new content | |
1886 # - the file affected bny uncommit with the same content than base. | |
1887 files = (initialfiles - affected) | newcontent | |
1888 if not newcontent and files == initialfiles: | |
1871 return None | 1889 return None |
1872 | 1890 |
1873 # Filter copies | 1891 # Filter copies |
1874 copied = copies.pathcopies(base, ctx) | 1892 copied = copies.pathcopies(target, ctx) |
1875 copied = dict((src, dst) for src, dst in copied.iteritems() | 1893 copied = dict((src, dst) for src, dst in copied.iteritems() |
1876 if dst in files) | 1894 if dst in files) |
1877 def filectxfn(repo, memctx, path): | 1895 def filectxfn(repo, memctx, path, contentctx=ctx, redirect=newcontent): |
1878 if path not in ctx: | 1896 if path in redirect: |
1897 return filectxfn(repo, memctx, path, contentctx=target, redirect=()) | |
1898 if path not in contentctx: | |
1879 raise IOError() | 1899 raise IOError() |
1880 fctx = ctx[path] | 1900 fctx = contentctx[path] |
1881 flags = fctx.flags() | 1901 flags = fctx.flags() |
1882 mctx = memfilectx(repo, fctx.path(), fctx.data(), | 1902 mctx = memfilectx(repo, fctx.path(), fctx.data(), |
1883 islink='l' in flags, | 1903 islink='l' in flags, |
1884 isexec='x' in flags, | 1904 isexec='x' in flags, |
1885 copied=copied.get(path)) | 1905 copied=copied.get(path)) |
1941 src = None | 1961 src = None |
1942 ds.copy(src, dst) | 1962 ds.copy(src, dst) |
1943 | 1963 |
1944 @command('^uncommit', | 1964 @command('^uncommit', |
1945 [('a', 'all', None, _('uncommit all changes when no arguments given')), | 1965 [('a', 'all', None, _('uncommit all changes when no arguments given')), |
1966 ('r', 'rev', '', _('revert commit content to REV instead')), | |
1946 ] + commands.walkopts, | 1967 ] + commands.walkopts, |
1947 _('[OPTION]... [NAME]')) | 1968 _('[OPTION]... [NAME]')) |
1948 def uncommit(ui, repo, *pats, **opts): | 1969 def uncommit(ui, repo, *pats, **opts): |
1949 """move changes from parent revision to working directory | 1970 """move changes from parent revision to working directory |
1950 | 1971 |
1953 without the selected changes is created, becomes the checked out | 1974 without the selected changes is created, becomes the checked out |
1954 revision, and obsoletes the previous one. | 1975 revision, and obsoletes the previous one. |
1955 | 1976 |
1956 The --include option specifies patterns to uncommit. | 1977 The --include option specifies patterns to uncommit. |
1957 The --exclude option specifies patterns to keep in the commit. | 1978 The --exclude option specifies patterns to keep in the commit. |
1979 | |
1980 The --rev argument let you change the commit file to a content of another | |
1981 revision. It still does not change the content of your file in the working | |
1982 directory. | |
1958 | 1983 |
1959 Return 0 if changed files are uncommitted. | 1984 Return 0 if changed files are uncommitted. |
1960 """ | 1985 """ |
1961 | 1986 |
1962 wlock = lock = tr = None | 1987 wlock = lock = tr = None |
1974 if len(old.parents()) > 1: | 1999 if len(old.parents()) > 1: |
1975 raise util.Abort(_("cannot uncommit merge changeset")) | 2000 raise util.Abort(_("cannot uncommit merge changeset")) |
1976 oldphase = old.phase() | 2001 oldphase = old.phase() |
1977 updatebookmarks = _bookmarksupdater(repo, old.node()) | 2002 updatebookmarks = _bookmarksupdater(repo, old.node()) |
1978 | 2003 |
2004 | |
2005 rev = None | |
2006 if opts.get('rev'): | |
2007 rev = scmutil.revsingle(repo, opts.get('rev')) | |
2008 | |
1979 # Recommit the filtered changeset | 2009 # Recommit the filtered changeset |
1980 tr = repo.transaction('uncommit') | 2010 tr = repo.transaction('uncommit') |
1981 newid = None | 2011 newid = None |
1982 if (pats or opts.get('include') or opts.get('exclude') | 2012 if (pats or opts.get('include') or opts.get('exclude') |
1983 or opts.get('all')): | 2013 or opts.get('all')): |
1984 match = scmutil.match(old, pats, opts) | 2014 match = scmutil.match(old, pats, opts) |
1985 newid = _commitfiltered(repo, old, match) | 2015 newid = _commitfiltered(repo, old, match, target=rev) |
1986 if newid is None: | 2016 if newid is None: |
1987 raise util.Abort(_('nothing to uncommit'), | 2017 raise util.Abort(_('nothing to uncommit'), |
1988 hint=_("use --all to uncommit all files")) | 2018 hint=_("use --all to uncommit all files")) |
1989 # Move local changes on filtered changeset | 2019 # Move local changes on filtered changeset |
1990 createmarkers(repo, [(old, (repo[newid],))]) | 2020 createmarkers(repo, [(old, (repo[newid],))]) |