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