100 |
100 |
101 def utcdate(date): |
101 def utcdate(date): |
102 '''Returns hgdate in cvs-like UTC format.''' |
102 '''Returns hgdate in cvs-like UTC format.''' |
103 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
103 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
104 |
104 |
105 |
|
106 # make keyword tools accessible |
105 # make keyword tools accessible |
107 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']} |
106 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']} |
108 |
|
109 # store originals of monkeypatches to be done at end of reposetup |
|
110 # that is, only if needed |
|
111 _patchfile_init = patch.patchfile.__init__ |
|
112 _patch_diff = patch.diff |
|
113 _webcommands_changeset = webcommands.changeset |
|
114 _webcommands_filediff = webcommands.filediff |
|
115 |
|
116 def _kwpatchfile_init(self, ui, fname, missing=False): |
|
117 '''Monkeypatch/wrap patch.patchfile.__init__ to avoid |
|
118 rejects or conflicts due to expanded keywords in working dir.''' |
|
119 _patchfile_init(self, ui, fname, missing=missing) |
|
120 # shrink keywords read from working dir |
|
121 kwt = kwtools['templater'] |
|
122 self.lines = kwt.shrinklines(self.fname, self.lines) |
|
123 |
|
124 def _kw_diff(repo, node1=None, node2=None, files=None, match=util.always, |
|
125 fp=None, changes=None, opts=None): |
|
126 '''Monkeypatch patch.diff to avoid expansion except when |
|
127 comparing against working dir.''' |
|
128 if node2 is not None: |
|
129 kwtools['templater'].matcher = util.never |
|
130 elif node1 is not None and node1 != repo.changectx().node(): |
|
131 kwtools['templater'].restrict = True |
|
132 _patch_diff(repo, node1=node1, node2=node2, files=files, match=match, |
|
133 fp=fp, changes=changes, opts=opts) |
|
134 |
|
135 def _kwweb_changeset(web, req, tmpl): |
|
136 '''Wraps webcommands.changeset turning off keyword expansion.''' |
|
137 kwtools['templater'].matcher = util.never |
|
138 return _webcommands_changeset(web, req, tmpl) |
|
139 |
|
140 def _kwweb_filediff(web, req, tmpl): |
|
141 '''Wraps webcommands.filediff turning off keyword expansion.''' |
|
142 kwtools['templater'].matcher = util.never |
|
143 return _webcommands_filediff(web, req, tmpl) |
|
144 |
107 |
145 |
108 |
146 class kwtemplater(object): |
109 class kwtemplater(object): |
147 ''' |
110 ''' |
148 Sets up keyword templates, corresponding keyword regex, and |
111 Sets up keyword templates, corresponding keyword regex, and |
265 class kwfilelog(filelog.filelog): |
228 class kwfilelog(filelog.filelog): |
266 ''' |
229 ''' |
267 Subclass of filelog to hook into its read, add, cmp methods. |
230 Subclass of filelog to hook into its read, add, cmp methods. |
268 Keywords are "stored" unexpanded, and processed on reading. |
231 Keywords are "stored" unexpanded, and processed on reading. |
269 ''' |
232 ''' |
270 def __init__(self, opener, path): |
233 def __init__(self, opener, kwt, path): |
271 super(kwfilelog, self).__init__(opener, path) |
234 super(kwfilelog, self).__init__(opener, path) |
272 self.kwt = kwtools['templater'] |
235 self.kwt = kwt |
273 self.path = path |
236 self.path = path |
274 |
237 |
275 def read(self, node): |
238 def read(self, node): |
276 '''Expands keywords when reading filelog.''' |
239 '''Expands keywords when reading filelog.''' |
277 data = super(kwfilelog, self).read(node) |
240 data = super(kwfilelog, self).read(node) |
469 '''Sets up repo as kwrepo for keyword substitution. |
432 '''Sets up repo as kwrepo for keyword substitution. |
470 Overrides file method to return kwfilelog instead of filelog |
433 Overrides file method to return kwfilelog instead of filelog |
471 if file matches user configuration. |
434 if file matches user configuration. |
472 Wraps commit to overwrite configured files with updated |
435 Wraps commit to overwrite configured files with updated |
473 keyword substitutions. |
436 keyword substitutions. |
474 This is done for local repos only, and only if there are |
437 Monkeypatches patch and webcommands.''' |
475 files configured at all for keyword substitution.''' |
|
476 |
438 |
477 try: |
439 try: |
478 if (not repo.local() or not kwtools['inc'] |
440 if (not repo.local() or not kwtools['inc'] |
479 or kwtools['hgcmd'] in nokwcommands.split() |
441 or kwtools['hgcmd'] in nokwcommands.split() |
480 or '.hg' in util.splitpath(repo.root) |
442 or '.hg' in util.splitpath(repo.root) |
487 |
449 |
488 class kwrepo(repo.__class__): |
450 class kwrepo(repo.__class__): |
489 def file(self, f): |
451 def file(self, f): |
490 if f[0] == '/': |
452 if f[0] == '/': |
491 f = f[1:] |
453 f = f[1:] |
492 return kwfilelog(self.sopener, f) |
454 return kwfilelog(self.sopener, kwt, f) |
493 |
455 |
494 def wread(self, filename): |
456 def wread(self, filename): |
495 data = super(kwrepo, self).wread(filename) |
457 data = super(kwrepo, self).wread(filename) |
496 return kwt.wread(filename, data) |
458 return kwt.wread(filename, data) |
497 |
459 |
536 repo.hook('commit', node=node, parent1=_p1, parent2=_p2) |
498 repo.hook('commit', node=node, parent1=_p1, parent2=_p2) |
537 return node |
499 return node |
538 finally: |
500 finally: |
539 del wlock, lock |
501 del wlock, lock |
540 |
502 |
|
503 # monkeypatches |
|
504 def kwpatchfile_init(self, ui, fname, missing=False): |
|
505 '''Monkeypatch/wrap patch.patchfile.__init__ to avoid |
|
506 rejects or conflicts due to expanded keywords in working dir.''' |
|
507 patchfile_init(self, ui, fname, missing=missing) |
|
508 # shrink keywords read from working dir |
|
509 self.lines = kwt.shrinklines(self.fname, self.lines) |
|
510 |
|
511 def kw_diff(repo, node1=None, node2=None, files=None, match=util.always, |
|
512 fp=None, changes=None, opts=None): |
|
513 '''Monkeypatch patch.diff to avoid expansion except when |
|
514 comparing against working dir.''' |
|
515 if node2 is not None: |
|
516 kwt.matcher = util.never |
|
517 elif node1 is not None and node1 != repo.changectx().node(): |
|
518 kwt.restrict = True |
|
519 patch_diff(repo, node1=node1, node2=node2, files=files, match=match, |
|
520 fp=fp, changes=changes, opts=opts) |
|
521 |
|
522 def kwweb_changeset(web, req, tmpl): |
|
523 '''Wraps webcommands.changeset turning off keyword expansion.''' |
|
524 kwt.matcher = util.never |
|
525 return webcommands_changeset(web, req, tmpl) |
|
526 |
|
527 def kwweb_filediff(web, req, tmpl): |
|
528 '''Wraps webcommands.filediff turning off keyword expansion.''' |
|
529 kwt.matcher = util.never |
|
530 return webcommands_filediff(web, req, tmpl) |
|
531 |
541 repo.__class__ = kwrepo |
532 repo.__class__ = kwrepo |
542 patch.patchfile.__init__ = _kwpatchfile_init |
533 |
543 patch.diff = _kw_diff |
534 patchfile_init = patch.patchfile.__init__ |
544 webcommands.changeset = webcommands.rev = _kwweb_changeset |
535 patch_diff = patch.diff |
545 webcommands.filediff = webcommands.diff = _kwweb_filediff |
536 webcommands_changeset = webcommands.changeset |
|
537 webcommands_filediff = webcommands.filediff |
|
538 |
|
539 patch.patchfile.__init__ = kwpatchfile_init |
|
540 patch.diff = kw_diff |
|
541 webcommands.changeset = webcommands.rev = kwweb_changeset |
|
542 webcommands.filediff = webcommands.diff = kwweb_filediff |
546 |
543 |
547 |
544 |
548 cmdtable = { |
545 cmdtable = { |
549 'kwdemo': |
546 'kwdemo': |
550 (demo, |
547 (demo, |