42 |
42 |
43 Keywords are only expanded in local repositories and not logged by |
43 Keywords are only expanded in local repositories and not logged by |
44 Mercurial internally. The mechanism can be regarded as a convenience |
44 Mercurial internally. The mechanism can be regarded as a convenience |
45 for the current user and may be turned off anytime. |
45 for the current user and may be turned off anytime. |
46 |
46 |
47 Substitution takes place on every commit and update of the working |
47 The exansion works in 2 modes: |
48 repository. |
48 1) working mode: substitution takes place on every commit and |
|
49 update of the working repository. |
|
50 2) archive mode: substitution is only triggered by "hg archive". |
49 |
51 |
50 Caveat: "hg import" might fail if the patches were exported from a |
52 Caveat: "hg import" might fail if the patches were exported from a |
51 repo with a different/no keyword setup, whereas "hg unbundle" is |
53 repo with a different/no keyword setup, whereas "hg unbundle" is |
52 safe. |
54 safe. |
53 |
55 |
58 [keyword] |
60 [keyword] |
59 # filename patterns for expansion are configured in this section |
61 # filename patterns for expansion are configured in this section |
60 # files matching patterns with value 'ignore' are ignored |
62 # files matching patterns with value 'ignore' are ignored |
61 **.py = ## expand keywords in all python files |
63 **.py = ## expand keywords in all python files |
62 x* = ignore ## but ignore files matching "x*" |
64 x* = ignore ## but ignore files matching "x*" |
|
65 ** = archive ## keywords in all textfiles are expanded |
|
66 ## when creating a distribution |
|
67 y* = noarchive ## keywords in files matching "y*" are not expanded |
|
68 ## on archive creation |
63 ... |
69 ... |
64 [keywordmaps] |
70 [keywordmaps] |
65 # custom hg template maps _replace_ the CVS-like default ones |
71 # custom hg template maps _replace_ the CVS-like default ones |
66 HGdate = {date|rfc822date} |
72 HGdate = {date|rfc822date} |
67 lastlog = {desc} ## same as {desc|firstline} in this context |
73 lastlog = {desc} ## same as {desc|firstline} in this context |
81 ''' |
87 ''' |
82 |
88 |
83 try: |
89 try: |
84 from mercurial.demandload import * # stable |
90 from mercurial.demandload import * # stable |
85 from mercurial.i18n import gettext as _ |
91 from mercurial.i18n import gettext as _ |
86 demandload(globals(), 'mercurial:cmdutil,templater,util') |
92 demandload(globals(), 'mercurial:commands,fancyopts,templater,util') |
87 demandload(globals(), 'mercurial:context,filelog,revlog') |
93 demandload(globals(), 'mercurial:cmdutil,context,filelog,revlog') |
88 demandload(globals(), 're time') |
94 demandload(globals(), 're sys time') |
89 except ImportError: # demandimport |
95 except ImportError: # demandimport |
90 from mercurial.i18n import _ |
96 from mercurial.i18n import _ |
91 from mercurial import cmdutil, templater, util |
97 from mercurial import commands, fancyopts, templater, util |
92 from mercurial import context, filelog, revlog |
98 from mercurial import cmdutil, context, filelog, revlog |
93 import re, time |
99 import re, sys, time |
94 |
100 |
95 deftemplates = { |
101 deftemplates = { |
96 'Revision': '{node|short}', |
102 'Revision': '{node|short}', |
97 'Author': '{author|user}', |
103 'Author': '{author|user}', |
98 'Date': '{date|utcdate}', |
104 'Date': '{date|utcdate}', |
103 } |
109 } |
104 |
110 |
105 def utcdate(date): |
111 def utcdate(date): |
106 '''Returns hgdate in cvs-like UTC format.''' |
112 '''Returns hgdate in cvs-like UTC format.''' |
107 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
113 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
|
114 |
|
115 def getcmd(ui): |
|
116 '''Returns current hg command.''' |
|
117 # commands.parse(ui, sys.argv[1:])[0] breaks "hg diff -r" |
|
118 try: |
|
119 args = fancyopts.fancyopts(sys.argv[1:], commands.globalopts, {}) |
|
120 except fancyopts.getopt.GetoptError, inst: |
|
121 raise commands.ParseError(None, inst) |
|
122 if args: |
|
123 cmd = args[0] |
|
124 aliases, i = commands.findcmd(ui, cmd) |
|
125 return aliases[0] |
108 |
126 |
109 class kwtemplater(object): |
127 class kwtemplater(object): |
110 ''' |
128 ''' |
111 Sets up keyword templates, corresponding keyword regex, and |
129 Sets up keyword templates, corresponding keyword regex, and |
112 provides keyword substitution functions. |
130 provides keyword substitution functions. |
208 files configured at all for keyword substitution.''' |
226 files configured at all for keyword substitution.''' |
209 |
227 |
210 if not repo.local(): |
228 if not repo.local(): |
211 return |
229 return |
212 |
230 |
213 inc, exc = [], ['.hg*'] |
231 archivemode = (getcmd(repo.ui) == 'archive') |
|
232 |
|
233 inc, exc, archive, noarchive = [], ['.hg*'], [], ['.hg*'] |
214 for pat, opt in repo.ui.configitems('keyword'): |
234 for pat, opt in repo.ui.configitems('keyword'): |
215 if opt != 'ignore': |
235 if opt == 'archive': |
|
236 archive.append(pat) |
|
237 elif opt == 'noarchive': |
|
238 noarchive.append(pat) |
|
239 elif opt == 'ignore': |
|
240 exc.append(pat) |
|
241 else: |
216 inc.append(pat) |
242 inc.append(pat) |
217 else: |
243 if archivemode: |
218 exc.append(pat) |
244 inc, exc = archive, noarchive |
219 if not inc: |
245 if not inc: |
220 return |
246 return |
221 |
247 |
222 repo.kwfmatcher = util.matcher(repo.root, inc=inc, exc=exc)[1] |
248 repo.kwfmatcher = util.matcher(repo.root, inc=inc, exc=exc)[1] |
223 |
249 |