187 '''Returns true if path matches [keyword] pattern |
187 '''Returns true if path matches [keyword] pattern |
188 and is not a symbolic link. |
188 and is not a symbolic link. |
189 Caveat: localrepository._link fails on Windows.''' |
189 Caveat: localrepository._link fails on Windows.''' |
190 return self.match(path) and not 'l' in flagfunc(path) |
190 return self.match(path) and not 'l' in flagfunc(path) |
191 |
191 |
192 def overwrite(self, node, expand, candidates): |
192 def overwrite(self, ctx, candidates, iswctx, expand): |
193 '''Overwrites selected files expanding/shrinking keywords.''' |
193 '''Overwrites selected files expanding/shrinking keywords.''' |
194 ctx = self.repo[node] |
|
195 mf = ctx.manifest() |
194 mf = ctx.manifest() |
196 if node is not None: # commit, record |
195 if self.record: |
197 candidates = [f for f in ctx.files() if f in mf] |
196 candidates = [f for f in ctx.files() if f in mf] |
198 candidates = [f for f in candidates if self.iskwfile(f, ctx.flags)] |
197 candidates = [f for f in candidates if self.iskwfile(f, ctx.flags)] |
199 if candidates: |
198 if candidates: |
200 self.restrict = True # do not expand when reading |
199 self.restrict = True # do not expand when reading |
201 msg = (expand and _('overwriting %s expanding keywords\n') |
200 msg = (expand and _('overwriting %s expanding keywords\n') |
202 or _('overwriting %s shrinking keywords\n')) |
201 or _('overwriting %s shrinking keywords\n')) |
203 for f in candidates: |
202 for f in candidates: |
204 if not self.record: |
203 if not self.record: |
205 data = self.repo.file(f).read(mf[f]) |
204 data = self.repo.file(f).read(mf[f]) |
206 else: |
205 else: |
207 data = self.repo.wread(f) |
206 data = self.repo.wread(f) |
208 if util.binary(data): |
207 if util.binary(data): |
209 continue |
208 continue |
210 if expand: |
209 if expand: |
211 if node is None: |
210 if iswctx: |
212 ctx = self.repo.filectx(f, fileid=mf[f]).changectx() |
211 ctx = self.repo.filectx(f, fileid=mf[f]).changectx() |
213 data, found = self.substitute(data, f, ctx, |
212 data, found = self.substitute(data, f, ctx, |
214 self.re_kw.subn) |
213 self.re_kw.subn) |
215 else: |
214 else: |
216 found = self.re_kw.search(data) |
215 found = self.re_kw.search(data) |
217 if found: |
216 if found: |
218 self.ui.note(msg % f) |
217 self.ui.note(msg % f) |
219 self.repo.wwrite(f, data, mf.flags(f)) |
218 self.repo.wwrite(f, data, mf.flags(f)) |
220 if node is None: |
219 if iswctx: |
221 self.repo.dirstate.normal(f) |
220 self.repo.dirstate.normal(f) |
|
221 elif self.record: |
|
222 self.repo.dirstate.normallookup(f) |
222 self.restrict = False |
223 self.restrict = False |
223 |
224 |
224 def shrinktext(self, text): |
225 def shrinktext(self, text): |
225 '''Unconditionally removes all keyword substitutions from text.''' |
226 '''Unconditionally removes all keyword substitutions from text.''' |
226 return self.re_kw.sub(r'$\1$', text) |
227 return self.re_kw.sub(r'$\1$', text) |
282 raise util.Abort(_('[keyword] patterns cannot match')) |
283 raise util.Abort(_('[keyword] patterns cannot match')) |
283 raise util.Abort(_('no [keyword] patterns configured')) |
284 raise util.Abort(_('no [keyword] patterns configured')) |
284 |
285 |
285 def _kwfwrite(ui, repo, expand, *pats, **opts): |
286 def _kwfwrite(ui, repo, expand, *pats, **opts): |
286 '''Selects files and passes them to kwtemplater.overwrite.''' |
287 '''Selects files and passes them to kwtemplater.overwrite.''' |
287 if len(repo[None].parents()) > 1: |
288 wctx = repo[None] |
|
289 if len(wctx.parents()) > 1: |
288 raise util.Abort(_('outstanding uncommitted merge')) |
290 raise util.Abort(_('outstanding uncommitted merge')) |
289 kwt = kwtools['templater'] |
291 kwt = kwtools['templater'] |
290 wlock = repo.wlock() |
292 wlock = repo.wlock() |
291 try: |
293 try: |
292 status = _status(ui, repo, kwt, *pats, **opts) |
294 status = _status(ui, repo, kwt, *pats, **opts) |
293 modified, added, removed, deleted, unknown, ignored, clean = status |
295 modified, added, removed, deleted, unknown, ignored, clean = status |
294 if modified or added or removed or deleted: |
296 if modified or added or removed or deleted: |
295 raise util.Abort(_('outstanding uncommitted changes')) |
297 raise util.Abort(_('outstanding uncommitted changes')) |
296 kwt.overwrite(None, expand, clean) |
298 kwt.overwrite(wctx, clean, True, expand) |
297 finally: |
299 finally: |
298 wlock.release() |
300 wlock.release() |
299 |
301 |
300 def demo(ui, repo, *args, **opts): |
302 def demo(ui, repo, *args, **opts): |
301 '''print [keywordmaps] configuration and an expansion example |
303 '''print [keywordmaps] configuration and an expansion example |
494 |
496 |
495 def kwcommitctx(self, ctx, error=False): |
497 def kwcommitctx(self, ctx, error=False): |
496 n = super(kwrepo, self).commitctx(ctx, error) |
498 n = super(kwrepo, self).commitctx(ctx, error) |
497 # no lock needed, only called from repo.commit() which already locks |
499 # no lock needed, only called from repo.commit() which already locks |
498 if not kwt.record: |
500 if not kwt.record: |
499 kwt.overwrite(n, True, None) |
501 kwt.overwrite(self[n], sorted(ctx.added() + ctx.modified()), |
|
502 False, True) |
500 return n |
503 return n |
501 |
504 |
502 # monkeypatches |
505 # monkeypatches |
503 def kwpatchfile_init(orig, self, ui, fname, opener, |
506 def kwpatchfile_init(orig, self, ui, fname, opener, |
504 missing=False, eolmode=None): |
507 missing=False, eolmode=None): |
529 try: |
532 try: |
530 # record returns 0 even when nothing has changed |
533 # record returns 0 even when nothing has changed |
531 # therefore compare nodes before and after |
534 # therefore compare nodes before and after |
532 ctx = repo['.'] |
535 ctx = repo['.'] |
533 ret = orig(ui, repo, commitfunc, *pats, **opts) |
536 ret = orig(ui, repo, commitfunc, *pats, **opts) |
534 if ctx != repo['.']: |
537 recordctx = repo['.'] |
535 kwt.overwrite('.', True, None) |
538 if ctx != recordctx: |
|
539 kwt.overwrite(recordctx, None, False, True) |
536 return ret |
540 return ret |
537 finally: |
541 finally: |
538 wlock.release() |
542 wlock.release() |
539 |
543 |
540 repo.__class__ = kwrepo |
544 repo.__class__ = kwrepo |