diff --git a/hgext/keyword.py b/hgext/keyword.py --- a/hgext/keyword.py +++ b/hgext/keyword.py @@ -92,8 +92,7 @@ commands.optionalrepo += ' kwdemo' # hg commands that do not act on keywords nokwcommands = ('add addremove annotate bundle copy export grep incoming init' - ' log outgoing push rename rollback tip verify' - ' convert email glog') + ' log outgoing push rename tip verify convert email glog') # hg commands that trigger expansion only when writing to working dir, # not when reading filelog, and unexpand when reading from working dir @@ -192,19 +191,20 @@ class kwtemplater(object): Caveat: localrepository._link fails on Windows.''' return self.match(path) and not 'l' in flagfunc(path) - def overwrite(self, ctx, candidates, iswctx, expand): + def overwrite(self, ctx, candidates, iswctx, expand, cfiles): '''Overwrites selected files expanding/shrinking keywords.''' - if self.record: - candidates = [f for f in ctx.files() if f in ctx] + if cfiles is not None: + candidates = [f for f in candidates if f in cfiles] candidates = [f for f in candidates if self.iskwfile(f, ctx.flags)] if candidates: restrict = self.restrict self.restrict = True # do not expand when reading + rollback = kwtools['hgcmd'] == 'rollback' mf = ctx.manifest() msg = (expand and _('overwriting %s expanding keywords\n') or _('overwriting %s shrinking keywords\n')) for f in candidates: - if not self.record: + if not self.record and not rollback: data = self.repo.file(f).read(mf[f]) else: data = self.repo.wread(f) @@ -220,7 +220,7 @@ class kwtemplater(object): if found: self.ui.note(msg % f) self.repo.wwrite(f, data, mf.flags(f)) - if iswctx: + if iswctx and not rollback: self.repo.dirstate.normal(f) elif self.record: self.repo.dirstate.normallookup(f) @@ -299,7 +299,7 @@ def _kwfwrite(ui, repo, expand, *pats, * modified, added, removed, deleted, unknown, ignored, clean = status if modified or added or removed or deleted: raise util.Abort(_('outstanding uncommitted changes')) - kwt.overwrite(wctx, clean, True, expand) + kwt.overwrite(wctx, clean, True, expand, None) finally: wlock.release() @@ -503,9 +503,24 @@ def reposetup(ui, repo): # no lock needed, only called from repo.commit() which already locks if not kwt.record: kwt.overwrite(self[n], sorted(ctx.added() + ctx.modified()), - False, True) + False, True, None) return n + def rollback(self, dryrun=False): + wlock = repo.wlock() + try: + if not dryrun: + cfiles = self['.'].files() + ret = super(kwrepo, self).rollback(dryrun) + if not dryrun: + ctx = self['.'] + modified, added = super(kwrepo, self).status()[:2] + kwt.overwrite(ctx, added, True, False, cfiles) + kwt.overwrite(ctx, modified, True, True, cfiles) + return ret + finally: + wlock.release() + # monkeypatches def kwpatchfile_init(orig, self, ui, fname, opener, missing=False, eolmode=None): @@ -536,7 +551,8 @@ def reposetup(ui, repo): ret = orig(ui, repo, commitfunc, *pats, **opts) recordctx = repo['.'] if ctx != recordctx: - kwt.overwrite(recordctx, None, False, True) + kwt.overwrite(recordctx, recordctx.files(), + False, True, recordctx) return ret finally: wlock.release() diff --git a/tests/test-keyword.t b/tests/test-keyword.t --- a/tests/test-keyword.t +++ b/tests/test-keyword.t @@ -375,10 +375,48 @@ File a should be clean $ hg status -A a C a + $ rm msg - $ rm msg - $ hg rollback +rollback and revert expansion + + $ cat a + expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $ + foo + do not process $Id: + xxx $ + bar + $ hg --verbose rollback rolling back to revision 2 (undo commit) + overwriting a expanding keywords + $ hg status a + M a + $ cat a + expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $ + foo + do not process $Id: + xxx $ + bar + $ echo '$Id$' > y + $ echo '$Id$' > z + $ hg add y + $ hg commit -Am "rollback only" z + $ cat z + $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $ + $ hg --verbose rollback + rolling back to revision 2 (undo commit) + overwriting z shrinking keywords + +Only z should be overwritten + + $ hg status a y z + M a + A y + A z + $ cat z + $Id$ + $ hg forget y z + $ rm y z + $ hg update -C 1 files updated, 0 files merged, 0 files removed, 0 files unresolved