--- a/hgext/keyword.py Fri Oct 08 18:00:19 2010 -0500
+++ b/hgext/keyword.py Fri Oct 08 18:39:46 2010 +0100
@@ -96,7 +96,7 @@
# hg commands that trigger expansion only when writing to working dir,
# not when reading filelog, and unexpand when reading from working dir
-restricted = 'merge record qrecord resolve transplant'
+restricted = 'merge kwexpand kwshrink record qrecord resolve transplant'
# commands using dorecord
recordcommands = 'record qrecord'
@@ -138,6 +138,12 @@
templates.update(kwsets[ui.configbool('keywordset', 'svn')])
return templates
+def _shrinktext(text, subfunc):
+ '''Helper for keyword expansion removal in text.
+ Depending on subfunc also returns number of substitutions.'''
+ return subfunc(r'$\1$', text)
+
+
class kwtemplater(object):
'''
Sets up keyword templates, corresponding keyword regex, and
@@ -191,49 +197,44 @@
Caveat: localrepository._link fails on Windows.'''
return self.match(path) and not 'l' in flagfunc(path)
- def overwrite(self, ctx, candidates, iswctx, expand, changed):
+ def overwrite(self, ctx, candidates, lookup, expand):
'''Overwrites selected files expanding/shrinking keywords.'''
- if changed is not None:
- candidates = [f for f in candidates if f in changed]
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'
+ if not candidates:
+ return
+ commit = self.restrict and not lookup
+ if self.restrict or expand and lookup:
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 and not rollback:
- data = self.repo.file(f).read(mf[f])
- else:
- data = self.repo.wread(f)
- if util.binary(data):
- continue
- if expand:
- if iswctx:
- ctx = self.repo.filectx(f, fileid=mf[f]).changectx()
- data, found = self.substitute(data, f, ctx,
- self.re_kw.subn)
- else:
- found = self.re_kw.search(data)
- if found:
- self.ui.note(msg % f)
- self.repo.wwrite(f, data, mf.flags(f))
- if iswctx and not rollback:
- self.repo.dirstate.normal(f)
- elif self.record:
- self.repo.dirstate.normallookup(f)
- self.restrict = restrict
-
- def shrinktext(self, text):
- '''Unconditionally removes all keyword substitutions from text.'''
- return self.re_kw.sub(r'$\1$', text)
+ fctx = ctx
+ msg = (expand and _('overwriting %s expanding keywords\n')
+ or _('overwriting %s shrinking keywords\n'))
+ for f in candidates:
+ if self.restrict:
+ data = self.repo.file(f).read(mf[f])
+ else:
+ data = self.repo.wread(f)
+ if util.binary(data):
+ continue
+ if expand:
+ if lookup:
+ fctx = self.repo.filectx(f, fileid=mf[f]).changectx()
+ data, found = self.substitute(data, f, fctx, self.re_kw.subn)
+ elif self.restrict:
+ found = self.re_kw.search(data)
+ else:
+ data, found = _shrinktext(data, self.re_kw.subn)
+ if found:
+ self.ui.note(msg % f)
+ self.repo.wwrite(f, data, ctx.flags(f))
+ if commit:
+ self.repo.dirstate.normal(f)
+ elif self.record:
+ self.repo.dirstate.normallookup(f)
def shrink(self, fname, text):
'''Returns text with all keyword substitutions removed.'''
if self.match(fname) and not util.binary(text):
- return self.shrinktext(text)
+ return _shrinktext(text, self.re_kw.sub)
return text
def shrinklines(self, fname, lines):
@@ -241,7 +242,7 @@
if self.match(fname):
text = ''.join(lines)
if not util.binary(text):
- return self.shrinktext(text).splitlines(True)
+ return _shrinktext(text, self.re_kw.sub).splitlines(True)
return lines
def wread(self, fname, data):
@@ -299,7 +300,7 @@
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, None)
+ kwt.overwrite(wctx, clean, True, expand)
finally:
wlock.release()
@@ -502,8 +503,11 @@
n = super(kwrepo, self).commitctx(ctx, error)
# no lock needed, only called from repo.commit() which already locks
if not kwt.record:
+ restrict = kwt.restrict
+ kwt.restrict = True
kwt.overwrite(self[n], sorted(ctx.added() + ctx.modified()),
- False, True, None)
+ False, True)
+ kwt.restrict = restrict
return n
def rollback(self, dryrun=False):
@@ -515,8 +519,10 @@
if not dryrun:
ctx = self['.']
modified, added = self[None].status()[:2]
- kwt.overwrite(ctx, added, True, False, changed)
- kwt.overwrite(ctx, modified, True, True, changed)
+ modified = [f for f in modified if f in changed]
+ added = [f for f in added if f in changed]
+ kwt.overwrite(ctx, added, True, False)
+ kwt.overwrite(ctx, modified, True, True)
return ret
finally:
wlock.release()
@@ -551,8 +557,10 @@
ret = orig(ui, repo, commitfunc, *pats, **opts)
recordctx = repo['.']
if ctx != recordctx:
- kwt.overwrite(recordctx, recordctx.files(),
- False, True, recordctx)
+ candidates = [f for f in recordctx.files() if f in recordctx]
+ kwt.restrict = False
+ kwt.overwrite(recordctx, candidates, False, True)
+ kwt.restrict = True
return ret
finally:
wlock.release()