##// END OF EJS Templates
cmdutil: use '[committemplate]' section like as map file for style definition...
FUJIWARA Katsunori -
r22013:de5cee8b default
parent child Browse files
Show More
@@ -1,2643 +1,2647 b''
1 # cmdutil.py - help for command processing in mercurial
1 # cmdutil.py - help for command processing in mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex, nullid, nullrev, short
8 from node import hex, nullid, nullrev, short
9 from i18n import _
9 from i18n import _
10 import os, sys, errno, re, tempfile
10 import os, sys, errno, re, tempfile
11 import util, scmutil, templater, patch, error, templatekw, revlog, copies
11 import util, scmutil, templater, patch, error, templatekw, revlog, copies
12 import match as matchmod
12 import match as matchmod
13 import context, repair, graphmod, revset, phases, obsolete, pathutil
13 import context, repair, graphmod, revset, phases, obsolete, pathutil
14 import changelog
14 import changelog
15 import bookmarks
15 import bookmarks
16 import lock as lockmod
16 import lock as lockmod
17
17
18 def parsealiases(cmd):
18 def parsealiases(cmd):
19 return cmd.lstrip("^").split("|")
19 return cmd.lstrip("^").split("|")
20
20
21 def findpossible(cmd, table, strict=False):
21 def findpossible(cmd, table, strict=False):
22 """
22 """
23 Return cmd -> (aliases, command table entry)
23 Return cmd -> (aliases, command table entry)
24 for each matching command.
24 for each matching command.
25 Return debug commands (or their aliases) only if no normal command matches.
25 Return debug commands (or their aliases) only if no normal command matches.
26 """
26 """
27 choice = {}
27 choice = {}
28 debugchoice = {}
28 debugchoice = {}
29
29
30 if cmd in table:
30 if cmd in table:
31 # short-circuit exact matches, "log" alias beats "^log|history"
31 # short-circuit exact matches, "log" alias beats "^log|history"
32 keys = [cmd]
32 keys = [cmd]
33 else:
33 else:
34 keys = table.keys()
34 keys = table.keys()
35
35
36 for e in keys:
36 for e in keys:
37 aliases = parsealiases(e)
37 aliases = parsealiases(e)
38 found = None
38 found = None
39 if cmd in aliases:
39 if cmd in aliases:
40 found = cmd
40 found = cmd
41 elif not strict:
41 elif not strict:
42 for a in aliases:
42 for a in aliases:
43 if a.startswith(cmd):
43 if a.startswith(cmd):
44 found = a
44 found = a
45 break
45 break
46 if found is not None:
46 if found is not None:
47 if aliases[0].startswith("debug") or found.startswith("debug"):
47 if aliases[0].startswith("debug") or found.startswith("debug"):
48 debugchoice[found] = (aliases, table[e])
48 debugchoice[found] = (aliases, table[e])
49 else:
49 else:
50 choice[found] = (aliases, table[e])
50 choice[found] = (aliases, table[e])
51
51
52 if not choice and debugchoice:
52 if not choice and debugchoice:
53 choice = debugchoice
53 choice = debugchoice
54
54
55 return choice
55 return choice
56
56
57 def findcmd(cmd, table, strict=True):
57 def findcmd(cmd, table, strict=True):
58 """Return (aliases, command table entry) for command string."""
58 """Return (aliases, command table entry) for command string."""
59 choice = findpossible(cmd, table, strict)
59 choice = findpossible(cmd, table, strict)
60
60
61 if cmd in choice:
61 if cmd in choice:
62 return choice[cmd]
62 return choice[cmd]
63
63
64 if len(choice) > 1:
64 if len(choice) > 1:
65 clist = choice.keys()
65 clist = choice.keys()
66 clist.sort()
66 clist.sort()
67 raise error.AmbiguousCommand(cmd, clist)
67 raise error.AmbiguousCommand(cmd, clist)
68
68
69 if choice:
69 if choice:
70 return choice.values()[0]
70 return choice.values()[0]
71
71
72 raise error.UnknownCommand(cmd)
72 raise error.UnknownCommand(cmd)
73
73
74 def findrepo(p):
74 def findrepo(p):
75 while not os.path.isdir(os.path.join(p, ".hg")):
75 while not os.path.isdir(os.path.join(p, ".hg")):
76 oldp, p = p, os.path.dirname(p)
76 oldp, p = p, os.path.dirname(p)
77 if p == oldp:
77 if p == oldp:
78 return None
78 return None
79
79
80 return p
80 return p
81
81
82 def bailifchanged(repo):
82 def bailifchanged(repo):
83 if repo.dirstate.p2() != nullid:
83 if repo.dirstate.p2() != nullid:
84 raise util.Abort(_('outstanding uncommitted merge'))
84 raise util.Abort(_('outstanding uncommitted merge'))
85 modified, added, removed, deleted = repo.status()[:4]
85 modified, added, removed, deleted = repo.status()[:4]
86 if modified or added or removed or deleted:
86 if modified or added or removed or deleted:
87 raise util.Abort(_('uncommitted changes'))
87 raise util.Abort(_('uncommitted changes'))
88 ctx = repo[None]
88 ctx = repo[None]
89 for s in sorted(ctx.substate):
89 for s in sorted(ctx.substate):
90 if ctx.sub(s).dirty():
90 if ctx.sub(s).dirty():
91 raise util.Abort(_("uncommitted changes in subrepo %s") % s)
91 raise util.Abort(_("uncommitted changes in subrepo %s") % s)
92
92
93 def logmessage(ui, opts):
93 def logmessage(ui, opts):
94 """ get the log message according to -m and -l option """
94 """ get the log message according to -m and -l option """
95 message = opts.get('message')
95 message = opts.get('message')
96 logfile = opts.get('logfile')
96 logfile = opts.get('logfile')
97
97
98 if message and logfile:
98 if message and logfile:
99 raise util.Abort(_('options --message and --logfile are mutually '
99 raise util.Abort(_('options --message and --logfile are mutually '
100 'exclusive'))
100 'exclusive'))
101 if not message and logfile:
101 if not message and logfile:
102 try:
102 try:
103 if logfile == '-':
103 if logfile == '-':
104 message = ui.fin.read()
104 message = ui.fin.read()
105 else:
105 else:
106 message = '\n'.join(util.readfile(logfile).splitlines())
106 message = '\n'.join(util.readfile(logfile).splitlines())
107 except IOError, inst:
107 except IOError, inst:
108 raise util.Abort(_("can't read commit message '%s': %s") %
108 raise util.Abort(_("can't read commit message '%s': %s") %
109 (logfile, inst.strerror))
109 (logfile, inst.strerror))
110 return message
110 return message
111
111
112 def getcommiteditor(edit=False, finishdesc=None, extramsg=None,
112 def getcommiteditor(edit=False, finishdesc=None, extramsg=None,
113 editform='', **opts):
113 editform='', **opts):
114 """get appropriate commit message editor according to '--edit' option
114 """get appropriate commit message editor according to '--edit' option
115
115
116 'finishdesc' is a function to be called with edited commit message
116 'finishdesc' is a function to be called with edited commit message
117 (= 'description' of the new changeset) just after editing, but
117 (= 'description' of the new changeset) just after editing, but
118 before checking empty-ness. It should return actual text to be
118 before checking empty-ness. It should return actual text to be
119 stored into history. This allows to change description before
119 stored into history. This allows to change description before
120 storing.
120 storing.
121
121
122 'extramsg' is a extra message to be shown in the editor instead of
122 'extramsg' is a extra message to be shown in the editor instead of
123 'Leave message empty to abort commit' line. 'HG: ' prefix and EOL
123 'Leave message empty to abort commit' line. 'HG: ' prefix and EOL
124 is automatically added.
124 is automatically added.
125
125
126 'editform' is a dot-separated list of names, to distinguish
126 'editform' is a dot-separated list of names, to distinguish
127 the purpose of commit text editing.
127 the purpose of commit text editing.
128
128
129 'getcommiteditor' returns 'commitforceeditor' regardless of
129 'getcommiteditor' returns 'commitforceeditor' regardless of
130 'edit', if one of 'finishdesc' or 'extramsg' is specified, because
130 'edit', if one of 'finishdesc' or 'extramsg' is specified, because
131 they are specific for usage in MQ.
131 they are specific for usage in MQ.
132 """
132 """
133 if edit or finishdesc or extramsg:
133 if edit or finishdesc or extramsg:
134 return lambda r, c, s: commitforceeditor(r, c, s,
134 return lambda r, c, s: commitforceeditor(r, c, s,
135 finishdesc=finishdesc,
135 finishdesc=finishdesc,
136 extramsg=extramsg,
136 extramsg=extramsg,
137 editform=editform)
137 editform=editform)
138 elif editform:
138 elif editform:
139 return lambda r, c, s: commiteditor(r, c, s, editform=editform)
139 return lambda r, c, s: commiteditor(r, c, s, editform=editform)
140 else:
140 else:
141 return commiteditor
141 return commiteditor
142
142
143 def loglimit(opts):
143 def loglimit(opts):
144 """get the log limit according to option -l/--limit"""
144 """get the log limit according to option -l/--limit"""
145 limit = opts.get('limit')
145 limit = opts.get('limit')
146 if limit:
146 if limit:
147 try:
147 try:
148 limit = int(limit)
148 limit = int(limit)
149 except ValueError:
149 except ValueError:
150 raise util.Abort(_('limit must be a positive integer'))
150 raise util.Abort(_('limit must be a positive integer'))
151 if limit <= 0:
151 if limit <= 0:
152 raise util.Abort(_('limit must be positive'))
152 raise util.Abort(_('limit must be positive'))
153 else:
153 else:
154 limit = None
154 limit = None
155 return limit
155 return limit
156
156
157 def makefilename(repo, pat, node, desc=None,
157 def makefilename(repo, pat, node, desc=None,
158 total=None, seqno=None, revwidth=None, pathname=None):
158 total=None, seqno=None, revwidth=None, pathname=None):
159 node_expander = {
159 node_expander = {
160 'H': lambda: hex(node),
160 'H': lambda: hex(node),
161 'R': lambda: str(repo.changelog.rev(node)),
161 'R': lambda: str(repo.changelog.rev(node)),
162 'h': lambda: short(node),
162 'h': lambda: short(node),
163 'm': lambda: re.sub('[^\w]', '_', str(desc))
163 'm': lambda: re.sub('[^\w]', '_', str(desc))
164 }
164 }
165 expander = {
165 expander = {
166 '%': lambda: '%',
166 '%': lambda: '%',
167 'b': lambda: os.path.basename(repo.root),
167 'b': lambda: os.path.basename(repo.root),
168 }
168 }
169
169
170 try:
170 try:
171 if node:
171 if node:
172 expander.update(node_expander)
172 expander.update(node_expander)
173 if node:
173 if node:
174 expander['r'] = (lambda:
174 expander['r'] = (lambda:
175 str(repo.changelog.rev(node)).zfill(revwidth or 0))
175 str(repo.changelog.rev(node)).zfill(revwidth or 0))
176 if total is not None:
176 if total is not None:
177 expander['N'] = lambda: str(total)
177 expander['N'] = lambda: str(total)
178 if seqno is not None:
178 if seqno is not None:
179 expander['n'] = lambda: str(seqno)
179 expander['n'] = lambda: str(seqno)
180 if total is not None and seqno is not None:
180 if total is not None and seqno is not None:
181 expander['n'] = lambda: str(seqno).zfill(len(str(total)))
181 expander['n'] = lambda: str(seqno).zfill(len(str(total)))
182 if pathname is not None:
182 if pathname is not None:
183 expander['s'] = lambda: os.path.basename(pathname)
183 expander['s'] = lambda: os.path.basename(pathname)
184 expander['d'] = lambda: os.path.dirname(pathname) or '.'
184 expander['d'] = lambda: os.path.dirname(pathname) or '.'
185 expander['p'] = lambda: pathname
185 expander['p'] = lambda: pathname
186
186
187 newname = []
187 newname = []
188 patlen = len(pat)
188 patlen = len(pat)
189 i = 0
189 i = 0
190 while i < patlen:
190 while i < patlen:
191 c = pat[i]
191 c = pat[i]
192 if c == '%':
192 if c == '%':
193 i += 1
193 i += 1
194 c = pat[i]
194 c = pat[i]
195 c = expander[c]()
195 c = expander[c]()
196 newname.append(c)
196 newname.append(c)
197 i += 1
197 i += 1
198 return ''.join(newname)
198 return ''.join(newname)
199 except KeyError, inst:
199 except KeyError, inst:
200 raise util.Abort(_("invalid format spec '%%%s' in output filename") %
200 raise util.Abort(_("invalid format spec '%%%s' in output filename") %
201 inst.args[0])
201 inst.args[0])
202
202
203 def makefileobj(repo, pat, node=None, desc=None, total=None,
203 def makefileobj(repo, pat, node=None, desc=None, total=None,
204 seqno=None, revwidth=None, mode='wb', modemap=None,
204 seqno=None, revwidth=None, mode='wb', modemap=None,
205 pathname=None):
205 pathname=None):
206
206
207 writable = mode not in ('r', 'rb')
207 writable = mode not in ('r', 'rb')
208
208
209 if not pat or pat == '-':
209 if not pat or pat == '-':
210 fp = writable and repo.ui.fout or repo.ui.fin
210 fp = writable and repo.ui.fout or repo.ui.fin
211 if util.safehasattr(fp, 'fileno'):
211 if util.safehasattr(fp, 'fileno'):
212 return os.fdopen(os.dup(fp.fileno()), mode)
212 return os.fdopen(os.dup(fp.fileno()), mode)
213 else:
213 else:
214 # if this fp can't be duped properly, return
214 # if this fp can't be duped properly, return
215 # a dummy object that can be closed
215 # a dummy object that can be closed
216 class wrappedfileobj(object):
216 class wrappedfileobj(object):
217 noop = lambda x: None
217 noop = lambda x: None
218 def __init__(self, f):
218 def __init__(self, f):
219 self.f = f
219 self.f = f
220 def __getattr__(self, attr):
220 def __getattr__(self, attr):
221 if attr == 'close':
221 if attr == 'close':
222 return self.noop
222 return self.noop
223 else:
223 else:
224 return getattr(self.f, attr)
224 return getattr(self.f, attr)
225
225
226 return wrappedfileobj(fp)
226 return wrappedfileobj(fp)
227 if util.safehasattr(pat, 'write') and writable:
227 if util.safehasattr(pat, 'write') and writable:
228 return pat
228 return pat
229 if util.safehasattr(pat, 'read') and 'r' in mode:
229 if util.safehasattr(pat, 'read') and 'r' in mode:
230 return pat
230 return pat
231 fn = makefilename(repo, pat, node, desc, total, seqno, revwidth, pathname)
231 fn = makefilename(repo, pat, node, desc, total, seqno, revwidth, pathname)
232 if modemap is not None:
232 if modemap is not None:
233 mode = modemap.get(fn, mode)
233 mode = modemap.get(fn, mode)
234 if mode == 'wb':
234 if mode == 'wb':
235 modemap[fn] = 'ab'
235 modemap[fn] = 'ab'
236 return open(fn, mode)
236 return open(fn, mode)
237
237
238 def openrevlog(repo, cmd, file_, opts):
238 def openrevlog(repo, cmd, file_, opts):
239 """opens the changelog, manifest, a filelog or a given revlog"""
239 """opens the changelog, manifest, a filelog or a given revlog"""
240 cl = opts['changelog']
240 cl = opts['changelog']
241 mf = opts['manifest']
241 mf = opts['manifest']
242 msg = None
242 msg = None
243 if cl and mf:
243 if cl and mf:
244 msg = _('cannot specify --changelog and --manifest at the same time')
244 msg = _('cannot specify --changelog and --manifest at the same time')
245 elif cl or mf:
245 elif cl or mf:
246 if file_:
246 if file_:
247 msg = _('cannot specify filename with --changelog or --manifest')
247 msg = _('cannot specify filename with --changelog or --manifest')
248 elif not repo:
248 elif not repo:
249 msg = _('cannot specify --changelog or --manifest '
249 msg = _('cannot specify --changelog or --manifest '
250 'without a repository')
250 'without a repository')
251 if msg:
251 if msg:
252 raise util.Abort(msg)
252 raise util.Abort(msg)
253
253
254 r = None
254 r = None
255 if repo:
255 if repo:
256 if cl:
256 if cl:
257 r = repo.unfiltered().changelog
257 r = repo.unfiltered().changelog
258 elif mf:
258 elif mf:
259 r = repo.manifest
259 r = repo.manifest
260 elif file_:
260 elif file_:
261 filelog = repo.file(file_)
261 filelog = repo.file(file_)
262 if len(filelog):
262 if len(filelog):
263 r = filelog
263 r = filelog
264 if not r:
264 if not r:
265 if not file_:
265 if not file_:
266 raise error.CommandError(cmd, _('invalid arguments'))
266 raise error.CommandError(cmd, _('invalid arguments'))
267 if not os.path.isfile(file_):
267 if not os.path.isfile(file_):
268 raise util.Abort(_("revlog '%s' not found") % file_)
268 raise util.Abort(_("revlog '%s' not found") % file_)
269 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
269 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
270 file_[:-2] + ".i")
270 file_[:-2] + ".i")
271 return r
271 return r
272
272
273 def copy(ui, repo, pats, opts, rename=False):
273 def copy(ui, repo, pats, opts, rename=False):
274 # called with the repo lock held
274 # called with the repo lock held
275 #
275 #
276 # hgsep => pathname that uses "/" to separate directories
276 # hgsep => pathname that uses "/" to separate directories
277 # ossep => pathname that uses os.sep to separate directories
277 # ossep => pathname that uses os.sep to separate directories
278 cwd = repo.getcwd()
278 cwd = repo.getcwd()
279 targets = {}
279 targets = {}
280 after = opts.get("after")
280 after = opts.get("after")
281 dryrun = opts.get("dry_run")
281 dryrun = opts.get("dry_run")
282 wctx = repo[None]
282 wctx = repo[None]
283
283
284 def walkpat(pat):
284 def walkpat(pat):
285 srcs = []
285 srcs = []
286 badstates = after and '?' or '?r'
286 badstates = after and '?' or '?r'
287 m = scmutil.match(repo[None], [pat], opts, globbed=True)
287 m = scmutil.match(repo[None], [pat], opts, globbed=True)
288 for abs in repo.walk(m):
288 for abs in repo.walk(m):
289 state = repo.dirstate[abs]
289 state = repo.dirstate[abs]
290 rel = m.rel(abs)
290 rel = m.rel(abs)
291 exact = m.exact(abs)
291 exact = m.exact(abs)
292 if state in badstates:
292 if state in badstates:
293 if exact and state == '?':
293 if exact and state == '?':
294 ui.warn(_('%s: not copying - file is not managed\n') % rel)
294 ui.warn(_('%s: not copying - file is not managed\n') % rel)
295 if exact and state == 'r':
295 if exact and state == 'r':
296 ui.warn(_('%s: not copying - file has been marked for'
296 ui.warn(_('%s: not copying - file has been marked for'
297 ' remove\n') % rel)
297 ' remove\n') % rel)
298 continue
298 continue
299 # abs: hgsep
299 # abs: hgsep
300 # rel: ossep
300 # rel: ossep
301 srcs.append((abs, rel, exact))
301 srcs.append((abs, rel, exact))
302 return srcs
302 return srcs
303
303
304 # abssrc: hgsep
304 # abssrc: hgsep
305 # relsrc: ossep
305 # relsrc: ossep
306 # otarget: ossep
306 # otarget: ossep
307 def copyfile(abssrc, relsrc, otarget, exact):
307 def copyfile(abssrc, relsrc, otarget, exact):
308 abstarget = pathutil.canonpath(repo.root, cwd, otarget)
308 abstarget = pathutil.canonpath(repo.root, cwd, otarget)
309 if '/' in abstarget:
309 if '/' in abstarget:
310 # We cannot normalize abstarget itself, this would prevent
310 # We cannot normalize abstarget itself, this would prevent
311 # case only renames, like a => A.
311 # case only renames, like a => A.
312 abspath, absname = abstarget.rsplit('/', 1)
312 abspath, absname = abstarget.rsplit('/', 1)
313 abstarget = repo.dirstate.normalize(abspath) + '/' + absname
313 abstarget = repo.dirstate.normalize(abspath) + '/' + absname
314 reltarget = repo.pathto(abstarget, cwd)
314 reltarget = repo.pathto(abstarget, cwd)
315 target = repo.wjoin(abstarget)
315 target = repo.wjoin(abstarget)
316 src = repo.wjoin(abssrc)
316 src = repo.wjoin(abssrc)
317 state = repo.dirstate[abstarget]
317 state = repo.dirstate[abstarget]
318
318
319 scmutil.checkportable(ui, abstarget)
319 scmutil.checkportable(ui, abstarget)
320
320
321 # check for collisions
321 # check for collisions
322 prevsrc = targets.get(abstarget)
322 prevsrc = targets.get(abstarget)
323 if prevsrc is not None:
323 if prevsrc is not None:
324 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
324 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
325 (reltarget, repo.pathto(abssrc, cwd),
325 (reltarget, repo.pathto(abssrc, cwd),
326 repo.pathto(prevsrc, cwd)))
326 repo.pathto(prevsrc, cwd)))
327 return
327 return
328
328
329 # check for overwrites
329 # check for overwrites
330 exists = os.path.lexists(target)
330 exists = os.path.lexists(target)
331 samefile = False
331 samefile = False
332 if exists and abssrc != abstarget:
332 if exists and abssrc != abstarget:
333 if (repo.dirstate.normalize(abssrc) ==
333 if (repo.dirstate.normalize(abssrc) ==
334 repo.dirstate.normalize(abstarget)):
334 repo.dirstate.normalize(abstarget)):
335 if not rename:
335 if not rename:
336 ui.warn(_("%s: can't copy - same file\n") % reltarget)
336 ui.warn(_("%s: can't copy - same file\n") % reltarget)
337 return
337 return
338 exists = False
338 exists = False
339 samefile = True
339 samefile = True
340
340
341 if not after and exists or after and state in 'mn':
341 if not after and exists or after and state in 'mn':
342 if not opts['force']:
342 if not opts['force']:
343 ui.warn(_('%s: not overwriting - file exists\n') %
343 ui.warn(_('%s: not overwriting - file exists\n') %
344 reltarget)
344 reltarget)
345 return
345 return
346
346
347 if after:
347 if after:
348 if not exists:
348 if not exists:
349 if rename:
349 if rename:
350 ui.warn(_('%s: not recording move - %s does not exist\n') %
350 ui.warn(_('%s: not recording move - %s does not exist\n') %
351 (relsrc, reltarget))
351 (relsrc, reltarget))
352 else:
352 else:
353 ui.warn(_('%s: not recording copy - %s does not exist\n') %
353 ui.warn(_('%s: not recording copy - %s does not exist\n') %
354 (relsrc, reltarget))
354 (relsrc, reltarget))
355 return
355 return
356 elif not dryrun:
356 elif not dryrun:
357 try:
357 try:
358 if exists:
358 if exists:
359 os.unlink(target)
359 os.unlink(target)
360 targetdir = os.path.dirname(target) or '.'
360 targetdir = os.path.dirname(target) or '.'
361 if not os.path.isdir(targetdir):
361 if not os.path.isdir(targetdir):
362 os.makedirs(targetdir)
362 os.makedirs(targetdir)
363 if samefile:
363 if samefile:
364 tmp = target + "~hgrename"
364 tmp = target + "~hgrename"
365 os.rename(src, tmp)
365 os.rename(src, tmp)
366 os.rename(tmp, target)
366 os.rename(tmp, target)
367 else:
367 else:
368 util.copyfile(src, target)
368 util.copyfile(src, target)
369 srcexists = True
369 srcexists = True
370 except IOError, inst:
370 except IOError, inst:
371 if inst.errno == errno.ENOENT:
371 if inst.errno == errno.ENOENT:
372 ui.warn(_('%s: deleted in working copy\n') % relsrc)
372 ui.warn(_('%s: deleted in working copy\n') % relsrc)
373 srcexists = False
373 srcexists = False
374 else:
374 else:
375 ui.warn(_('%s: cannot copy - %s\n') %
375 ui.warn(_('%s: cannot copy - %s\n') %
376 (relsrc, inst.strerror))
376 (relsrc, inst.strerror))
377 return True # report a failure
377 return True # report a failure
378
378
379 if ui.verbose or not exact:
379 if ui.verbose or not exact:
380 if rename:
380 if rename:
381 ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
381 ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
382 else:
382 else:
383 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
383 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
384
384
385 targets[abstarget] = abssrc
385 targets[abstarget] = abssrc
386
386
387 # fix up dirstate
387 # fix up dirstate
388 scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
388 scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
389 dryrun=dryrun, cwd=cwd)
389 dryrun=dryrun, cwd=cwd)
390 if rename and not dryrun:
390 if rename and not dryrun:
391 if not after and srcexists and not samefile:
391 if not after and srcexists and not samefile:
392 util.unlinkpath(repo.wjoin(abssrc))
392 util.unlinkpath(repo.wjoin(abssrc))
393 wctx.forget([abssrc])
393 wctx.forget([abssrc])
394
394
395 # pat: ossep
395 # pat: ossep
396 # dest ossep
396 # dest ossep
397 # srcs: list of (hgsep, hgsep, ossep, bool)
397 # srcs: list of (hgsep, hgsep, ossep, bool)
398 # return: function that takes hgsep and returns ossep
398 # return: function that takes hgsep and returns ossep
399 def targetpathfn(pat, dest, srcs):
399 def targetpathfn(pat, dest, srcs):
400 if os.path.isdir(pat):
400 if os.path.isdir(pat):
401 abspfx = pathutil.canonpath(repo.root, cwd, pat)
401 abspfx = pathutil.canonpath(repo.root, cwd, pat)
402 abspfx = util.localpath(abspfx)
402 abspfx = util.localpath(abspfx)
403 if destdirexists:
403 if destdirexists:
404 striplen = len(os.path.split(abspfx)[0])
404 striplen = len(os.path.split(abspfx)[0])
405 else:
405 else:
406 striplen = len(abspfx)
406 striplen = len(abspfx)
407 if striplen:
407 if striplen:
408 striplen += len(os.sep)
408 striplen += len(os.sep)
409 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
409 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
410 elif destdirexists:
410 elif destdirexists:
411 res = lambda p: os.path.join(dest,
411 res = lambda p: os.path.join(dest,
412 os.path.basename(util.localpath(p)))
412 os.path.basename(util.localpath(p)))
413 else:
413 else:
414 res = lambda p: dest
414 res = lambda p: dest
415 return res
415 return res
416
416
417 # pat: ossep
417 # pat: ossep
418 # dest ossep
418 # dest ossep
419 # srcs: list of (hgsep, hgsep, ossep, bool)
419 # srcs: list of (hgsep, hgsep, ossep, bool)
420 # return: function that takes hgsep and returns ossep
420 # return: function that takes hgsep and returns ossep
421 def targetpathafterfn(pat, dest, srcs):
421 def targetpathafterfn(pat, dest, srcs):
422 if matchmod.patkind(pat):
422 if matchmod.patkind(pat):
423 # a mercurial pattern
423 # a mercurial pattern
424 res = lambda p: os.path.join(dest,
424 res = lambda p: os.path.join(dest,
425 os.path.basename(util.localpath(p)))
425 os.path.basename(util.localpath(p)))
426 else:
426 else:
427 abspfx = pathutil.canonpath(repo.root, cwd, pat)
427 abspfx = pathutil.canonpath(repo.root, cwd, pat)
428 if len(abspfx) < len(srcs[0][0]):
428 if len(abspfx) < len(srcs[0][0]):
429 # A directory. Either the target path contains the last
429 # A directory. Either the target path contains the last
430 # component of the source path or it does not.
430 # component of the source path or it does not.
431 def evalpath(striplen):
431 def evalpath(striplen):
432 score = 0
432 score = 0
433 for s in srcs:
433 for s in srcs:
434 t = os.path.join(dest, util.localpath(s[0])[striplen:])
434 t = os.path.join(dest, util.localpath(s[0])[striplen:])
435 if os.path.lexists(t):
435 if os.path.lexists(t):
436 score += 1
436 score += 1
437 return score
437 return score
438
438
439 abspfx = util.localpath(abspfx)
439 abspfx = util.localpath(abspfx)
440 striplen = len(abspfx)
440 striplen = len(abspfx)
441 if striplen:
441 if striplen:
442 striplen += len(os.sep)
442 striplen += len(os.sep)
443 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
443 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
444 score = evalpath(striplen)
444 score = evalpath(striplen)
445 striplen1 = len(os.path.split(abspfx)[0])
445 striplen1 = len(os.path.split(abspfx)[0])
446 if striplen1:
446 if striplen1:
447 striplen1 += len(os.sep)
447 striplen1 += len(os.sep)
448 if evalpath(striplen1) > score:
448 if evalpath(striplen1) > score:
449 striplen = striplen1
449 striplen = striplen1
450 res = lambda p: os.path.join(dest,
450 res = lambda p: os.path.join(dest,
451 util.localpath(p)[striplen:])
451 util.localpath(p)[striplen:])
452 else:
452 else:
453 # a file
453 # a file
454 if destdirexists:
454 if destdirexists:
455 res = lambda p: os.path.join(dest,
455 res = lambda p: os.path.join(dest,
456 os.path.basename(util.localpath(p)))
456 os.path.basename(util.localpath(p)))
457 else:
457 else:
458 res = lambda p: dest
458 res = lambda p: dest
459 return res
459 return res
460
460
461
461
462 pats = scmutil.expandpats(pats)
462 pats = scmutil.expandpats(pats)
463 if not pats:
463 if not pats:
464 raise util.Abort(_('no source or destination specified'))
464 raise util.Abort(_('no source or destination specified'))
465 if len(pats) == 1:
465 if len(pats) == 1:
466 raise util.Abort(_('no destination specified'))
466 raise util.Abort(_('no destination specified'))
467 dest = pats.pop()
467 dest = pats.pop()
468 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
468 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
469 if not destdirexists:
469 if not destdirexists:
470 if len(pats) > 1 or matchmod.patkind(pats[0]):
470 if len(pats) > 1 or matchmod.patkind(pats[0]):
471 raise util.Abort(_('with multiple sources, destination must be an '
471 raise util.Abort(_('with multiple sources, destination must be an '
472 'existing directory'))
472 'existing directory'))
473 if util.endswithsep(dest):
473 if util.endswithsep(dest):
474 raise util.Abort(_('destination %s is not a directory') % dest)
474 raise util.Abort(_('destination %s is not a directory') % dest)
475
475
476 tfn = targetpathfn
476 tfn = targetpathfn
477 if after:
477 if after:
478 tfn = targetpathafterfn
478 tfn = targetpathafterfn
479 copylist = []
479 copylist = []
480 for pat in pats:
480 for pat in pats:
481 srcs = walkpat(pat)
481 srcs = walkpat(pat)
482 if not srcs:
482 if not srcs:
483 continue
483 continue
484 copylist.append((tfn(pat, dest, srcs), srcs))
484 copylist.append((tfn(pat, dest, srcs), srcs))
485 if not copylist:
485 if not copylist:
486 raise util.Abort(_('no files to copy'))
486 raise util.Abort(_('no files to copy'))
487
487
488 errors = 0
488 errors = 0
489 for targetpath, srcs in copylist:
489 for targetpath, srcs in copylist:
490 for abssrc, relsrc, exact in srcs:
490 for abssrc, relsrc, exact in srcs:
491 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
491 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
492 errors += 1
492 errors += 1
493
493
494 if errors:
494 if errors:
495 ui.warn(_('(consider using --after)\n'))
495 ui.warn(_('(consider using --after)\n'))
496
496
497 return errors != 0
497 return errors != 0
498
498
499 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
499 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
500 runargs=None, appendpid=False):
500 runargs=None, appendpid=False):
501 '''Run a command as a service.'''
501 '''Run a command as a service.'''
502
502
503 def writepid(pid):
503 def writepid(pid):
504 if opts['pid_file']:
504 if opts['pid_file']:
505 mode = appendpid and 'a' or 'w'
505 mode = appendpid and 'a' or 'w'
506 fp = open(opts['pid_file'], mode)
506 fp = open(opts['pid_file'], mode)
507 fp.write(str(pid) + '\n')
507 fp.write(str(pid) + '\n')
508 fp.close()
508 fp.close()
509
509
510 if opts['daemon'] and not opts['daemon_pipefds']:
510 if opts['daemon'] and not opts['daemon_pipefds']:
511 # Signal child process startup with file removal
511 # Signal child process startup with file removal
512 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
512 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
513 os.close(lockfd)
513 os.close(lockfd)
514 try:
514 try:
515 if not runargs:
515 if not runargs:
516 runargs = util.hgcmd() + sys.argv[1:]
516 runargs = util.hgcmd() + sys.argv[1:]
517 runargs.append('--daemon-pipefds=%s' % lockpath)
517 runargs.append('--daemon-pipefds=%s' % lockpath)
518 # Don't pass --cwd to the child process, because we've already
518 # Don't pass --cwd to the child process, because we've already
519 # changed directory.
519 # changed directory.
520 for i in xrange(1, len(runargs)):
520 for i in xrange(1, len(runargs)):
521 if runargs[i].startswith('--cwd='):
521 if runargs[i].startswith('--cwd='):
522 del runargs[i]
522 del runargs[i]
523 break
523 break
524 elif runargs[i].startswith('--cwd'):
524 elif runargs[i].startswith('--cwd'):
525 del runargs[i:i + 2]
525 del runargs[i:i + 2]
526 break
526 break
527 def condfn():
527 def condfn():
528 return not os.path.exists(lockpath)
528 return not os.path.exists(lockpath)
529 pid = util.rundetached(runargs, condfn)
529 pid = util.rundetached(runargs, condfn)
530 if pid < 0:
530 if pid < 0:
531 raise util.Abort(_('child process failed to start'))
531 raise util.Abort(_('child process failed to start'))
532 writepid(pid)
532 writepid(pid)
533 finally:
533 finally:
534 try:
534 try:
535 os.unlink(lockpath)
535 os.unlink(lockpath)
536 except OSError, e:
536 except OSError, e:
537 if e.errno != errno.ENOENT:
537 if e.errno != errno.ENOENT:
538 raise
538 raise
539 if parentfn:
539 if parentfn:
540 return parentfn(pid)
540 return parentfn(pid)
541 else:
541 else:
542 return
542 return
543
543
544 if initfn:
544 if initfn:
545 initfn()
545 initfn()
546
546
547 if not opts['daemon']:
547 if not opts['daemon']:
548 writepid(os.getpid())
548 writepid(os.getpid())
549
549
550 if opts['daemon_pipefds']:
550 if opts['daemon_pipefds']:
551 lockpath = opts['daemon_pipefds']
551 lockpath = opts['daemon_pipefds']
552 try:
552 try:
553 os.setsid()
553 os.setsid()
554 except AttributeError:
554 except AttributeError:
555 pass
555 pass
556 os.unlink(lockpath)
556 os.unlink(lockpath)
557 util.hidewindow()
557 util.hidewindow()
558 sys.stdout.flush()
558 sys.stdout.flush()
559 sys.stderr.flush()
559 sys.stderr.flush()
560
560
561 nullfd = os.open(os.devnull, os.O_RDWR)
561 nullfd = os.open(os.devnull, os.O_RDWR)
562 logfilefd = nullfd
562 logfilefd = nullfd
563 if logfile:
563 if logfile:
564 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
564 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
565 os.dup2(nullfd, 0)
565 os.dup2(nullfd, 0)
566 os.dup2(logfilefd, 1)
566 os.dup2(logfilefd, 1)
567 os.dup2(logfilefd, 2)
567 os.dup2(logfilefd, 2)
568 if nullfd not in (0, 1, 2):
568 if nullfd not in (0, 1, 2):
569 os.close(nullfd)
569 os.close(nullfd)
570 if logfile and logfilefd not in (0, 1, 2):
570 if logfile and logfilefd not in (0, 1, 2):
571 os.close(logfilefd)
571 os.close(logfilefd)
572
572
573 if runfn:
573 if runfn:
574 return runfn()
574 return runfn()
575
575
576 def tryimportone(ui, repo, hunk, parents, opts, msgs, updatefunc):
576 def tryimportone(ui, repo, hunk, parents, opts, msgs, updatefunc):
577 """Utility function used by commands.import to import a single patch
577 """Utility function used by commands.import to import a single patch
578
578
579 This function is explicitly defined here to help the evolve extension to
579 This function is explicitly defined here to help the evolve extension to
580 wrap this part of the import logic.
580 wrap this part of the import logic.
581
581
582 The API is currently a bit ugly because it a simple code translation from
582 The API is currently a bit ugly because it a simple code translation from
583 the import command. Feel free to make it better.
583 the import command. Feel free to make it better.
584
584
585 :hunk: a patch (as a binary string)
585 :hunk: a patch (as a binary string)
586 :parents: nodes that will be parent of the created commit
586 :parents: nodes that will be parent of the created commit
587 :opts: the full dict of option passed to the import command
587 :opts: the full dict of option passed to the import command
588 :msgs: list to save commit message to.
588 :msgs: list to save commit message to.
589 (used in case we need to save it when failing)
589 (used in case we need to save it when failing)
590 :updatefunc: a function that update a repo to a given node
590 :updatefunc: a function that update a repo to a given node
591 updatefunc(<repo>, <node>)
591 updatefunc(<repo>, <node>)
592 """
592 """
593 tmpname, message, user, date, branch, nodeid, p1, p2 = \
593 tmpname, message, user, date, branch, nodeid, p1, p2 = \
594 patch.extract(ui, hunk)
594 patch.extract(ui, hunk)
595
595
596 editor = getcommiteditor(editform='import.normal', **opts)
596 editor = getcommiteditor(editform='import.normal', **opts)
597 update = not opts.get('bypass')
597 update = not opts.get('bypass')
598 strip = opts["strip"]
598 strip = opts["strip"]
599 sim = float(opts.get('similarity') or 0)
599 sim = float(opts.get('similarity') or 0)
600 if not tmpname:
600 if not tmpname:
601 return (None, None, False)
601 return (None, None, False)
602 msg = _('applied to working directory')
602 msg = _('applied to working directory')
603
603
604 rejects = False
604 rejects = False
605
605
606 try:
606 try:
607 cmdline_message = logmessage(ui, opts)
607 cmdline_message = logmessage(ui, opts)
608 if cmdline_message:
608 if cmdline_message:
609 # pickup the cmdline msg
609 # pickup the cmdline msg
610 message = cmdline_message
610 message = cmdline_message
611 elif message:
611 elif message:
612 # pickup the patch msg
612 # pickup the patch msg
613 message = message.strip()
613 message = message.strip()
614 else:
614 else:
615 # launch the editor
615 # launch the editor
616 message = None
616 message = None
617 ui.debug('message:\n%s\n' % message)
617 ui.debug('message:\n%s\n' % message)
618
618
619 if len(parents) == 1:
619 if len(parents) == 1:
620 parents.append(repo[nullid])
620 parents.append(repo[nullid])
621 if opts.get('exact'):
621 if opts.get('exact'):
622 if not nodeid or not p1:
622 if not nodeid or not p1:
623 raise util.Abort(_('not a Mercurial patch'))
623 raise util.Abort(_('not a Mercurial patch'))
624 p1 = repo[p1]
624 p1 = repo[p1]
625 p2 = repo[p2 or nullid]
625 p2 = repo[p2 or nullid]
626 elif p2:
626 elif p2:
627 try:
627 try:
628 p1 = repo[p1]
628 p1 = repo[p1]
629 p2 = repo[p2]
629 p2 = repo[p2]
630 # Without any options, consider p2 only if the
630 # Without any options, consider p2 only if the
631 # patch is being applied on top of the recorded
631 # patch is being applied on top of the recorded
632 # first parent.
632 # first parent.
633 if p1 != parents[0]:
633 if p1 != parents[0]:
634 p1 = parents[0]
634 p1 = parents[0]
635 p2 = repo[nullid]
635 p2 = repo[nullid]
636 except error.RepoError:
636 except error.RepoError:
637 p1, p2 = parents
637 p1, p2 = parents
638 else:
638 else:
639 p1, p2 = parents
639 p1, p2 = parents
640
640
641 n = None
641 n = None
642 if update:
642 if update:
643 if p1 != parents[0]:
643 if p1 != parents[0]:
644 updatefunc(repo, p1.node())
644 updatefunc(repo, p1.node())
645 if p2 != parents[1]:
645 if p2 != parents[1]:
646 repo.setparents(p1.node(), p2.node())
646 repo.setparents(p1.node(), p2.node())
647
647
648 if opts.get('exact') or opts.get('import_branch'):
648 if opts.get('exact') or opts.get('import_branch'):
649 repo.dirstate.setbranch(branch or 'default')
649 repo.dirstate.setbranch(branch or 'default')
650
650
651 partial = opts.get('partial', False)
651 partial = opts.get('partial', False)
652 files = set()
652 files = set()
653 try:
653 try:
654 patch.patch(ui, repo, tmpname, strip=strip, files=files,
654 patch.patch(ui, repo, tmpname, strip=strip, files=files,
655 eolmode=None, similarity=sim / 100.0)
655 eolmode=None, similarity=sim / 100.0)
656 except patch.PatchError, e:
656 except patch.PatchError, e:
657 if not partial:
657 if not partial:
658 raise util.Abort(str(e))
658 raise util.Abort(str(e))
659 if partial:
659 if partial:
660 rejects = True
660 rejects = True
661
661
662 files = list(files)
662 files = list(files)
663 if opts.get('no_commit'):
663 if opts.get('no_commit'):
664 if message:
664 if message:
665 msgs.append(message)
665 msgs.append(message)
666 else:
666 else:
667 if opts.get('exact') or p2:
667 if opts.get('exact') or p2:
668 # If you got here, you either use --force and know what
668 # If you got here, you either use --force and know what
669 # you are doing or used --exact or a merge patch while
669 # you are doing or used --exact or a merge patch while
670 # being updated to its first parent.
670 # being updated to its first parent.
671 m = None
671 m = None
672 else:
672 else:
673 m = scmutil.matchfiles(repo, files or [])
673 m = scmutil.matchfiles(repo, files or [])
674 n = repo.commit(message, opts.get('user') or user,
674 n = repo.commit(message, opts.get('user') or user,
675 opts.get('date') or date, match=m,
675 opts.get('date') or date, match=m,
676 editor=editor, force=partial)
676 editor=editor, force=partial)
677 else:
677 else:
678 if opts.get('exact') or opts.get('import_branch'):
678 if opts.get('exact') or opts.get('import_branch'):
679 branch = branch or 'default'
679 branch = branch or 'default'
680 else:
680 else:
681 branch = p1.branch()
681 branch = p1.branch()
682 store = patch.filestore()
682 store = patch.filestore()
683 try:
683 try:
684 files = set()
684 files = set()
685 try:
685 try:
686 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
686 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
687 files, eolmode=None)
687 files, eolmode=None)
688 except patch.PatchError, e:
688 except patch.PatchError, e:
689 raise util.Abort(str(e))
689 raise util.Abort(str(e))
690 editor = getcommiteditor(editform='import.bypass')
690 editor = getcommiteditor(editform='import.bypass')
691 memctx = context.makememctx(repo, (p1.node(), p2.node()),
691 memctx = context.makememctx(repo, (p1.node(), p2.node()),
692 message,
692 message,
693 opts.get('user') or user,
693 opts.get('user') or user,
694 opts.get('date') or date,
694 opts.get('date') or date,
695 branch, files, store,
695 branch, files, store,
696 editor=editor)
696 editor=editor)
697 n = memctx.commit()
697 n = memctx.commit()
698 finally:
698 finally:
699 store.close()
699 store.close()
700 if opts.get('exact') and hex(n) != nodeid:
700 if opts.get('exact') and hex(n) != nodeid:
701 raise util.Abort(_('patch is damaged or loses information'))
701 raise util.Abort(_('patch is damaged or loses information'))
702 if n:
702 if n:
703 # i18n: refers to a short changeset id
703 # i18n: refers to a short changeset id
704 msg = _('created %s') % short(n)
704 msg = _('created %s') % short(n)
705 return (msg, n, rejects)
705 return (msg, n, rejects)
706 finally:
706 finally:
707 os.unlink(tmpname)
707 os.unlink(tmpname)
708
708
709 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
709 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
710 opts=None):
710 opts=None):
711 '''export changesets as hg patches.'''
711 '''export changesets as hg patches.'''
712
712
713 total = len(revs)
713 total = len(revs)
714 revwidth = max([len(str(rev)) for rev in revs])
714 revwidth = max([len(str(rev)) for rev in revs])
715 filemode = {}
715 filemode = {}
716
716
717 def single(rev, seqno, fp):
717 def single(rev, seqno, fp):
718 ctx = repo[rev]
718 ctx = repo[rev]
719 node = ctx.node()
719 node = ctx.node()
720 parents = [p.node() for p in ctx.parents() if p]
720 parents = [p.node() for p in ctx.parents() if p]
721 branch = ctx.branch()
721 branch = ctx.branch()
722 if switch_parent:
722 if switch_parent:
723 parents.reverse()
723 parents.reverse()
724 prev = (parents and parents[0]) or nullid
724 prev = (parents and parents[0]) or nullid
725
725
726 shouldclose = False
726 shouldclose = False
727 if not fp and len(template) > 0:
727 if not fp and len(template) > 0:
728 desc_lines = ctx.description().rstrip().split('\n')
728 desc_lines = ctx.description().rstrip().split('\n')
729 desc = desc_lines[0] #Commit always has a first line.
729 desc = desc_lines[0] #Commit always has a first line.
730 fp = makefileobj(repo, template, node, desc=desc, total=total,
730 fp = makefileobj(repo, template, node, desc=desc, total=total,
731 seqno=seqno, revwidth=revwidth, mode='wb',
731 seqno=seqno, revwidth=revwidth, mode='wb',
732 modemap=filemode)
732 modemap=filemode)
733 if fp != template:
733 if fp != template:
734 shouldclose = True
734 shouldclose = True
735 if fp and fp != sys.stdout and util.safehasattr(fp, 'name'):
735 if fp and fp != sys.stdout and util.safehasattr(fp, 'name'):
736 repo.ui.note("%s\n" % fp.name)
736 repo.ui.note("%s\n" % fp.name)
737
737
738 if not fp:
738 if not fp:
739 write = repo.ui.write
739 write = repo.ui.write
740 else:
740 else:
741 def write(s, **kw):
741 def write(s, **kw):
742 fp.write(s)
742 fp.write(s)
743
743
744
744
745 write("# HG changeset patch\n")
745 write("# HG changeset patch\n")
746 write("# User %s\n" % ctx.user())
746 write("# User %s\n" % ctx.user())
747 write("# Date %d %d\n" % ctx.date())
747 write("# Date %d %d\n" % ctx.date())
748 write("# %s\n" % util.datestr(ctx.date()))
748 write("# %s\n" % util.datestr(ctx.date()))
749 if branch and branch != 'default':
749 if branch and branch != 'default':
750 write("# Branch %s\n" % branch)
750 write("# Branch %s\n" % branch)
751 write("# Node ID %s\n" % hex(node))
751 write("# Node ID %s\n" % hex(node))
752 write("# Parent %s\n" % hex(prev))
752 write("# Parent %s\n" % hex(prev))
753 if len(parents) > 1:
753 if len(parents) > 1:
754 write("# Parent %s\n" % hex(parents[1]))
754 write("# Parent %s\n" % hex(parents[1]))
755 write(ctx.description().rstrip())
755 write(ctx.description().rstrip())
756 write("\n\n")
756 write("\n\n")
757
757
758 for chunk, label in patch.diffui(repo, prev, node, opts=opts):
758 for chunk, label in patch.diffui(repo, prev, node, opts=opts):
759 write(chunk, label=label)
759 write(chunk, label=label)
760
760
761 if shouldclose:
761 if shouldclose:
762 fp.close()
762 fp.close()
763
763
764 for seqno, rev in enumerate(revs):
764 for seqno, rev in enumerate(revs):
765 single(rev, seqno + 1, fp)
765 single(rev, seqno + 1, fp)
766
766
767 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
767 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
768 changes=None, stat=False, fp=None, prefix='',
768 changes=None, stat=False, fp=None, prefix='',
769 listsubrepos=False):
769 listsubrepos=False):
770 '''show diff or diffstat.'''
770 '''show diff or diffstat.'''
771 if fp is None:
771 if fp is None:
772 write = ui.write
772 write = ui.write
773 else:
773 else:
774 def write(s, **kw):
774 def write(s, **kw):
775 fp.write(s)
775 fp.write(s)
776
776
777 if stat:
777 if stat:
778 diffopts = diffopts.copy(context=0)
778 diffopts = diffopts.copy(context=0)
779 width = 80
779 width = 80
780 if not ui.plain():
780 if not ui.plain():
781 width = ui.termwidth()
781 width = ui.termwidth()
782 chunks = patch.diff(repo, node1, node2, match, changes, diffopts,
782 chunks = patch.diff(repo, node1, node2, match, changes, diffopts,
783 prefix=prefix)
783 prefix=prefix)
784 for chunk, label in patch.diffstatui(util.iterlines(chunks),
784 for chunk, label in patch.diffstatui(util.iterlines(chunks),
785 width=width,
785 width=width,
786 git=diffopts.git):
786 git=diffopts.git):
787 write(chunk, label=label)
787 write(chunk, label=label)
788 else:
788 else:
789 for chunk, label in patch.diffui(repo, node1, node2, match,
789 for chunk, label in patch.diffui(repo, node1, node2, match,
790 changes, diffopts, prefix=prefix):
790 changes, diffopts, prefix=prefix):
791 write(chunk, label=label)
791 write(chunk, label=label)
792
792
793 if listsubrepos:
793 if listsubrepos:
794 ctx1 = repo[node1]
794 ctx1 = repo[node1]
795 ctx2 = repo[node2]
795 ctx2 = repo[node2]
796 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
796 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
797 tempnode2 = node2
797 tempnode2 = node2
798 try:
798 try:
799 if node2 is not None:
799 if node2 is not None:
800 tempnode2 = ctx2.substate[subpath][1]
800 tempnode2 = ctx2.substate[subpath][1]
801 except KeyError:
801 except KeyError:
802 # A subrepo that existed in node1 was deleted between node1 and
802 # A subrepo that existed in node1 was deleted between node1 and
803 # node2 (inclusive). Thus, ctx2's substate won't contain that
803 # node2 (inclusive). Thus, ctx2's substate won't contain that
804 # subpath. The best we can do is to ignore it.
804 # subpath. The best we can do is to ignore it.
805 tempnode2 = None
805 tempnode2 = None
806 submatch = matchmod.narrowmatcher(subpath, match)
806 submatch = matchmod.narrowmatcher(subpath, match)
807 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
807 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
808 stat=stat, fp=fp, prefix=prefix)
808 stat=stat, fp=fp, prefix=prefix)
809
809
810 class changeset_printer(object):
810 class changeset_printer(object):
811 '''show changeset information when templating not requested.'''
811 '''show changeset information when templating not requested.'''
812
812
813 def __init__(self, ui, repo, patch, diffopts, buffered):
813 def __init__(self, ui, repo, patch, diffopts, buffered):
814 self.ui = ui
814 self.ui = ui
815 self.repo = repo
815 self.repo = repo
816 self.buffered = buffered
816 self.buffered = buffered
817 self.patch = patch
817 self.patch = patch
818 self.diffopts = diffopts
818 self.diffopts = diffopts
819 self.header = {}
819 self.header = {}
820 self.hunk = {}
820 self.hunk = {}
821 self.lastheader = None
821 self.lastheader = None
822 self.footer = None
822 self.footer = None
823
823
824 def flush(self, rev):
824 def flush(self, rev):
825 if rev in self.header:
825 if rev in self.header:
826 h = self.header[rev]
826 h = self.header[rev]
827 if h != self.lastheader:
827 if h != self.lastheader:
828 self.lastheader = h
828 self.lastheader = h
829 self.ui.write(h)
829 self.ui.write(h)
830 del self.header[rev]
830 del self.header[rev]
831 if rev in self.hunk:
831 if rev in self.hunk:
832 self.ui.write(self.hunk[rev])
832 self.ui.write(self.hunk[rev])
833 del self.hunk[rev]
833 del self.hunk[rev]
834 return 1
834 return 1
835 return 0
835 return 0
836
836
837 def close(self):
837 def close(self):
838 if self.footer:
838 if self.footer:
839 self.ui.write(self.footer)
839 self.ui.write(self.footer)
840
840
841 def show(self, ctx, copies=None, matchfn=None, **props):
841 def show(self, ctx, copies=None, matchfn=None, **props):
842 if self.buffered:
842 if self.buffered:
843 self.ui.pushbuffer()
843 self.ui.pushbuffer()
844 self._show(ctx, copies, matchfn, props)
844 self._show(ctx, copies, matchfn, props)
845 self.hunk[ctx.rev()] = self.ui.popbuffer(labeled=True)
845 self.hunk[ctx.rev()] = self.ui.popbuffer(labeled=True)
846 else:
846 else:
847 self._show(ctx, copies, matchfn, props)
847 self._show(ctx, copies, matchfn, props)
848
848
849 def _show(self, ctx, copies, matchfn, props):
849 def _show(self, ctx, copies, matchfn, props):
850 '''show a single changeset or file revision'''
850 '''show a single changeset or file revision'''
851 changenode = ctx.node()
851 changenode = ctx.node()
852 rev = ctx.rev()
852 rev = ctx.rev()
853
853
854 if self.ui.quiet:
854 if self.ui.quiet:
855 self.ui.write("%d:%s\n" % (rev, short(changenode)),
855 self.ui.write("%d:%s\n" % (rev, short(changenode)),
856 label='log.node')
856 label='log.node')
857 return
857 return
858
858
859 log = self.repo.changelog
859 log = self.repo.changelog
860 date = util.datestr(ctx.date())
860 date = util.datestr(ctx.date())
861
861
862 hexfunc = self.ui.debugflag and hex or short
862 hexfunc = self.ui.debugflag and hex or short
863
863
864 parents = [(p, hexfunc(log.node(p)))
864 parents = [(p, hexfunc(log.node(p)))
865 for p in self._meaningful_parentrevs(log, rev)]
865 for p in self._meaningful_parentrevs(log, rev)]
866
866
867 # i18n: column positioning for "hg log"
867 # i18n: column positioning for "hg log"
868 self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)),
868 self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)),
869 label='log.changeset changeset.%s' % ctx.phasestr())
869 label='log.changeset changeset.%s' % ctx.phasestr())
870
870
871 branch = ctx.branch()
871 branch = ctx.branch()
872 # don't show the default branch name
872 # don't show the default branch name
873 if branch != 'default':
873 if branch != 'default':
874 # i18n: column positioning for "hg log"
874 # i18n: column positioning for "hg log"
875 self.ui.write(_("branch: %s\n") % branch,
875 self.ui.write(_("branch: %s\n") % branch,
876 label='log.branch')
876 label='log.branch')
877 for bookmark in self.repo.nodebookmarks(changenode):
877 for bookmark in self.repo.nodebookmarks(changenode):
878 # i18n: column positioning for "hg log"
878 # i18n: column positioning for "hg log"
879 self.ui.write(_("bookmark: %s\n") % bookmark,
879 self.ui.write(_("bookmark: %s\n") % bookmark,
880 label='log.bookmark')
880 label='log.bookmark')
881 for tag in self.repo.nodetags(changenode):
881 for tag in self.repo.nodetags(changenode):
882 # i18n: column positioning for "hg log"
882 # i18n: column positioning for "hg log"
883 self.ui.write(_("tag: %s\n") % tag,
883 self.ui.write(_("tag: %s\n") % tag,
884 label='log.tag')
884 label='log.tag')
885 if self.ui.debugflag and ctx.phase():
885 if self.ui.debugflag and ctx.phase():
886 # i18n: column positioning for "hg log"
886 # i18n: column positioning for "hg log"
887 self.ui.write(_("phase: %s\n") % _(ctx.phasestr()),
887 self.ui.write(_("phase: %s\n") % _(ctx.phasestr()),
888 label='log.phase')
888 label='log.phase')
889 for parent in parents:
889 for parent in parents:
890 # i18n: column positioning for "hg log"
890 # i18n: column positioning for "hg log"
891 self.ui.write(_("parent: %d:%s\n") % parent,
891 self.ui.write(_("parent: %d:%s\n") % parent,
892 label='log.parent changeset.%s' % ctx.phasestr())
892 label='log.parent changeset.%s' % ctx.phasestr())
893
893
894 if self.ui.debugflag:
894 if self.ui.debugflag:
895 mnode = ctx.manifestnode()
895 mnode = ctx.manifestnode()
896 # i18n: column positioning for "hg log"
896 # i18n: column positioning for "hg log"
897 self.ui.write(_("manifest: %d:%s\n") %
897 self.ui.write(_("manifest: %d:%s\n") %
898 (self.repo.manifest.rev(mnode), hex(mnode)),
898 (self.repo.manifest.rev(mnode), hex(mnode)),
899 label='ui.debug log.manifest')
899 label='ui.debug log.manifest')
900 # i18n: column positioning for "hg log"
900 # i18n: column positioning for "hg log"
901 self.ui.write(_("user: %s\n") % ctx.user(),
901 self.ui.write(_("user: %s\n") % ctx.user(),
902 label='log.user')
902 label='log.user')
903 # i18n: column positioning for "hg log"
903 # i18n: column positioning for "hg log"
904 self.ui.write(_("date: %s\n") % date,
904 self.ui.write(_("date: %s\n") % date,
905 label='log.date')
905 label='log.date')
906
906
907 if self.ui.debugflag:
907 if self.ui.debugflag:
908 files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
908 files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
909 for key, value in zip([# i18n: column positioning for "hg log"
909 for key, value in zip([# i18n: column positioning for "hg log"
910 _("files:"),
910 _("files:"),
911 # i18n: column positioning for "hg log"
911 # i18n: column positioning for "hg log"
912 _("files+:"),
912 _("files+:"),
913 # i18n: column positioning for "hg log"
913 # i18n: column positioning for "hg log"
914 _("files-:")], files):
914 _("files-:")], files):
915 if value:
915 if value:
916 self.ui.write("%-12s %s\n" % (key, " ".join(value)),
916 self.ui.write("%-12s %s\n" % (key, " ".join(value)),
917 label='ui.debug log.files')
917 label='ui.debug log.files')
918 elif ctx.files() and self.ui.verbose:
918 elif ctx.files() and self.ui.verbose:
919 # i18n: column positioning for "hg log"
919 # i18n: column positioning for "hg log"
920 self.ui.write(_("files: %s\n") % " ".join(ctx.files()),
920 self.ui.write(_("files: %s\n") % " ".join(ctx.files()),
921 label='ui.note log.files')
921 label='ui.note log.files')
922 if copies and self.ui.verbose:
922 if copies and self.ui.verbose:
923 copies = ['%s (%s)' % c for c in copies]
923 copies = ['%s (%s)' % c for c in copies]
924 # i18n: column positioning for "hg log"
924 # i18n: column positioning for "hg log"
925 self.ui.write(_("copies: %s\n") % ' '.join(copies),
925 self.ui.write(_("copies: %s\n") % ' '.join(copies),
926 label='ui.note log.copies')
926 label='ui.note log.copies')
927
927
928 extra = ctx.extra()
928 extra = ctx.extra()
929 if extra and self.ui.debugflag:
929 if extra and self.ui.debugflag:
930 for key, value in sorted(extra.items()):
930 for key, value in sorted(extra.items()):
931 # i18n: column positioning for "hg log"
931 # i18n: column positioning for "hg log"
932 self.ui.write(_("extra: %s=%s\n")
932 self.ui.write(_("extra: %s=%s\n")
933 % (key, value.encode('string_escape')),
933 % (key, value.encode('string_escape')),
934 label='ui.debug log.extra')
934 label='ui.debug log.extra')
935
935
936 description = ctx.description().strip()
936 description = ctx.description().strip()
937 if description:
937 if description:
938 if self.ui.verbose:
938 if self.ui.verbose:
939 self.ui.write(_("description:\n"),
939 self.ui.write(_("description:\n"),
940 label='ui.note log.description')
940 label='ui.note log.description')
941 self.ui.write(description,
941 self.ui.write(description,
942 label='ui.note log.description')
942 label='ui.note log.description')
943 self.ui.write("\n\n")
943 self.ui.write("\n\n")
944 else:
944 else:
945 # i18n: column positioning for "hg log"
945 # i18n: column positioning for "hg log"
946 self.ui.write(_("summary: %s\n") %
946 self.ui.write(_("summary: %s\n") %
947 description.splitlines()[0],
947 description.splitlines()[0],
948 label='log.summary')
948 label='log.summary')
949 self.ui.write("\n")
949 self.ui.write("\n")
950
950
951 self.showpatch(changenode, matchfn)
951 self.showpatch(changenode, matchfn)
952
952
953 def showpatch(self, node, matchfn):
953 def showpatch(self, node, matchfn):
954 if not matchfn:
954 if not matchfn:
955 matchfn = self.patch
955 matchfn = self.patch
956 if matchfn:
956 if matchfn:
957 stat = self.diffopts.get('stat')
957 stat = self.diffopts.get('stat')
958 diff = self.diffopts.get('patch')
958 diff = self.diffopts.get('patch')
959 diffopts = patch.diffopts(self.ui, self.diffopts)
959 diffopts = patch.diffopts(self.ui, self.diffopts)
960 prev = self.repo.changelog.parents(node)[0]
960 prev = self.repo.changelog.parents(node)[0]
961 if stat:
961 if stat:
962 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
962 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
963 match=matchfn, stat=True)
963 match=matchfn, stat=True)
964 if diff:
964 if diff:
965 if stat:
965 if stat:
966 self.ui.write("\n")
966 self.ui.write("\n")
967 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
967 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
968 match=matchfn, stat=False)
968 match=matchfn, stat=False)
969 self.ui.write("\n")
969 self.ui.write("\n")
970
970
971 def _meaningful_parentrevs(self, log, rev):
971 def _meaningful_parentrevs(self, log, rev):
972 """Return list of meaningful (or all if debug) parentrevs for rev.
972 """Return list of meaningful (or all if debug) parentrevs for rev.
973
973
974 For merges (two non-nullrev revisions) both parents are meaningful.
974 For merges (two non-nullrev revisions) both parents are meaningful.
975 Otherwise the first parent revision is considered meaningful if it
975 Otherwise the first parent revision is considered meaningful if it
976 is not the preceding revision.
976 is not the preceding revision.
977 """
977 """
978 parents = log.parentrevs(rev)
978 parents = log.parentrevs(rev)
979 if not self.ui.debugflag and parents[1] == nullrev:
979 if not self.ui.debugflag and parents[1] == nullrev:
980 if parents[0] >= rev - 1:
980 if parents[0] >= rev - 1:
981 parents = []
981 parents = []
982 else:
982 else:
983 parents = [parents[0]]
983 parents = [parents[0]]
984 return parents
984 return parents
985
985
986
986
987 class changeset_templater(changeset_printer):
987 class changeset_templater(changeset_printer):
988 '''format changeset information.'''
988 '''format changeset information.'''
989
989
990 def __init__(self, ui, repo, patch, diffopts, tmpl, mapfile, buffered):
990 def __init__(self, ui, repo, patch, diffopts, tmpl, mapfile, buffered):
991 changeset_printer.__init__(self, ui, repo, patch, diffopts, buffered)
991 changeset_printer.__init__(self, ui, repo, patch, diffopts, buffered)
992 formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
992 formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
993 defaulttempl = {
993 defaulttempl = {
994 'parent': '{rev}:{node|formatnode} ',
994 'parent': '{rev}:{node|formatnode} ',
995 'manifest': '{rev}:{node|formatnode}',
995 'manifest': '{rev}:{node|formatnode}',
996 'file_copy': '{name} ({source})',
996 'file_copy': '{name} ({source})',
997 'extra': '{key}={value|stringescape}'
997 'extra': '{key}={value|stringescape}'
998 }
998 }
999 # filecopy is preserved for compatibility reasons
999 # filecopy is preserved for compatibility reasons
1000 defaulttempl['filecopy'] = defaulttempl['file_copy']
1000 defaulttempl['filecopy'] = defaulttempl['file_copy']
1001 self.t = templater.templater(mapfile, {'formatnode': formatnode},
1001 self.t = templater.templater(mapfile, {'formatnode': formatnode},
1002 cache=defaulttempl)
1002 cache=defaulttempl)
1003 if tmpl:
1003 if tmpl:
1004 self.t.cache['changeset'] = tmpl
1004 self.t.cache['changeset'] = tmpl
1005
1005
1006 self.cache = {}
1006 self.cache = {}
1007
1007
1008 def _meaningful_parentrevs(self, ctx):
1008 def _meaningful_parentrevs(self, ctx):
1009 """Return list of meaningful (or all if debug) parentrevs for rev.
1009 """Return list of meaningful (or all if debug) parentrevs for rev.
1010 """
1010 """
1011 parents = ctx.parents()
1011 parents = ctx.parents()
1012 if len(parents) > 1:
1012 if len(parents) > 1:
1013 return parents
1013 return parents
1014 if self.ui.debugflag:
1014 if self.ui.debugflag:
1015 return [parents[0], self.repo['null']]
1015 return [parents[0], self.repo['null']]
1016 if parents[0].rev() >= ctx.rev() - 1:
1016 if parents[0].rev() >= ctx.rev() - 1:
1017 return []
1017 return []
1018 return parents
1018 return parents
1019
1019
1020 def _show(self, ctx, copies, matchfn, props):
1020 def _show(self, ctx, copies, matchfn, props):
1021 '''show a single changeset or file revision'''
1021 '''show a single changeset or file revision'''
1022
1022
1023 showlist = templatekw.showlist
1023 showlist = templatekw.showlist
1024
1024
1025 # showparents() behaviour depends on ui trace level which
1025 # showparents() behaviour depends on ui trace level which
1026 # causes unexpected behaviours at templating level and makes
1026 # causes unexpected behaviours at templating level and makes
1027 # it harder to extract it in a standalone function. Its
1027 # it harder to extract it in a standalone function. Its
1028 # behaviour cannot be changed so leave it here for now.
1028 # behaviour cannot be changed so leave it here for now.
1029 def showparents(**args):
1029 def showparents(**args):
1030 ctx = args['ctx']
1030 ctx = args['ctx']
1031 parents = [[('rev', p.rev()), ('node', p.hex())]
1031 parents = [[('rev', p.rev()), ('node', p.hex())]
1032 for p in self._meaningful_parentrevs(ctx)]
1032 for p in self._meaningful_parentrevs(ctx)]
1033 return showlist('parent', parents, **args)
1033 return showlist('parent', parents, **args)
1034
1034
1035 props = props.copy()
1035 props = props.copy()
1036 props.update(templatekw.keywords)
1036 props.update(templatekw.keywords)
1037 props['parents'] = showparents
1037 props['parents'] = showparents
1038 props['templ'] = self.t
1038 props['templ'] = self.t
1039 props['ctx'] = ctx
1039 props['ctx'] = ctx
1040 props['repo'] = self.repo
1040 props['repo'] = self.repo
1041 props['revcache'] = {'copies': copies}
1041 props['revcache'] = {'copies': copies}
1042 props['cache'] = self.cache
1042 props['cache'] = self.cache
1043
1043
1044 # find correct templates for current mode
1044 # find correct templates for current mode
1045
1045
1046 tmplmodes = [
1046 tmplmodes = [
1047 (True, None),
1047 (True, None),
1048 (self.ui.verbose, 'verbose'),
1048 (self.ui.verbose, 'verbose'),
1049 (self.ui.quiet, 'quiet'),
1049 (self.ui.quiet, 'quiet'),
1050 (self.ui.debugflag, 'debug'),
1050 (self.ui.debugflag, 'debug'),
1051 ]
1051 ]
1052
1052
1053 types = {'header': '', 'footer':'', 'changeset': 'changeset'}
1053 types = {'header': '', 'footer':'', 'changeset': 'changeset'}
1054 for mode, postfix in tmplmodes:
1054 for mode, postfix in tmplmodes:
1055 for type in types:
1055 for type in types:
1056 cur = postfix and ('%s_%s' % (type, postfix)) or type
1056 cur = postfix and ('%s_%s' % (type, postfix)) or type
1057 if mode and cur in self.t:
1057 if mode and cur in self.t:
1058 types[type] = cur
1058 types[type] = cur
1059
1059
1060 try:
1060 try:
1061
1061
1062 # write header
1062 # write header
1063 if types['header']:
1063 if types['header']:
1064 h = templater.stringify(self.t(types['header'], **props))
1064 h = templater.stringify(self.t(types['header'], **props))
1065 if self.buffered:
1065 if self.buffered:
1066 self.header[ctx.rev()] = h
1066 self.header[ctx.rev()] = h
1067 else:
1067 else:
1068 if self.lastheader != h:
1068 if self.lastheader != h:
1069 self.lastheader = h
1069 self.lastheader = h
1070 self.ui.write(h)
1070 self.ui.write(h)
1071
1071
1072 # write changeset metadata, then patch if requested
1072 # write changeset metadata, then patch if requested
1073 key = types['changeset']
1073 key = types['changeset']
1074 self.ui.write(templater.stringify(self.t(key, **props)))
1074 self.ui.write(templater.stringify(self.t(key, **props)))
1075 self.showpatch(ctx.node(), matchfn)
1075 self.showpatch(ctx.node(), matchfn)
1076
1076
1077 if types['footer']:
1077 if types['footer']:
1078 if not self.footer:
1078 if not self.footer:
1079 self.footer = templater.stringify(self.t(types['footer'],
1079 self.footer = templater.stringify(self.t(types['footer'],
1080 **props))
1080 **props))
1081
1081
1082 except KeyError, inst:
1082 except KeyError, inst:
1083 msg = _("%s: no key named '%s'")
1083 msg = _("%s: no key named '%s'")
1084 raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
1084 raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
1085 except SyntaxError, inst:
1085 except SyntaxError, inst:
1086 raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
1086 raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
1087
1087
1088 def gettemplate(ui, tmpl, style):
1088 def gettemplate(ui, tmpl, style):
1089 """
1089 """
1090 Find the template matching the given template spec or style.
1090 Find the template matching the given template spec or style.
1091 """
1091 """
1092
1092
1093 # ui settings
1093 # ui settings
1094 if not tmpl and not style:
1094 if not tmpl and not style:
1095 tmpl = ui.config('ui', 'logtemplate')
1095 tmpl = ui.config('ui', 'logtemplate')
1096 if tmpl:
1096 if tmpl:
1097 try:
1097 try:
1098 tmpl = templater.parsestring(tmpl)
1098 tmpl = templater.parsestring(tmpl)
1099 except SyntaxError:
1099 except SyntaxError:
1100 tmpl = templater.parsestring(tmpl, quoted=False)
1100 tmpl = templater.parsestring(tmpl, quoted=False)
1101 return tmpl, None
1101 return tmpl, None
1102 else:
1102 else:
1103 style = util.expandpath(ui.config('ui', 'style', ''))
1103 style = util.expandpath(ui.config('ui', 'style', ''))
1104
1104
1105 if style:
1105 if style:
1106 mapfile = style
1106 mapfile = style
1107 if not os.path.split(mapfile)[0]:
1107 if not os.path.split(mapfile)[0]:
1108 mapname = (templater.templatepath('map-cmdline.' + mapfile)
1108 mapname = (templater.templatepath('map-cmdline.' + mapfile)
1109 or templater.templatepath(mapfile))
1109 or templater.templatepath(mapfile))
1110 if mapname:
1110 if mapname:
1111 mapfile = mapname
1111 mapfile = mapname
1112 return None, mapfile
1112 return None, mapfile
1113
1113
1114 if not tmpl:
1114 if not tmpl:
1115 return None, None
1115 return None, None
1116
1116
1117 # looks like a literal template?
1117 # looks like a literal template?
1118 if '{' in tmpl:
1118 if '{' in tmpl:
1119 return tmpl, None
1119 return tmpl, None
1120
1120
1121 # perhaps a stock style?
1121 # perhaps a stock style?
1122 if not os.path.split(tmpl)[0]:
1122 if not os.path.split(tmpl)[0]:
1123 mapname = (templater.templatepath('map-cmdline.' + tmpl)
1123 mapname = (templater.templatepath('map-cmdline.' + tmpl)
1124 or templater.templatepath(tmpl))
1124 or templater.templatepath(tmpl))
1125 if mapname and os.path.isfile(mapname):
1125 if mapname and os.path.isfile(mapname):
1126 return None, mapname
1126 return None, mapname
1127
1127
1128 # perhaps it's a reference to [templates]
1128 # perhaps it's a reference to [templates]
1129 t = ui.config('templates', tmpl)
1129 t = ui.config('templates', tmpl)
1130 if t:
1130 if t:
1131 try:
1131 try:
1132 tmpl = templater.parsestring(t)
1132 tmpl = templater.parsestring(t)
1133 except SyntaxError:
1133 except SyntaxError:
1134 tmpl = templater.parsestring(t, quoted=False)
1134 tmpl = templater.parsestring(t, quoted=False)
1135 return tmpl, None
1135 return tmpl, None
1136
1136
1137 if tmpl == 'list':
1137 if tmpl == 'list':
1138 ui.write(_("available styles: %s\n") % templater.stylelist())
1138 ui.write(_("available styles: %s\n") % templater.stylelist())
1139 raise util.Abort(_("specify a template"))
1139 raise util.Abort(_("specify a template"))
1140
1140
1141 # perhaps it's a path to a map or a template
1141 # perhaps it's a path to a map or a template
1142 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
1142 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
1143 # is it a mapfile for a style?
1143 # is it a mapfile for a style?
1144 if os.path.basename(tmpl).startswith("map-"):
1144 if os.path.basename(tmpl).startswith("map-"):
1145 return None, os.path.realpath(tmpl)
1145 return None, os.path.realpath(tmpl)
1146 tmpl = open(tmpl).read()
1146 tmpl = open(tmpl).read()
1147 return tmpl, None
1147 return tmpl, None
1148
1148
1149 # constant string?
1149 # constant string?
1150 return tmpl, None
1150 return tmpl, None
1151
1151
1152 def show_changeset(ui, repo, opts, buffered=False):
1152 def show_changeset(ui, repo, opts, buffered=False):
1153 """show one changeset using template or regular display.
1153 """show one changeset using template or regular display.
1154
1154
1155 Display format will be the first non-empty hit of:
1155 Display format will be the first non-empty hit of:
1156 1. option 'template'
1156 1. option 'template'
1157 2. option 'style'
1157 2. option 'style'
1158 3. [ui] setting 'logtemplate'
1158 3. [ui] setting 'logtemplate'
1159 4. [ui] setting 'style'
1159 4. [ui] setting 'style'
1160 If all of these values are either the unset or the empty string,
1160 If all of these values are either the unset or the empty string,
1161 regular display via changeset_printer() is done.
1161 regular display via changeset_printer() is done.
1162 """
1162 """
1163 # options
1163 # options
1164 patch = None
1164 patch = None
1165 if opts.get('patch') or opts.get('stat'):
1165 if opts.get('patch') or opts.get('stat'):
1166 patch = scmutil.matchall(repo)
1166 patch = scmutil.matchall(repo)
1167
1167
1168 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1168 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1169
1169
1170 if not tmpl and not mapfile:
1170 if not tmpl and not mapfile:
1171 return changeset_printer(ui, repo, patch, opts, buffered)
1171 return changeset_printer(ui, repo, patch, opts, buffered)
1172
1172
1173 try:
1173 try:
1174 t = changeset_templater(ui, repo, patch, opts, tmpl, mapfile, buffered)
1174 t = changeset_templater(ui, repo, patch, opts, tmpl, mapfile, buffered)
1175 except SyntaxError, inst:
1175 except SyntaxError, inst:
1176 raise util.Abort(inst.args[0])
1176 raise util.Abort(inst.args[0])
1177 return t
1177 return t
1178
1178
1179 def showmarker(ui, marker):
1179 def showmarker(ui, marker):
1180 """utility function to display obsolescence marker in a readable way
1180 """utility function to display obsolescence marker in a readable way
1181
1181
1182 To be used by debug function."""
1182 To be used by debug function."""
1183 ui.write(hex(marker.precnode()))
1183 ui.write(hex(marker.precnode()))
1184 for repl in marker.succnodes():
1184 for repl in marker.succnodes():
1185 ui.write(' ')
1185 ui.write(' ')
1186 ui.write(hex(repl))
1186 ui.write(hex(repl))
1187 ui.write(' %X ' % marker._data[2])
1187 ui.write(' %X ' % marker._data[2])
1188 ui.write('{%s}' % (', '.join('%r: %r' % t for t in
1188 ui.write('{%s}' % (', '.join('%r: %r' % t for t in
1189 sorted(marker.metadata().items()))))
1189 sorted(marker.metadata().items()))))
1190 ui.write('\n')
1190 ui.write('\n')
1191
1191
1192 def finddate(ui, repo, date):
1192 def finddate(ui, repo, date):
1193 """Find the tipmost changeset that matches the given date spec"""
1193 """Find the tipmost changeset that matches the given date spec"""
1194
1194
1195 df = util.matchdate(date)
1195 df = util.matchdate(date)
1196 m = scmutil.matchall(repo)
1196 m = scmutil.matchall(repo)
1197 results = {}
1197 results = {}
1198
1198
1199 def prep(ctx, fns):
1199 def prep(ctx, fns):
1200 d = ctx.date()
1200 d = ctx.date()
1201 if df(d[0]):
1201 if df(d[0]):
1202 results[ctx.rev()] = d
1202 results[ctx.rev()] = d
1203
1203
1204 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1204 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1205 rev = ctx.rev()
1205 rev = ctx.rev()
1206 if rev in results:
1206 if rev in results:
1207 ui.status(_("found revision %s from %s\n") %
1207 ui.status(_("found revision %s from %s\n") %
1208 (rev, util.datestr(results[rev])))
1208 (rev, util.datestr(results[rev])))
1209 return str(rev)
1209 return str(rev)
1210
1210
1211 raise util.Abort(_("revision matching date not found"))
1211 raise util.Abort(_("revision matching date not found"))
1212
1212
1213 def increasingwindows(windowsize=8, sizelimit=512):
1213 def increasingwindows(windowsize=8, sizelimit=512):
1214 while True:
1214 while True:
1215 yield windowsize
1215 yield windowsize
1216 if windowsize < sizelimit:
1216 if windowsize < sizelimit:
1217 windowsize *= 2
1217 windowsize *= 2
1218
1218
1219 class FileWalkError(Exception):
1219 class FileWalkError(Exception):
1220 pass
1220 pass
1221
1221
1222 def walkfilerevs(repo, match, follow, revs, fncache):
1222 def walkfilerevs(repo, match, follow, revs, fncache):
1223 '''Walks the file history for the matched files.
1223 '''Walks the file history for the matched files.
1224
1224
1225 Returns the changeset revs that are involved in the file history.
1225 Returns the changeset revs that are involved in the file history.
1226
1226
1227 Throws FileWalkError if the file history can't be walked using
1227 Throws FileWalkError if the file history can't be walked using
1228 filelogs alone.
1228 filelogs alone.
1229 '''
1229 '''
1230 wanted = set()
1230 wanted = set()
1231 copies = []
1231 copies = []
1232 minrev, maxrev = min(revs), max(revs)
1232 minrev, maxrev = min(revs), max(revs)
1233 def filerevgen(filelog, last):
1233 def filerevgen(filelog, last):
1234 """
1234 """
1235 Only files, no patterns. Check the history of each file.
1235 Only files, no patterns. Check the history of each file.
1236
1236
1237 Examines filelog entries within minrev, maxrev linkrev range
1237 Examines filelog entries within minrev, maxrev linkrev range
1238 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1238 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1239 tuples in backwards order
1239 tuples in backwards order
1240 """
1240 """
1241 cl_count = len(repo)
1241 cl_count = len(repo)
1242 revs = []
1242 revs = []
1243 for j in xrange(0, last + 1):
1243 for j in xrange(0, last + 1):
1244 linkrev = filelog.linkrev(j)
1244 linkrev = filelog.linkrev(j)
1245 if linkrev < minrev:
1245 if linkrev < minrev:
1246 continue
1246 continue
1247 # only yield rev for which we have the changelog, it can
1247 # only yield rev for which we have the changelog, it can
1248 # happen while doing "hg log" during a pull or commit
1248 # happen while doing "hg log" during a pull or commit
1249 if linkrev >= cl_count:
1249 if linkrev >= cl_count:
1250 break
1250 break
1251
1251
1252 parentlinkrevs = []
1252 parentlinkrevs = []
1253 for p in filelog.parentrevs(j):
1253 for p in filelog.parentrevs(j):
1254 if p != nullrev:
1254 if p != nullrev:
1255 parentlinkrevs.append(filelog.linkrev(p))
1255 parentlinkrevs.append(filelog.linkrev(p))
1256 n = filelog.node(j)
1256 n = filelog.node(j)
1257 revs.append((linkrev, parentlinkrevs,
1257 revs.append((linkrev, parentlinkrevs,
1258 follow and filelog.renamed(n)))
1258 follow and filelog.renamed(n)))
1259
1259
1260 return reversed(revs)
1260 return reversed(revs)
1261 def iterfiles():
1261 def iterfiles():
1262 pctx = repo['.']
1262 pctx = repo['.']
1263 for filename in match.files():
1263 for filename in match.files():
1264 if follow:
1264 if follow:
1265 if filename not in pctx:
1265 if filename not in pctx:
1266 raise util.Abort(_('cannot follow file not in parent '
1266 raise util.Abort(_('cannot follow file not in parent '
1267 'revision: "%s"') % filename)
1267 'revision: "%s"') % filename)
1268 yield filename, pctx[filename].filenode()
1268 yield filename, pctx[filename].filenode()
1269 else:
1269 else:
1270 yield filename, None
1270 yield filename, None
1271 for filename_node in copies:
1271 for filename_node in copies:
1272 yield filename_node
1272 yield filename_node
1273
1273
1274 for file_, node in iterfiles():
1274 for file_, node in iterfiles():
1275 filelog = repo.file(file_)
1275 filelog = repo.file(file_)
1276 if not len(filelog):
1276 if not len(filelog):
1277 if node is None:
1277 if node is None:
1278 # A zero count may be a directory or deleted file, so
1278 # A zero count may be a directory or deleted file, so
1279 # try to find matching entries on the slow path.
1279 # try to find matching entries on the slow path.
1280 if follow:
1280 if follow:
1281 raise util.Abort(
1281 raise util.Abort(
1282 _('cannot follow nonexistent file: "%s"') % file_)
1282 _('cannot follow nonexistent file: "%s"') % file_)
1283 raise FileWalkError("Cannot walk via filelog")
1283 raise FileWalkError("Cannot walk via filelog")
1284 else:
1284 else:
1285 continue
1285 continue
1286
1286
1287 if node is None:
1287 if node is None:
1288 last = len(filelog) - 1
1288 last = len(filelog) - 1
1289 else:
1289 else:
1290 last = filelog.rev(node)
1290 last = filelog.rev(node)
1291
1291
1292
1292
1293 # keep track of all ancestors of the file
1293 # keep track of all ancestors of the file
1294 ancestors = set([filelog.linkrev(last)])
1294 ancestors = set([filelog.linkrev(last)])
1295
1295
1296 # iterate from latest to oldest revision
1296 # iterate from latest to oldest revision
1297 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1297 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1298 if not follow:
1298 if not follow:
1299 if rev > maxrev:
1299 if rev > maxrev:
1300 continue
1300 continue
1301 else:
1301 else:
1302 # Note that last might not be the first interesting
1302 # Note that last might not be the first interesting
1303 # rev to us:
1303 # rev to us:
1304 # if the file has been changed after maxrev, we'll
1304 # if the file has been changed after maxrev, we'll
1305 # have linkrev(last) > maxrev, and we still need
1305 # have linkrev(last) > maxrev, and we still need
1306 # to explore the file graph
1306 # to explore the file graph
1307 if rev not in ancestors:
1307 if rev not in ancestors:
1308 continue
1308 continue
1309 # XXX insert 1327 fix here
1309 # XXX insert 1327 fix here
1310 if flparentlinkrevs:
1310 if flparentlinkrevs:
1311 ancestors.update(flparentlinkrevs)
1311 ancestors.update(flparentlinkrevs)
1312
1312
1313 fncache.setdefault(rev, []).append(file_)
1313 fncache.setdefault(rev, []).append(file_)
1314 wanted.add(rev)
1314 wanted.add(rev)
1315 if copied:
1315 if copied:
1316 copies.append(copied)
1316 copies.append(copied)
1317
1317
1318 return wanted
1318 return wanted
1319
1319
1320 def walkchangerevs(repo, match, opts, prepare):
1320 def walkchangerevs(repo, match, opts, prepare):
1321 '''Iterate over files and the revs in which they changed.
1321 '''Iterate over files and the revs in which they changed.
1322
1322
1323 Callers most commonly need to iterate backwards over the history
1323 Callers most commonly need to iterate backwards over the history
1324 in which they are interested. Doing so has awful (quadratic-looking)
1324 in which they are interested. Doing so has awful (quadratic-looking)
1325 performance, so we use iterators in a "windowed" way.
1325 performance, so we use iterators in a "windowed" way.
1326
1326
1327 We walk a window of revisions in the desired order. Within the
1327 We walk a window of revisions in the desired order. Within the
1328 window, we first walk forwards to gather data, then in the desired
1328 window, we first walk forwards to gather data, then in the desired
1329 order (usually backwards) to display it.
1329 order (usually backwards) to display it.
1330
1330
1331 This function returns an iterator yielding contexts. Before
1331 This function returns an iterator yielding contexts. Before
1332 yielding each context, the iterator will first call the prepare
1332 yielding each context, the iterator will first call the prepare
1333 function on each context in the window in forward order.'''
1333 function on each context in the window in forward order.'''
1334
1334
1335 follow = opts.get('follow') or opts.get('follow_first')
1335 follow = opts.get('follow') or opts.get('follow_first')
1336
1336
1337 if opts.get('rev'):
1337 if opts.get('rev'):
1338 revs = scmutil.revrange(repo, opts.get('rev'))
1338 revs = scmutil.revrange(repo, opts.get('rev'))
1339 elif follow:
1339 elif follow:
1340 revs = repo.revs('reverse(:.)')
1340 revs = repo.revs('reverse(:.)')
1341 else:
1341 else:
1342 revs = revset.spanset(repo)
1342 revs = revset.spanset(repo)
1343 revs.reverse()
1343 revs.reverse()
1344 if not revs:
1344 if not revs:
1345 return []
1345 return []
1346 wanted = set()
1346 wanted = set()
1347 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1347 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1348 fncache = {}
1348 fncache = {}
1349 change = repo.changectx
1349 change = repo.changectx
1350
1350
1351 # First step is to fill wanted, the set of revisions that we want to yield.
1351 # First step is to fill wanted, the set of revisions that we want to yield.
1352 # When it does not induce extra cost, we also fill fncache for revisions in
1352 # When it does not induce extra cost, we also fill fncache for revisions in
1353 # wanted: a cache of filenames that were changed (ctx.files()) and that
1353 # wanted: a cache of filenames that were changed (ctx.files()) and that
1354 # match the file filtering conditions.
1354 # match the file filtering conditions.
1355
1355
1356 if not slowpath and not match.files():
1356 if not slowpath and not match.files():
1357 # No files, no patterns. Display all revs.
1357 # No files, no patterns. Display all revs.
1358 wanted = revs
1358 wanted = revs
1359
1359
1360 if not slowpath and match.files():
1360 if not slowpath and match.files():
1361 # We only have to read through the filelog to find wanted revisions
1361 # We only have to read through the filelog to find wanted revisions
1362
1362
1363 try:
1363 try:
1364 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1364 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1365 except FileWalkError:
1365 except FileWalkError:
1366 slowpath = True
1366 slowpath = True
1367
1367
1368 # We decided to fall back to the slowpath because at least one
1368 # We decided to fall back to the slowpath because at least one
1369 # of the paths was not a file. Check to see if at least one of them
1369 # of the paths was not a file. Check to see if at least one of them
1370 # existed in history, otherwise simply return
1370 # existed in history, otherwise simply return
1371 for path in match.files():
1371 for path in match.files():
1372 if path == '.' or path in repo.store:
1372 if path == '.' or path in repo.store:
1373 break
1373 break
1374 else:
1374 else:
1375 return []
1375 return []
1376
1376
1377 if slowpath:
1377 if slowpath:
1378 # We have to read the changelog to match filenames against
1378 # We have to read the changelog to match filenames against
1379 # changed files
1379 # changed files
1380
1380
1381 if follow:
1381 if follow:
1382 raise util.Abort(_('can only follow copies/renames for explicit '
1382 raise util.Abort(_('can only follow copies/renames for explicit '
1383 'filenames'))
1383 'filenames'))
1384
1384
1385 # The slow path checks files modified in every changeset.
1385 # The slow path checks files modified in every changeset.
1386 # This is really slow on large repos, so compute the set lazily.
1386 # This is really slow on large repos, so compute the set lazily.
1387 class lazywantedset(object):
1387 class lazywantedset(object):
1388 def __init__(self):
1388 def __init__(self):
1389 self.set = set()
1389 self.set = set()
1390 self.revs = set(revs)
1390 self.revs = set(revs)
1391
1391
1392 # No need to worry about locality here because it will be accessed
1392 # No need to worry about locality here because it will be accessed
1393 # in the same order as the increasing window below.
1393 # in the same order as the increasing window below.
1394 def __contains__(self, value):
1394 def __contains__(self, value):
1395 if value in self.set:
1395 if value in self.set:
1396 return True
1396 return True
1397 elif not value in self.revs:
1397 elif not value in self.revs:
1398 return False
1398 return False
1399 else:
1399 else:
1400 self.revs.discard(value)
1400 self.revs.discard(value)
1401 ctx = change(value)
1401 ctx = change(value)
1402 matches = filter(match, ctx.files())
1402 matches = filter(match, ctx.files())
1403 if matches:
1403 if matches:
1404 fncache[value] = matches
1404 fncache[value] = matches
1405 self.set.add(value)
1405 self.set.add(value)
1406 return True
1406 return True
1407 return False
1407 return False
1408
1408
1409 def discard(self, value):
1409 def discard(self, value):
1410 self.revs.discard(value)
1410 self.revs.discard(value)
1411 self.set.discard(value)
1411 self.set.discard(value)
1412
1412
1413 wanted = lazywantedset()
1413 wanted = lazywantedset()
1414
1414
1415 class followfilter(object):
1415 class followfilter(object):
1416 def __init__(self, onlyfirst=False):
1416 def __init__(self, onlyfirst=False):
1417 self.startrev = nullrev
1417 self.startrev = nullrev
1418 self.roots = set()
1418 self.roots = set()
1419 self.onlyfirst = onlyfirst
1419 self.onlyfirst = onlyfirst
1420
1420
1421 def match(self, rev):
1421 def match(self, rev):
1422 def realparents(rev):
1422 def realparents(rev):
1423 if self.onlyfirst:
1423 if self.onlyfirst:
1424 return repo.changelog.parentrevs(rev)[0:1]
1424 return repo.changelog.parentrevs(rev)[0:1]
1425 else:
1425 else:
1426 return filter(lambda x: x != nullrev,
1426 return filter(lambda x: x != nullrev,
1427 repo.changelog.parentrevs(rev))
1427 repo.changelog.parentrevs(rev))
1428
1428
1429 if self.startrev == nullrev:
1429 if self.startrev == nullrev:
1430 self.startrev = rev
1430 self.startrev = rev
1431 return True
1431 return True
1432
1432
1433 if rev > self.startrev:
1433 if rev > self.startrev:
1434 # forward: all descendants
1434 # forward: all descendants
1435 if not self.roots:
1435 if not self.roots:
1436 self.roots.add(self.startrev)
1436 self.roots.add(self.startrev)
1437 for parent in realparents(rev):
1437 for parent in realparents(rev):
1438 if parent in self.roots:
1438 if parent in self.roots:
1439 self.roots.add(rev)
1439 self.roots.add(rev)
1440 return True
1440 return True
1441 else:
1441 else:
1442 # backwards: all parents
1442 # backwards: all parents
1443 if not self.roots:
1443 if not self.roots:
1444 self.roots.update(realparents(self.startrev))
1444 self.roots.update(realparents(self.startrev))
1445 if rev in self.roots:
1445 if rev in self.roots:
1446 self.roots.remove(rev)
1446 self.roots.remove(rev)
1447 self.roots.update(realparents(rev))
1447 self.roots.update(realparents(rev))
1448 return True
1448 return True
1449
1449
1450 return False
1450 return False
1451
1451
1452 # it might be worthwhile to do this in the iterator if the rev range
1452 # it might be worthwhile to do this in the iterator if the rev range
1453 # is descending and the prune args are all within that range
1453 # is descending and the prune args are all within that range
1454 for rev in opts.get('prune', ()):
1454 for rev in opts.get('prune', ()):
1455 rev = repo[rev].rev()
1455 rev = repo[rev].rev()
1456 ff = followfilter()
1456 ff = followfilter()
1457 stop = min(revs[0], revs[-1])
1457 stop = min(revs[0], revs[-1])
1458 for x in xrange(rev, stop - 1, -1):
1458 for x in xrange(rev, stop - 1, -1):
1459 if ff.match(x):
1459 if ff.match(x):
1460 wanted = wanted - [x]
1460 wanted = wanted - [x]
1461
1461
1462 # Now that wanted is correctly initialized, we can iterate over the
1462 # Now that wanted is correctly initialized, we can iterate over the
1463 # revision range, yielding only revisions in wanted.
1463 # revision range, yielding only revisions in wanted.
1464 def iterate():
1464 def iterate():
1465 if follow and not match.files():
1465 if follow and not match.files():
1466 ff = followfilter(onlyfirst=opts.get('follow_first'))
1466 ff = followfilter(onlyfirst=opts.get('follow_first'))
1467 def want(rev):
1467 def want(rev):
1468 return ff.match(rev) and rev in wanted
1468 return ff.match(rev) and rev in wanted
1469 else:
1469 else:
1470 def want(rev):
1470 def want(rev):
1471 return rev in wanted
1471 return rev in wanted
1472
1472
1473 it = iter(revs)
1473 it = iter(revs)
1474 stopiteration = False
1474 stopiteration = False
1475 for windowsize in increasingwindows():
1475 for windowsize in increasingwindows():
1476 nrevs = []
1476 nrevs = []
1477 for i in xrange(windowsize):
1477 for i in xrange(windowsize):
1478 try:
1478 try:
1479 rev = it.next()
1479 rev = it.next()
1480 if want(rev):
1480 if want(rev):
1481 nrevs.append(rev)
1481 nrevs.append(rev)
1482 except (StopIteration):
1482 except (StopIteration):
1483 stopiteration = True
1483 stopiteration = True
1484 break
1484 break
1485 for rev in sorted(nrevs):
1485 for rev in sorted(nrevs):
1486 fns = fncache.get(rev)
1486 fns = fncache.get(rev)
1487 ctx = change(rev)
1487 ctx = change(rev)
1488 if not fns:
1488 if not fns:
1489 def fns_generator():
1489 def fns_generator():
1490 for f in ctx.files():
1490 for f in ctx.files():
1491 if match(f):
1491 if match(f):
1492 yield f
1492 yield f
1493 fns = fns_generator()
1493 fns = fns_generator()
1494 prepare(ctx, fns)
1494 prepare(ctx, fns)
1495 for rev in nrevs:
1495 for rev in nrevs:
1496 yield change(rev)
1496 yield change(rev)
1497
1497
1498 if stopiteration:
1498 if stopiteration:
1499 break
1499 break
1500
1500
1501 return iterate()
1501 return iterate()
1502
1502
1503 def _makelogfilematcher(repo, files, followfirst):
1503 def _makelogfilematcher(repo, files, followfirst):
1504 # When displaying a revision with --patch --follow FILE, we have
1504 # When displaying a revision with --patch --follow FILE, we have
1505 # to know which file of the revision must be diffed. With
1505 # to know which file of the revision must be diffed. With
1506 # --follow, we want the names of the ancestors of FILE in the
1506 # --follow, we want the names of the ancestors of FILE in the
1507 # revision, stored in "fcache". "fcache" is populated by
1507 # revision, stored in "fcache". "fcache" is populated by
1508 # reproducing the graph traversal already done by --follow revset
1508 # reproducing the graph traversal already done by --follow revset
1509 # and relating linkrevs to file names (which is not "correct" but
1509 # and relating linkrevs to file names (which is not "correct" but
1510 # good enough).
1510 # good enough).
1511 fcache = {}
1511 fcache = {}
1512 fcacheready = [False]
1512 fcacheready = [False]
1513 pctx = repo['.']
1513 pctx = repo['.']
1514
1514
1515 def populate():
1515 def populate():
1516 for fn in files:
1516 for fn in files:
1517 for i in ((pctx[fn],), pctx[fn].ancestors(followfirst=followfirst)):
1517 for i in ((pctx[fn],), pctx[fn].ancestors(followfirst=followfirst)):
1518 for c in i:
1518 for c in i:
1519 fcache.setdefault(c.linkrev(), set()).add(c.path())
1519 fcache.setdefault(c.linkrev(), set()).add(c.path())
1520
1520
1521 def filematcher(rev):
1521 def filematcher(rev):
1522 if not fcacheready[0]:
1522 if not fcacheready[0]:
1523 # Lazy initialization
1523 # Lazy initialization
1524 fcacheready[0] = True
1524 fcacheready[0] = True
1525 populate()
1525 populate()
1526 return scmutil.matchfiles(repo, fcache.get(rev, []))
1526 return scmutil.matchfiles(repo, fcache.get(rev, []))
1527
1527
1528 return filematcher
1528 return filematcher
1529
1529
1530 def _makelogrevset(repo, pats, opts, revs):
1530 def _makelogrevset(repo, pats, opts, revs):
1531 """Return (expr, filematcher) where expr is a revset string built
1531 """Return (expr, filematcher) where expr is a revset string built
1532 from log options and file patterns or None. If --stat or --patch
1532 from log options and file patterns or None. If --stat or --patch
1533 are not passed filematcher is None. Otherwise it is a callable
1533 are not passed filematcher is None. Otherwise it is a callable
1534 taking a revision number and returning a match objects filtering
1534 taking a revision number and returning a match objects filtering
1535 the files to be detailed when displaying the revision.
1535 the files to be detailed when displaying the revision.
1536 """
1536 """
1537 opt2revset = {
1537 opt2revset = {
1538 'no_merges': ('not merge()', None),
1538 'no_merges': ('not merge()', None),
1539 'only_merges': ('merge()', None),
1539 'only_merges': ('merge()', None),
1540 '_ancestors': ('ancestors(%(val)s)', None),
1540 '_ancestors': ('ancestors(%(val)s)', None),
1541 '_fancestors': ('_firstancestors(%(val)s)', None),
1541 '_fancestors': ('_firstancestors(%(val)s)', None),
1542 '_descendants': ('descendants(%(val)s)', None),
1542 '_descendants': ('descendants(%(val)s)', None),
1543 '_fdescendants': ('_firstdescendants(%(val)s)', None),
1543 '_fdescendants': ('_firstdescendants(%(val)s)', None),
1544 '_matchfiles': ('_matchfiles(%(val)s)', None),
1544 '_matchfiles': ('_matchfiles(%(val)s)', None),
1545 'date': ('date(%(val)r)', None),
1545 'date': ('date(%(val)r)', None),
1546 'branch': ('branch(%(val)r)', ' or '),
1546 'branch': ('branch(%(val)r)', ' or '),
1547 '_patslog': ('filelog(%(val)r)', ' or '),
1547 '_patslog': ('filelog(%(val)r)', ' or '),
1548 '_patsfollow': ('follow(%(val)r)', ' or '),
1548 '_patsfollow': ('follow(%(val)r)', ' or '),
1549 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
1549 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
1550 'keyword': ('keyword(%(val)r)', ' or '),
1550 'keyword': ('keyword(%(val)r)', ' or '),
1551 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
1551 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
1552 'user': ('user(%(val)r)', ' or '),
1552 'user': ('user(%(val)r)', ' or '),
1553 }
1553 }
1554
1554
1555 opts = dict(opts)
1555 opts = dict(opts)
1556 # follow or not follow?
1556 # follow or not follow?
1557 follow = opts.get('follow') or opts.get('follow_first')
1557 follow = opts.get('follow') or opts.get('follow_first')
1558 followfirst = opts.get('follow_first') and 1 or 0
1558 followfirst = opts.get('follow_first') and 1 or 0
1559 # --follow with FILE behaviour depends on revs...
1559 # --follow with FILE behaviour depends on revs...
1560 it = iter(revs)
1560 it = iter(revs)
1561 startrev = it.next()
1561 startrev = it.next()
1562 try:
1562 try:
1563 followdescendants = startrev < it.next()
1563 followdescendants = startrev < it.next()
1564 except (StopIteration):
1564 except (StopIteration):
1565 followdescendants = False
1565 followdescendants = False
1566
1566
1567 # branch and only_branch are really aliases and must be handled at
1567 # branch and only_branch are really aliases and must be handled at
1568 # the same time
1568 # the same time
1569 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
1569 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
1570 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
1570 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
1571 # pats/include/exclude are passed to match.match() directly in
1571 # pats/include/exclude are passed to match.match() directly in
1572 # _matchfiles() revset but walkchangerevs() builds its matcher with
1572 # _matchfiles() revset but walkchangerevs() builds its matcher with
1573 # scmutil.match(). The difference is input pats are globbed on
1573 # scmutil.match(). The difference is input pats are globbed on
1574 # platforms without shell expansion (windows).
1574 # platforms without shell expansion (windows).
1575 pctx = repo[None]
1575 pctx = repo[None]
1576 match, pats = scmutil.matchandpats(pctx, pats, opts)
1576 match, pats = scmutil.matchandpats(pctx, pats, opts)
1577 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1577 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1578 if not slowpath:
1578 if not slowpath:
1579 for f in match.files():
1579 for f in match.files():
1580 if follow and f not in pctx:
1580 if follow and f not in pctx:
1581 # If the file exists, it may be a directory, so let it
1581 # If the file exists, it may be a directory, so let it
1582 # take the slow path.
1582 # take the slow path.
1583 if os.path.exists(repo.wjoin(f)):
1583 if os.path.exists(repo.wjoin(f)):
1584 slowpath = True
1584 slowpath = True
1585 continue
1585 continue
1586 else:
1586 else:
1587 raise util.Abort(_('cannot follow file not in parent '
1587 raise util.Abort(_('cannot follow file not in parent '
1588 'revision: "%s"') % f)
1588 'revision: "%s"') % f)
1589 filelog = repo.file(f)
1589 filelog = repo.file(f)
1590 if not filelog:
1590 if not filelog:
1591 # A zero count may be a directory or deleted file, so
1591 # A zero count may be a directory or deleted file, so
1592 # try to find matching entries on the slow path.
1592 # try to find matching entries on the slow path.
1593 if follow:
1593 if follow:
1594 raise util.Abort(
1594 raise util.Abort(
1595 _('cannot follow nonexistent file: "%s"') % f)
1595 _('cannot follow nonexistent file: "%s"') % f)
1596 slowpath = True
1596 slowpath = True
1597
1597
1598 # We decided to fall back to the slowpath because at least one
1598 # We decided to fall back to the slowpath because at least one
1599 # of the paths was not a file. Check to see if at least one of them
1599 # of the paths was not a file. Check to see if at least one of them
1600 # existed in history - in that case, we'll continue down the
1600 # existed in history - in that case, we'll continue down the
1601 # slowpath; otherwise, we can turn off the slowpath
1601 # slowpath; otherwise, we can turn off the slowpath
1602 if slowpath:
1602 if slowpath:
1603 for path in match.files():
1603 for path in match.files():
1604 if path == '.' or path in repo.store:
1604 if path == '.' or path in repo.store:
1605 break
1605 break
1606 else:
1606 else:
1607 slowpath = False
1607 slowpath = False
1608
1608
1609 if slowpath:
1609 if slowpath:
1610 # See walkchangerevs() slow path.
1610 # See walkchangerevs() slow path.
1611 #
1611 #
1612 # pats/include/exclude cannot be represented as separate
1612 # pats/include/exclude cannot be represented as separate
1613 # revset expressions as their filtering logic applies at file
1613 # revset expressions as their filtering logic applies at file
1614 # level. For instance "-I a -X a" matches a revision touching
1614 # level. For instance "-I a -X a" matches a revision touching
1615 # "a" and "b" while "file(a) and not file(b)" does
1615 # "a" and "b" while "file(a) and not file(b)" does
1616 # not. Besides, filesets are evaluated against the working
1616 # not. Besides, filesets are evaluated against the working
1617 # directory.
1617 # directory.
1618 matchargs = ['r:', 'd:relpath']
1618 matchargs = ['r:', 'd:relpath']
1619 for p in pats:
1619 for p in pats:
1620 matchargs.append('p:' + p)
1620 matchargs.append('p:' + p)
1621 for p in opts.get('include', []):
1621 for p in opts.get('include', []):
1622 matchargs.append('i:' + p)
1622 matchargs.append('i:' + p)
1623 for p in opts.get('exclude', []):
1623 for p in opts.get('exclude', []):
1624 matchargs.append('x:' + p)
1624 matchargs.append('x:' + p)
1625 matchargs = ','.join(('%r' % p) for p in matchargs)
1625 matchargs = ','.join(('%r' % p) for p in matchargs)
1626 opts['_matchfiles'] = matchargs
1626 opts['_matchfiles'] = matchargs
1627 else:
1627 else:
1628 if follow:
1628 if follow:
1629 fpats = ('_patsfollow', '_patsfollowfirst')
1629 fpats = ('_patsfollow', '_patsfollowfirst')
1630 fnopats = (('_ancestors', '_fancestors'),
1630 fnopats = (('_ancestors', '_fancestors'),
1631 ('_descendants', '_fdescendants'))
1631 ('_descendants', '_fdescendants'))
1632 if pats:
1632 if pats:
1633 # follow() revset interprets its file argument as a
1633 # follow() revset interprets its file argument as a
1634 # manifest entry, so use match.files(), not pats.
1634 # manifest entry, so use match.files(), not pats.
1635 opts[fpats[followfirst]] = list(match.files())
1635 opts[fpats[followfirst]] = list(match.files())
1636 else:
1636 else:
1637 opts[fnopats[followdescendants][followfirst]] = str(startrev)
1637 opts[fnopats[followdescendants][followfirst]] = str(startrev)
1638 else:
1638 else:
1639 opts['_patslog'] = list(pats)
1639 opts['_patslog'] = list(pats)
1640
1640
1641 filematcher = None
1641 filematcher = None
1642 if opts.get('patch') or opts.get('stat'):
1642 if opts.get('patch') or opts.get('stat'):
1643 # When following files, track renames via a special matcher.
1643 # When following files, track renames via a special matcher.
1644 # If we're forced to take the slowpath it means we're following
1644 # If we're forced to take the slowpath it means we're following
1645 # at least one pattern/directory, so don't bother with rename tracking.
1645 # at least one pattern/directory, so don't bother with rename tracking.
1646 if follow and not match.always() and not slowpath:
1646 if follow and not match.always() and not slowpath:
1647 # _makelogfilematcher expects its files argument to be relative to
1647 # _makelogfilematcher expects its files argument to be relative to
1648 # the repo root, so use match.files(), not pats.
1648 # the repo root, so use match.files(), not pats.
1649 filematcher = _makelogfilematcher(repo, match.files(), followfirst)
1649 filematcher = _makelogfilematcher(repo, match.files(), followfirst)
1650 else:
1650 else:
1651 filematcher = lambda rev: match
1651 filematcher = lambda rev: match
1652
1652
1653 expr = []
1653 expr = []
1654 for op, val in opts.iteritems():
1654 for op, val in opts.iteritems():
1655 if not val:
1655 if not val:
1656 continue
1656 continue
1657 if op not in opt2revset:
1657 if op not in opt2revset:
1658 continue
1658 continue
1659 revop, andor = opt2revset[op]
1659 revop, andor = opt2revset[op]
1660 if '%(val)' not in revop:
1660 if '%(val)' not in revop:
1661 expr.append(revop)
1661 expr.append(revop)
1662 else:
1662 else:
1663 if not isinstance(val, list):
1663 if not isinstance(val, list):
1664 e = revop % {'val': val}
1664 e = revop % {'val': val}
1665 else:
1665 else:
1666 e = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
1666 e = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
1667 expr.append(e)
1667 expr.append(e)
1668
1668
1669 if expr:
1669 if expr:
1670 expr = '(' + ' and '.join(expr) + ')'
1670 expr = '(' + ' and '.join(expr) + ')'
1671 else:
1671 else:
1672 expr = None
1672 expr = None
1673 return expr, filematcher
1673 return expr, filematcher
1674
1674
1675 def getgraphlogrevs(repo, pats, opts):
1675 def getgraphlogrevs(repo, pats, opts):
1676 """Return (revs, expr, filematcher) where revs is an iterable of
1676 """Return (revs, expr, filematcher) where revs is an iterable of
1677 revision numbers, expr is a revset string built from log options
1677 revision numbers, expr is a revset string built from log options
1678 and file patterns or None, and used to filter 'revs'. If --stat or
1678 and file patterns or None, and used to filter 'revs'. If --stat or
1679 --patch are not passed filematcher is None. Otherwise it is a
1679 --patch are not passed filematcher is None. Otherwise it is a
1680 callable taking a revision number and returning a match objects
1680 callable taking a revision number and returning a match objects
1681 filtering the files to be detailed when displaying the revision.
1681 filtering the files to be detailed when displaying the revision.
1682 """
1682 """
1683 if not len(repo):
1683 if not len(repo):
1684 return [], None, None
1684 return [], None, None
1685 limit = loglimit(opts)
1685 limit = loglimit(opts)
1686 # Default --rev value depends on --follow but --follow behaviour
1686 # Default --rev value depends on --follow but --follow behaviour
1687 # depends on revisions resolved from --rev...
1687 # depends on revisions resolved from --rev...
1688 follow = opts.get('follow') or opts.get('follow_first')
1688 follow = opts.get('follow') or opts.get('follow_first')
1689 possiblyunsorted = False # whether revs might need sorting
1689 possiblyunsorted = False # whether revs might need sorting
1690 if opts.get('rev'):
1690 if opts.get('rev'):
1691 revs = scmutil.revrange(repo, opts['rev'])
1691 revs = scmutil.revrange(repo, opts['rev'])
1692 # Don't sort here because _makelogrevset might depend on the
1692 # Don't sort here because _makelogrevset might depend on the
1693 # order of revs
1693 # order of revs
1694 possiblyunsorted = True
1694 possiblyunsorted = True
1695 else:
1695 else:
1696 if follow and len(repo) > 0:
1696 if follow and len(repo) > 0:
1697 revs = repo.revs('reverse(:.)')
1697 revs = repo.revs('reverse(:.)')
1698 else:
1698 else:
1699 revs = revset.spanset(repo)
1699 revs = revset.spanset(repo)
1700 revs.reverse()
1700 revs.reverse()
1701 if not revs:
1701 if not revs:
1702 return revset.baseset(), None, None
1702 return revset.baseset(), None, None
1703 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1703 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1704 if possiblyunsorted:
1704 if possiblyunsorted:
1705 revs.sort(reverse=True)
1705 revs.sort(reverse=True)
1706 if expr:
1706 if expr:
1707 # Revset matchers often operate faster on revisions in changelog
1707 # Revset matchers often operate faster on revisions in changelog
1708 # order, because most filters deal with the changelog.
1708 # order, because most filters deal with the changelog.
1709 revs.reverse()
1709 revs.reverse()
1710 matcher = revset.match(repo.ui, expr)
1710 matcher = revset.match(repo.ui, expr)
1711 # Revset matches can reorder revisions. "A or B" typically returns
1711 # Revset matches can reorder revisions. "A or B" typically returns
1712 # returns the revision matching A then the revision matching B. Sort
1712 # returns the revision matching A then the revision matching B. Sort
1713 # again to fix that.
1713 # again to fix that.
1714 revs = matcher(repo, revs)
1714 revs = matcher(repo, revs)
1715 revs.sort(reverse=True)
1715 revs.sort(reverse=True)
1716 if limit is not None:
1716 if limit is not None:
1717 limitedrevs = revset.baseset()
1717 limitedrevs = revset.baseset()
1718 for idx, rev in enumerate(revs):
1718 for idx, rev in enumerate(revs):
1719 if idx >= limit:
1719 if idx >= limit:
1720 break
1720 break
1721 limitedrevs.append(rev)
1721 limitedrevs.append(rev)
1722 revs = limitedrevs
1722 revs = limitedrevs
1723
1723
1724 return revs, expr, filematcher
1724 return revs, expr, filematcher
1725
1725
1726 def getlogrevs(repo, pats, opts):
1726 def getlogrevs(repo, pats, opts):
1727 """Return (revs, expr, filematcher) where revs is an iterable of
1727 """Return (revs, expr, filematcher) where revs is an iterable of
1728 revision numbers, expr is a revset string built from log options
1728 revision numbers, expr is a revset string built from log options
1729 and file patterns or None, and used to filter 'revs'. If --stat or
1729 and file patterns or None, and used to filter 'revs'. If --stat or
1730 --patch are not passed filematcher is None. Otherwise it is a
1730 --patch are not passed filematcher is None. Otherwise it is a
1731 callable taking a revision number and returning a match objects
1731 callable taking a revision number and returning a match objects
1732 filtering the files to be detailed when displaying the revision.
1732 filtering the files to be detailed when displaying the revision.
1733 """
1733 """
1734 limit = loglimit(opts)
1734 limit = loglimit(opts)
1735 # Default --rev value depends on --follow but --follow behaviour
1735 # Default --rev value depends on --follow but --follow behaviour
1736 # depends on revisions resolved from --rev...
1736 # depends on revisions resolved from --rev...
1737 follow = opts.get('follow') or opts.get('follow_first')
1737 follow = opts.get('follow') or opts.get('follow_first')
1738 if opts.get('rev'):
1738 if opts.get('rev'):
1739 revs = scmutil.revrange(repo, opts['rev'])
1739 revs = scmutil.revrange(repo, opts['rev'])
1740 elif follow:
1740 elif follow:
1741 revs = repo.revs('reverse(:.)')
1741 revs = repo.revs('reverse(:.)')
1742 else:
1742 else:
1743 revs = revset.spanset(repo)
1743 revs = revset.spanset(repo)
1744 revs.reverse()
1744 revs.reverse()
1745 if not revs:
1745 if not revs:
1746 return revset.baseset([]), None, None
1746 return revset.baseset([]), None, None
1747 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1747 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1748 if expr:
1748 if expr:
1749 # Revset matchers often operate faster on revisions in changelog
1749 # Revset matchers often operate faster on revisions in changelog
1750 # order, because most filters deal with the changelog.
1750 # order, because most filters deal with the changelog.
1751 if not opts.get('rev'):
1751 if not opts.get('rev'):
1752 revs.reverse()
1752 revs.reverse()
1753 matcher = revset.match(repo.ui, expr)
1753 matcher = revset.match(repo.ui, expr)
1754 # Revset matches can reorder revisions. "A or B" typically returns
1754 # Revset matches can reorder revisions. "A or B" typically returns
1755 # returns the revision matching A then the revision matching B. Sort
1755 # returns the revision matching A then the revision matching B. Sort
1756 # again to fix that.
1756 # again to fix that.
1757 revs = matcher(repo, revs)
1757 revs = matcher(repo, revs)
1758 if not opts.get('rev'):
1758 if not opts.get('rev'):
1759 revs.sort(reverse=True)
1759 revs.sort(reverse=True)
1760 if limit is not None:
1760 if limit is not None:
1761 count = 0
1761 count = 0
1762 limitedrevs = revset.baseset([])
1762 limitedrevs = revset.baseset([])
1763 it = iter(revs)
1763 it = iter(revs)
1764 while count < limit:
1764 while count < limit:
1765 try:
1765 try:
1766 limitedrevs.append(it.next())
1766 limitedrevs.append(it.next())
1767 except (StopIteration):
1767 except (StopIteration):
1768 break
1768 break
1769 count += 1
1769 count += 1
1770 revs = limitedrevs
1770 revs = limitedrevs
1771
1771
1772 return revs, expr, filematcher
1772 return revs, expr, filematcher
1773
1773
1774 def displaygraph(ui, dag, displayer, showparents, edgefn, getrenamed=None,
1774 def displaygraph(ui, dag, displayer, showparents, edgefn, getrenamed=None,
1775 filematcher=None):
1775 filematcher=None):
1776 seen, state = [], graphmod.asciistate()
1776 seen, state = [], graphmod.asciistate()
1777 for rev, type, ctx, parents in dag:
1777 for rev, type, ctx, parents in dag:
1778 char = 'o'
1778 char = 'o'
1779 if ctx.node() in showparents:
1779 if ctx.node() in showparents:
1780 char = '@'
1780 char = '@'
1781 elif ctx.obsolete():
1781 elif ctx.obsolete():
1782 char = 'x'
1782 char = 'x'
1783 copies = None
1783 copies = None
1784 if getrenamed and ctx.rev():
1784 if getrenamed and ctx.rev():
1785 copies = []
1785 copies = []
1786 for fn in ctx.files():
1786 for fn in ctx.files():
1787 rename = getrenamed(fn, ctx.rev())
1787 rename = getrenamed(fn, ctx.rev())
1788 if rename:
1788 if rename:
1789 copies.append((fn, rename[0]))
1789 copies.append((fn, rename[0]))
1790 revmatchfn = None
1790 revmatchfn = None
1791 if filematcher is not None:
1791 if filematcher is not None:
1792 revmatchfn = filematcher(ctx.rev())
1792 revmatchfn = filematcher(ctx.rev())
1793 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
1793 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
1794 lines = displayer.hunk.pop(rev).split('\n')
1794 lines = displayer.hunk.pop(rev).split('\n')
1795 if not lines[-1]:
1795 if not lines[-1]:
1796 del lines[-1]
1796 del lines[-1]
1797 displayer.flush(rev)
1797 displayer.flush(rev)
1798 edges = edgefn(type, char, lines, seen, rev, parents)
1798 edges = edgefn(type, char, lines, seen, rev, parents)
1799 for type, char, lines, coldata in edges:
1799 for type, char, lines, coldata in edges:
1800 graphmod.ascii(ui, state, type, char, lines, coldata)
1800 graphmod.ascii(ui, state, type, char, lines, coldata)
1801 displayer.close()
1801 displayer.close()
1802
1802
1803 def graphlog(ui, repo, *pats, **opts):
1803 def graphlog(ui, repo, *pats, **opts):
1804 # Parameters are identical to log command ones
1804 # Parameters are identical to log command ones
1805 revs, expr, filematcher = getgraphlogrevs(repo, pats, opts)
1805 revs, expr, filematcher = getgraphlogrevs(repo, pats, opts)
1806 revdag = graphmod.dagwalker(repo, revs)
1806 revdag = graphmod.dagwalker(repo, revs)
1807
1807
1808 getrenamed = None
1808 getrenamed = None
1809 if opts.get('copies'):
1809 if opts.get('copies'):
1810 endrev = None
1810 endrev = None
1811 if opts.get('rev'):
1811 if opts.get('rev'):
1812 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
1812 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
1813 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
1813 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
1814 displayer = show_changeset(ui, repo, opts, buffered=True)
1814 displayer = show_changeset(ui, repo, opts, buffered=True)
1815 showparents = [ctx.node() for ctx in repo[None].parents()]
1815 showparents = [ctx.node() for ctx in repo[None].parents()]
1816 displaygraph(ui, revdag, displayer, showparents,
1816 displaygraph(ui, revdag, displayer, showparents,
1817 graphmod.asciiedges, getrenamed, filematcher)
1817 graphmod.asciiedges, getrenamed, filematcher)
1818
1818
1819 def checkunsupportedgraphflags(pats, opts):
1819 def checkunsupportedgraphflags(pats, opts):
1820 for op in ["newest_first"]:
1820 for op in ["newest_first"]:
1821 if op in opts and opts[op]:
1821 if op in opts and opts[op]:
1822 raise util.Abort(_("-G/--graph option is incompatible with --%s")
1822 raise util.Abort(_("-G/--graph option is incompatible with --%s")
1823 % op.replace("_", "-"))
1823 % op.replace("_", "-"))
1824
1824
1825 def graphrevs(repo, nodes, opts):
1825 def graphrevs(repo, nodes, opts):
1826 limit = loglimit(opts)
1826 limit = loglimit(opts)
1827 nodes.reverse()
1827 nodes.reverse()
1828 if limit is not None:
1828 if limit is not None:
1829 nodes = nodes[:limit]
1829 nodes = nodes[:limit]
1830 return graphmod.nodes(repo, nodes)
1830 return graphmod.nodes(repo, nodes)
1831
1831
1832 def add(ui, repo, match, dryrun, listsubrepos, prefix, explicitonly):
1832 def add(ui, repo, match, dryrun, listsubrepos, prefix, explicitonly):
1833 join = lambda f: os.path.join(prefix, f)
1833 join = lambda f: os.path.join(prefix, f)
1834 bad = []
1834 bad = []
1835 oldbad = match.bad
1835 oldbad = match.bad
1836 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1836 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1837 names = []
1837 names = []
1838 wctx = repo[None]
1838 wctx = repo[None]
1839 cca = None
1839 cca = None
1840 abort, warn = scmutil.checkportabilityalert(ui)
1840 abort, warn = scmutil.checkportabilityalert(ui)
1841 if abort or warn:
1841 if abort or warn:
1842 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
1842 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
1843 for f in repo.walk(match):
1843 for f in repo.walk(match):
1844 exact = match.exact(f)
1844 exact = match.exact(f)
1845 if exact or not explicitonly and f not in repo.dirstate:
1845 if exact or not explicitonly and f not in repo.dirstate:
1846 if cca:
1846 if cca:
1847 cca(f)
1847 cca(f)
1848 names.append(f)
1848 names.append(f)
1849 if ui.verbose or not exact:
1849 if ui.verbose or not exact:
1850 ui.status(_('adding %s\n') % match.rel(join(f)))
1850 ui.status(_('adding %s\n') % match.rel(join(f)))
1851
1851
1852 for subpath in sorted(wctx.substate):
1852 for subpath in sorted(wctx.substate):
1853 sub = wctx.sub(subpath)
1853 sub = wctx.sub(subpath)
1854 try:
1854 try:
1855 submatch = matchmod.narrowmatcher(subpath, match)
1855 submatch = matchmod.narrowmatcher(subpath, match)
1856 if listsubrepos:
1856 if listsubrepos:
1857 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
1857 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
1858 False))
1858 False))
1859 else:
1859 else:
1860 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
1860 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
1861 True))
1861 True))
1862 except error.LookupError:
1862 except error.LookupError:
1863 ui.status(_("skipping missing subrepository: %s\n")
1863 ui.status(_("skipping missing subrepository: %s\n")
1864 % join(subpath))
1864 % join(subpath))
1865
1865
1866 if not dryrun:
1866 if not dryrun:
1867 rejected = wctx.add(names, prefix)
1867 rejected = wctx.add(names, prefix)
1868 bad.extend(f for f in rejected if f in match.files())
1868 bad.extend(f for f in rejected if f in match.files())
1869 return bad
1869 return bad
1870
1870
1871 def forget(ui, repo, match, prefix, explicitonly):
1871 def forget(ui, repo, match, prefix, explicitonly):
1872 join = lambda f: os.path.join(prefix, f)
1872 join = lambda f: os.path.join(prefix, f)
1873 bad = []
1873 bad = []
1874 oldbad = match.bad
1874 oldbad = match.bad
1875 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1875 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1876 wctx = repo[None]
1876 wctx = repo[None]
1877 forgot = []
1877 forgot = []
1878 s = repo.status(match=match, clean=True)
1878 s = repo.status(match=match, clean=True)
1879 forget = sorted(s[0] + s[1] + s[3] + s[6])
1879 forget = sorted(s[0] + s[1] + s[3] + s[6])
1880 if explicitonly:
1880 if explicitonly:
1881 forget = [f for f in forget if match.exact(f)]
1881 forget = [f for f in forget if match.exact(f)]
1882
1882
1883 for subpath in sorted(wctx.substate):
1883 for subpath in sorted(wctx.substate):
1884 sub = wctx.sub(subpath)
1884 sub = wctx.sub(subpath)
1885 try:
1885 try:
1886 submatch = matchmod.narrowmatcher(subpath, match)
1886 submatch = matchmod.narrowmatcher(subpath, match)
1887 subbad, subforgot = sub.forget(ui, submatch, prefix)
1887 subbad, subforgot = sub.forget(ui, submatch, prefix)
1888 bad.extend([subpath + '/' + f for f in subbad])
1888 bad.extend([subpath + '/' + f for f in subbad])
1889 forgot.extend([subpath + '/' + f for f in subforgot])
1889 forgot.extend([subpath + '/' + f for f in subforgot])
1890 except error.LookupError:
1890 except error.LookupError:
1891 ui.status(_("skipping missing subrepository: %s\n")
1891 ui.status(_("skipping missing subrepository: %s\n")
1892 % join(subpath))
1892 % join(subpath))
1893
1893
1894 if not explicitonly:
1894 if not explicitonly:
1895 for f in match.files():
1895 for f in match.files():
1896 if f not in repo.dirstate and not os.path.isdir(match.rel(join(f))):
1896 if f not in repo.dirstate and not os.path.isdir(match.rel(join(f))):
1897 if f not in forgot:
1897 if f not in forgot:
1898 if os.path.exists(match.rel(join(f))):
1898 if os.path.exists(match.rel(join(f))):
1899 ui.warn(_('not removing %s: '
1899 ui.warn(_('not removing %s: '
1900 'file is already untracked\n')
1900 'file is already untracked\n')
1901 % match.rel(join(f)))
1901 % match.rel(join(f)))
1902 bad.append(f)
1902 bad.append(f)
1903
1903
1904 for f in forget:
1904 for f in forget:
1905 if ui.verbose or not match.exact(f):
1905 if ui.verbose or not match.exact(f):
1906 ui.status(_('removing %s\n') % match.rel(join(f)))
1906 ui.status(_('removing %s\n') % match.rel(join(f)))
1907
1907
1908 rejected = wctx.forget(forget, prefix)
1908 rejected = wctx.forget(forget, prefix)
1909 bad.extend(f for f in rejected if f in match.files())
1909 bad.extend(f for f in rejected if f in match.files())
1910 forgot.extend(forget)
1910 forgot.extend(forget)
1911 return bad, forgot
1911 return bad, forgot
1912
1912
1913 def cat(ui, repo, ctx, matcher, prefix, **opts):
1913 def cat(ui, repo, ctx, matcher, prefix, **opts):
1914 err = 1
1914 err = 1
1915
1915
1916 def write(path):
1916 def write(path):
1917 fp = makefileobj(repo, opts.get('output'), ctx.node(),
1917 fp = makefileobj(repo, opts.get('output'), ctx.node(),
1918 pathname=os.path.join(prefix, path))
1918 pathname=os.path.join(prefix, path))
1919 data = ctx[path].data()
1919 data = ctx[path].data()
1920 if opts.get('decode'):
1920 if opts.get('decode'):
1921 data = repo.wwritedata(path, data)
1921 data = repo.wwritedata(path, data)
1922 fp.write(data)
1922 fp.write(data)
1923 fp.close()
1923 fp.close()
1924
1924
1925 # Automation often uses hg cat on single files, so special case it
1925 # Automation often uses hg cat on single files, so special case it
1926 # for performance to avoid the cost of parsing the manifest.
1926 # for performance to avoid the cost of parsing the manifest.
1927 if len(matcher.files()) == 1 and not matcher.anypats():
1927 if len(matcher.files()) == 1 and not matcher.anypats():
1928 file = matcher.files()[0]
1928 file = matcher.files()[0]
1929 mf = repo.manifest
1929 mf = repo.manifest
1930 mfnode = ctx._changeset[0]
1930 mfnode = ctx._changeset[0]
1931 if mf.find(mfnode, file)[0]:
1931 if mf.find(mfnode, file)[0]:
1932 write(file)
1932 write(file)
1933 return 0
1933 return 0
1934
1934
1935 # Don't warn about "missing" files that are really in subrepos
1935 # Don't warn about "missing" files that are really in subrepos
1936 bad = matcher.bad
1936 bad = matcher.bad
1937
1937
1938 def badfn(path, msg):
1938 def badfn(path, msg):
1939 for subpath in ctx.substate:
1939 for subpath in ctx.substate:
1940 if path.startswith(subpath):
1940 if path.startswith(subpath):
1941 return
1941 return
1942 bad(path, msg)
1942 bad(path, msg)
1943
1943
1944 matcher.bad = badfn
1944 matcher.bad = badfn
1945
1945
1946 for abs in ctx.walk(matcher):
1946 for abs in ctx.walk(matcher):
1947 write(abs)
1947 write(abs)
1948 err = 0
1948 err = 0
1949
1949
1950 matcher.bad = bad
1950 matcher.bad = bad
1951
1951
1952 for subpath in sorted(ctx.substate):
1952 for subpath in sorted(ctx.substate):
1953 sub = ctx.sub(subpath)
1953 sub = ctx.sub(subpath)
1954 try:
1954 try:
1955 submatch = matchmod.narrowmatcher(subpath, matcher)
1955 submatch = matchmod.narrowmatcher(subpath, matcher)
1956
1956
1957 if not sub.cat(ui, submatch, os.path.join(prefix, sub._path),
1957 if not sub.cat(ui, submatch, os.path.join(prefix, sub._path),
1958 **opts):
1958 **opts):
1959 err = 0
1959 err = 0
1960 except error.RepoLookupError:
1960 except error.RepoLookupError:
1961 ui.status(_("skipping missing subrepository: %s\n")
1961 ui.status(_("skipping missing subrepository: %s\n")
1962 % os.path.join(prefix, subpath))
1962 % os.path.join(prefix, subpath))
1963
1963
1964 return err
1964 return err
1965
1965
1966 def duplicatecopies(repo, rev, fromrev, skiprev=None):
1966 def duplicatecopies(repo, rev, fromrev, skiprev=None):
1967 '''reproduce copies from fromrev to rev in the dirstate
1967 '''reproduce copies from fromrev to rev in the dirstate
1968
1968
1969 If skiprev is specified, it's a revision that should be used to
1969 If skiprev is specified, it's a revision that should be used to
1970 filter copy records. Any copies that occur between fromrev and
1970 filter copy records. Any copies that occur between fromrev and
1971 skiprev will not be duplicated, even if they appear in the set of
1971 skiprev will not be duplicated, even if they appear in the set of
1972 copies between fromrev and rev.
1972 copies between fromrev and rev.
1973 '''
1973 '''
1974 exclude = {}
1974 exclude = {}
1975 if skiprev is not None:
1975 if skiprev is not None:
1976 exclude = copies.pathcopies(repo[fromrev], repo[skiprev])
1976 exclude = copies.pathcopies(repo[fromrev], repo[skiprev])
1977 for dst, src in copies.pathcopies(repo[fromrev], repo[rev]).iteritems():
1977 for dst, src in copies.pathcopies(repo[fromrev], repo[rev]).iteritems():
1978 # copies.pathcopies returns backward renames, so dst might not
1978 # copies.pathcopies returns backward renames, so dst might not
1979 # actually be in the dirstate
1979 # actually be in the dirstate
1980 if dst in exclude:
1980 if dst in exclude:
1981 continue
1981 continue
1982 if repo.dirstate[dst] in "nma":
1982 if repo.dirstate[dst] in "nma":
1983 repo.dirstate.copy(src, dst)
1983 repo.dirstate.copy(src, dst)
1984
1984
1985 def commit(ui, repo, commitfunc, pats, opts):
1985 def commit(ui, repo, commitfunc, pats, opts):
1986 '''commit the specified files or all outstanding changes'''
1986 '''commit the specified files or all outstanding changes'''
1987 date = opts.get('date')
1987 date = opts.get('date')
1988 if date:
1988 if date:
1989 opts['date'] = util.parsedate(date)
1989 opts['date'] = util.parsedate(date)
1990 message = logmessage(ui, opts)
1990 message = logmessage(ui, opts)
1991
1991
1992 # extract addremove carefully -- this function can be called from a command
1992 # extract addremove carefully -- this function can be called from a command
1993 # that doesn't support addremove
1993 # that doesn't support addremove
1994 if opts.get('addremove'):
1994 if opts.get('addremove'):
1995 scmutil.addremove(repo, pats, opts)
1995 scmutil.addremove(repo, pats, opts)
1996
1996
1997 return commitfunc(ui, repo, message,
1997 return commitfunc(ui, repo, message,
1998 scmutil.match(repo[None], pats, opts), opts)
1998 scmutil.match(repo[None], pats, opts), opts)
1999
1999
2000 def amend(ui, repo, commitfunc, old, extra, pats, opts):
2000 def amend(ui, repo, commitfunc, old, extra, pats, opts):
2001 ui.note(_('amending changeset %s\n') % old)
2001 ui.note(_('amending changeset %s\n') % old)
2002 base = old.p1()
2002 base = old.p1()
2003
2003
2004 wlock = lock = newid = None
2004 wlock = lock = newid = None
2005 try:
2005 try:
2006 wlock = repo.wlock()
2006 wlock = repo.wlock()
2007 lock = repo.lock()
2007 lock = repo.lock()
2008 tr = repo.transaction('amend')
2008 tr = repo.transaction('amend')
2009 try:
2009 try:
2010 # See if we got a message from -m or -l, if not, open the editor
2010 # See if we got a message from -m or -l, if not, open the editor
2011 # with the message of the changeset to amend
2011 # with the message of the changeset to amend
2012 message = logmessage(ui, opts)
2012 message = logmessage(ui, opts)
2013 # ensure logfile does not conflict with later enforcement of the
2013 # ensure logfile does not conflict with later enforcement of the
2014 # message. potential logfile content has been processed by
2014 # message. potential logfile content has been processed by
2015 # `logmessage` anyway.
2015 # `logmessage` anyway.
2016 opts.pop('logfile')
2016 opts.pop('logfile')
2017 # First, do a regular commit to record all changes in the working
2017 # First, do a regular commit to record all changes in the working
2018 # directory (if there are any)
2018 # directory (if there are any)
2019 ui.callhooks = False
2019 ui.callhooks = False
2020 currentbookmark = repo._bookmarkcurrent
2020 currentbookmark = repo._bookmarkcurrent
2021 try:
2021 try:
2022 repo._bookmarkcurrent = None
2022 repo._bookmarkcurrent = None
2023 opts['message'] = 'temporary amend commit for %s' % old
2023 opts['message'] = 'temporary amend commit for %s' % old
2024 node = commit(ui, repo, commitfunc, pats, opts)
2024 node = commit(ui, repo, commitfunc, pats, opts)
2025 finally:
2025 finally:
2026 repo._bookmarkcurrent = currentbookmark
2026 repo._bookmarkcurrent = currentbookmark
2027 ui.callhooks = True
2027 ui.callhooks = True
2028 ctx = repo[node]
2028 ctx = repo[node]
2029
2029
2030 # Participating changesets:
2030 # Participating changesets:
2031 #
2031 #
2032 # node/ctx o - new (intermediate) commit that contains changes
2032 # node/ctx o - new (intermediate) commit that contains changes
2033 # | from working dir to go into amending commit
2033 # | from working dir to go into amending commit
2034 # | (or a workingctx if there were no changes)
2034 # | (or a workingctx if there were no changes)
2035 # |
2035 # |
2036 # old o - changeset to amend
2036 # old o - changeset to amend
2037 # |
2037 # |
2038 # base o - parent of amending changeset
2038 # base o - parent of amending changeset
2039
2039
2040 # Update extra dict from amended commit (e.g. to preserve graft
2040 # Update extra dict from amended commit (e.g. to preserve graft
2041 # source)
2041 # source)
2042 extra.update(old.extra())
2042 extra.update(old.extra())
2043
2043
2044 # Also update it from the intermediate commit or from the wctx
2044 # Also update it from the intermediate commit or from the wctx
2045 extra.update(ctx.extra())
2045 extra.update(ctx.extra())
2046
2046
2047 if len(old.parents()) > 1:
2047 if len(old.parents()) > 1:
2048 # ctx.files() isn't reliable for merges, so fall back to the
2048 # ctx.files() isn't reliable for merges, so fall back to the
2049 # slower repo.status() method
2049 # slower repo.status() method
2050 files = set([fn for st in repo.status(base, old)[:3]
2050 files = set([fn for st in repo.status(base, old)[:3]
2051 for fn in st])
2051 for fn in st])
2052 else:
2052 else:
2053 files = set(old.files())
2053 files = set(old.files())
2054
2054
2055 # Second, we use either the commit we just did, or if there were no
2055 # Second, we use either the commit we just did, or if there were no
2056 # changes the parent of the working directory as the version of the
2056 # changes the parent of the working directory as the version of the
2057 # files in the final amend commit
2057 # files in the final amend commit
2058 if node:
2058 if node:
2059 ui.note(_('copying changeset %s to %s\n') % (ctx, base))
2059 ui.note(_('copying changeset %s to %s\n') % (ctx, base))
2060
2060
2061 user = ctx.user()
2061 user = ctx.user()
2062 date = ctx.date()
2062 date = ctx.date()
2063 # Recompute copies (avoid recording a -> b -> a)
2063 # Recompute copies (avoid recording a -> b -> a)
2064 copied = copies.pathcopies(base, ctx)
2064 copied = copies.pathcopies(base, ctx)
2065
2065
2066 # Prune files which were reverted by the updates: if old
2066 # Prune files which were reverted by the updates: if old
2067 # introduced file X and our intermediate commit, node,
2067 # introduced file X and our intermediate commit, node,
2068 # renamed that file, then those two files are the same and
2068 # renamed that file, then those two files are the same and
2069 # we can discard X from our list of files. Likewise if X
2069 # we can discard X from our list of files. Likewise if X
2070 # was deleted, it's no longer relevant
2070 # was deleted, it's no longer relevant
2071 files.update(ctx.files())
2071 files.update(ctx.files())
2072
2072
2073 def samefile(f):
2073 def samefile(f):
2074 if f in ctx.manifest():
2074 if f in ctx.manifest():
2075 a = ctx.filectx(f)
2075 a = ctx.filectx(f)
2076 if f in base.manifest():
2076 if f in base.manifest():
2077 b = base.filectx(f)
2077 b = base.filectx(f)
2078 return (not a.cmp(b)
2078 return (not a.cmp(b)
2079 and a.flags() == b.flags())
2079 and a.flags() == b.flags())
2080 else:
2080 else:
2081 return False
2081 return False
2082 else:
2082 else:
2083 return f not in base.manifest()
2083 return f not in base.manifest()
2084 files = [f for f in files if not samefile(f)]
2084 files = [f for f in files if not samefile(f)]
2085
2085
2086 def filectxfn(repo, ctx_, path):
2086 def filectxfn(repo, ctx_, path):
2087 try:
2087 try:
2088 fctx = ctx[path]
2088 fctx = ctx[path]
2089 flags = fctx.flags()
2089 flags = fctx.flags()
2090 mctx = context.memfilectx(repo,
2090 mctx = context.memfilectx(repo,
2091 fctx.path(), fctx.data(),
2091 fctx.path(), fctx.data(),
2092 islink='l' in flags,
2092 islink='l' in flags,
2093 isexec='x' in flags,
2093 isexec='x' in flags,
2094 copied=copied.get(path))
2094 copied=copied.get(path))
2095 return mctx
2095 return mctx
2096 except KeyError:
2096 except KeyError:
2097 raise IOError
2097 raise IOError
2098 else:
2098 else:
2099 ui.note(_('copying changeset %s to %s\n') % (old, base))
2099 ui.note(_('copying changeset %s to %s\n') % (old, base))
2100
2100
2101 # Use version of files as in the old cset
2101 # Use version of files as in the old cset
2102 def filectxfn(repo, ctx_, path):
2102 def filectxfn(repo, ctx_, path):
2103 try:
2103 try:
2104 return old.filectx(path)
2104 return old.filectx(path)
2105 except KeyError:
2105 except KeyError:
2106 raise IOError
2106 raise IOError
2107
2107
2108 user = opts.get('user') or old.user()
2108 user = opts.get('user') or old.user()
2109 date = opts.get('date') or old.date()
2109 date = opts.get('date') or old.date()
2110 editform = 'commit.amend'
2110 editform = 'commit.amend'
2111 editor = getcommiteditor(editform=editform, **opts)
2111 editor = getcommiteditor(editform=editform, **opts)
2112 if not message:
2112 if not message:
2113 editor = getcommiteditor(edit=True, editform=editform)
2113 editor = getcommiteditor(edit=True, editform=editform)
2114 message = old.description()
2114 message = old.description()
2115
2115
2116 pureextra = extra.copy()
2116 pureextra = extra.copy()
2117 extra['amend_source'] = old.hex()
2117 extra['amend_source'] = old.hex()
2118
2118
2119 new = context.memctx(repo,
2119 new = context.memctx(repo,
2120 parents=[base.node(), old.p2().node()],
2120 parents=[base.node(), old.p2().node()],
2121 text=message,
2121 text=message,
2122 files=files,
2122 files=files,
2123 filectxfn=filectxfn,
2123 filectxfn=filectxfn,
2124 user=user,
2124 user=user,
2125 date=date,
2125 date=date,
2126 extra=extra,
2126 extra=extra,
2127 editor=editor)
2127 editor=editor)
2128
2128
2129 newdesc = changelog.stripdesc(new.description())
2129 newdesc = changelog.stripdesc(new.description())
2130 if ((not node)
2130 if ((not node)
2131 and newdesc == old.description()
2131 and newdesc == old.description()
2132 and user == old.user()
2132 and user == old.user()
2133 and date == old.date()
2133 and date == old.date()
2134 and pureextra == old.extra()):
2134 and pureextra == old.extra()):
2135 # nothing changed. continuing here would create a new node
2135 # nothing changed. continuing here would create a new node
2136 # anyway because of the amend_source noise.
2136 # anyway because of the amend_source noise.
2137 #
2137 #
2138 # This not what we expect from amend.
2138 # This not what we expect from amend.
2139 return old.node()
2139 return old.node()
2140
2140
2141 ph = repo.ui.config('phases', 'new-commit', phases.draft)
2141 ph = repo.ui.config('phases', 'new-commit', phases.draft)
2142 try:
2142 try:
2143 if opts.get('secret'):
2143 if opts.get('secret'):
2144 commitphase = 'secret'
2144 commitphase = 'secret'
2145 else:
2145 else:
2146 commitphase = old.phase()
2146 commitphase = old.phase()
2147 repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
2147 repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
2148 newid = repo.commitctx(new)
2148 newid = repo.commitctx(new)
2149 finally:
2149 finally:
2150 repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
2150 repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
2151 if newid != old.node():
2151 if newid != old.node():
2152 # Reroute the working copy parent to the new changeset
2152 # Reroute the working copy parent to the new changeset
2153 repo.setparents(newid, nullid)
2153 repo.setparents(newid, nullid)
2154
2154
2155 # Move bookmarks from old parent to amend commit
2155 # Move bookmarks from old parent to amend commit
2156 bms = repo.nodebookmarks(old.node())
2156 bms = repo.nodebookmarks(old.node())
2157 if bms:
2157 if bms:
2158 marks = repo._bookmarks
2158 marks = repo._bookmarks
2159 for bm in bms:
2159 for bm in bms:
2160 marks[bm] = newid
2160 marks[bm] = newid
2161 marks.write()
2161 marks.write()
2162 #commit the whole amend process
2162 #commit the whole amend process
2163 if obsolete._enabled and newid != old.node():
2163 if obsolete._enabled and newid != old.node():
2164 # mark the new changeset as successor of the rewritten one
2164 # mark the new changeset as successor of the rewritten one
2165 new = repo[newid]
2165 new = repo[newid]
2166 obs = [(old, (new,))]
2166 obs = [(old, (new,))]
2167 if node:
2167 if node:
2168 obs.append((ctx, ()))
2168 obs.append((ctx, ()))
2169
2169
2170 obsolete.createmarkers(repo, obs)
2170 obsolete.createmarkers(repo, obs)
2171 tr.close()
2171 tr.close()
2172 finally:
2172 finally:
2173 tr.release()
2173 tr.release()
2174 if (not obsolete._enabled) and newid != old.node():
2174 if (not obsolete._enabled) and newid != old.node():
2175 # Strip the intermediate commit (if there was one) and the amended
2175 # Strip the intermediate commit (if there was one) and the amended
2176 # commit
2176 # commit
2177 if node:
2177 if node:
2178 ui.note(_('stripping intermediate changeset %s\n') % ctx)
2178 ui.note(_('stripping intermediate changeset %s\n') % ctx)
2179 ui.note(_('stripping amended changeset %s\n') % old)
2179 ui.note(_('stripping amended changeset %s\n') % old)
2180 repair.strip(ui, repo, old.node(), topic='amend-backup')
2180 repair.strip(ui, repo, old.node(), topic='amend-backup')
2181 finally:
2181 finally:
2182 if newid is None:
2182 if newid is None:
2183 repo.dirstate.invalidate()
2183 repo.dirstate.invalidate()
2184 lockmod.release(lock, wlock)
2184 lockmod.release(lock, wlock)
2185 return newid
2185 return newid
2186
2186
2187 def commiteditor(repo, ctx, subs, editform=''):
2187 def commiteditor(repo, ctx, subs, editform=''):
2188 if ctx.description():
2188 if ctx.description():
2189 return ctx.description()
2189 return ctx.description()
2190 return commitforceeditor(repo, ctx, subs, editform=editform)
2190 return commitforceeditor(repo, ctx, subs, editform=editform)
2191
2191
2192 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2192 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2193 editform=''):
2193 editform=''):
2194 if not extramsg:
2194 if not extramsg:
2195 extramsg = _("Leave message empty to abort commit.")
2195 extramsg = _("Leave message empty to abort commit.")
2196
2196
2197 forms = [e for e in editform.split('.') if e]
2197 forms = [e for e in editform.split('.') if e]
2198 forms.insert(0, 'changeset')
2198 forms.insert(0, 'changeset')
2199 while forms:
2199 while forms:
2200 tmpl = repo.ui.config('committemplate', '.'.join(forms))
2200 tmpl = repo.ui.config('committemplate', '.'.join(forms))
2201 if tmpl:
2201 if tmpl:
2202 committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl)
2202 committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl)
2203 break
2203 break
2204 forms.pop()
2204 forms.pop()
2205 else:
2205 else:
2206 committext = buildcommittext(repo, ctx, subs, extramsg)
2206 committext = buildcommittext(repo, ctx, subs, extramsg)
2207
2207
2208 # run editor in the repository root
2208 # run editor in the repository root
2209 olddir = os.getcwd()
2209 olddir = os.getcwd()
2210 os.chdir(repo.root)
2210 os.chdir(repo.root)
2211 text = repo.ui.edit(committext, ctx.user(), ctx.extra())
2211 text = repo.ui.edit(committext, ctx.user(), ctx.extra())
2212 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2212 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2213 os.chdir(olddir)
2213 os.chdir(olddir)
2214
2214
2215 if finishdesc:
2215 if finishdesc:
2216 text = finishdesc(text)
2216 text = finishdesc(text)
2217 if not text.strip():
2217 if not text.strip():
2218 raise util.Abort(_("empty commit message"))
2218 raise util.Abort(_("empty commit message"))
2219
2219
2220 return text
2220 return text
2221
2221
2222 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
2222 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
2223 ui = repo.ui
2223 ui = repo.ui
2224 tmpl, mapfile = gettemplate(ui, tmpl, None)
2224 tmpl, mapfile = gettemplate(ui, tmpl, None)
2225
2225
2226 try:
2226 try:
2227 t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
2227 t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
2228 except SyntaxError, inst:
2228 except SyntaxError, inst:
2229 raise util.Abort(inst.args[0])
2229 raise util.Abort(inst.args[0])
2230
2230
2231 for k, v in repo.ui.configitems('committemplate'):
2232 if k != 'changeset':
2233 t.t.cache[k] = v
2234
2231 if not extramsg:
2235 if not extramsg:
2232 extramsg = '' # ensure that extramsg is string
2236 extramsg = '' # ensure that extramsg is string
2233
2237
2234 ui.pushbuffer()
2238 ui.pushbuffer()
2235 t.show(ctx, extramsg=extramsg)
2239 t.show(ctx, extramsg=extramsg)
2236 return ui.popbuffer()
2240 return ui.popbuffer()
2237
2241
2238 def buildcommittext(repo, ctx, subs, extramsg):
2242 def buildcommittext(repo, ctx, subs, extramsg):
2239 edittext = []
2243 edittext = []
2240 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2244 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2241 if ctx.description():
2245 if ctx.description():
2242 edittext.append(ctx.description())
2246 edittext.append(ctx.description())
2243 edittext.append("")
2247 edittext.append("")
2244 edittext.append("") # Empty line between message and comments.
2248 edittext.append("") # Empty line between message and comments.
2245 edittext.append(_("HG: Enter commit message."
2249 edittext.append(_("HG: Enter commit message."
2246 " Lines beginning with 'HG:' are removed."))
2250 " Lines beginning with 'HG:' are removed."))
2247 edittext.append("HG: %s" % extramsg)
2251 edittext.append("HG: %s" % extramsg)
2248 edittext.append("HG: --")
2252 edittext.append("HG: --")
2249 edittext.append(_("HG: user: %s") % ctx.user())
2253 edittext.append(_("HG: user: %s") % ctx.user())
2250 if ctx.p2():
2254 if ctx.p2():
2251 edittext.append(_("HG: branch merge"))
2255 edittext.append(_("HG: branch merge"))
2252 if ctx.branch():
2256 if ctx.branch():
2253 edittext.append(_("HG: branch '%s'") % ctx.branch())
2257 edittext.append(_("HG: branch '%s'") % ctx.branch())
2254 if bookmarks.iscurrent(repo):
2258 if bookmarks.iscurrent(repo):
2255 edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
2259 edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
2256 edittext.extend([_("HG: subrepo %s") % s for s in subs])
2260 edittext.extend([_("HG: subrepo %s") % s for s in subs])
2257 edittext.extend([_("HG: added %s") % f for f in added])
2261 edittext.extend([_("HG: added %s") % f for f in added])
2258 edittext.extend([_("HG: changed %s") % f for f in modified])
2262 edittext.extend([_("HG: changed %s") % f for f in modified])
2259 edittext.extend([_("HG: removed %s") % f for f in removed])
2263 edittext.extend([_("HG: removed %s") % f for f in removed])
2260 if not added and not modified and not removed:
2264 if not added and not modified and not removed:
2261 edittext.append(_("HG: no files changed"))
2265 edittext.append(_("HG: no files changed"))
2262 edittext.append("")
2266 edittext.append("")
2263
2267
2264 return "\n".join(edittext)
2268 return "\n".join(edittext)
2265
2269
2266 def commitstatus(repo, node, branch, bheads=None, opts={}):
2270 def commitstatus(repo, node, branch, bheads=None, opts={}):
2267 ctx = repo[node]
2271 ctx = repo[node]
2268 parents = ctx.parents()
2272 parents = ctx.parents()
2269
2273
2270 if (not opts.get('amend') and bheads and node not in bheads and not
2274 if (not opts.get('amend') and bheads and node not in bheads and not
2271 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2275 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2272 repo.ui.status(_('created new head\n'))
2276 repo.ui.status(_('created new head\n'))
2273 # The message is not printed for initial roots. For the other
2277 # The message is not printed for initial roots. For the other
2274 # changesets, it is printed in the following situations:
2278 # changesets, it is printed in the following situations:
2275 #
2279 #
2276 # Par column: for the 2 parents with ...
2280 # Par column: for the 2 parents with ...
2277 # N: null or no parent
2281 # N: null or no parent
2278 # B: parent is on another named branch
2282 # B: parent is on another named branch
2279 # C: parent is a regular non head changeset
2283 # C: parent is a regular non head changeset
2280 # H: parent was a branch head of the current branch
2284 # H: parent was a branch head of the current branch
2281 # Msg column: whether we print "created new head" message
2285 # Msg column: whether we print "created new head" message
2282 # In the following, it is assumed that there already exists some
2286 # In the following, it is assumed that there already exists some
2283 # initial branch heads of the current branch, otherwise nothing is
2287 # initial branch heads of the current branch, otherwise nothing is
2284 # printed anyway.
2288 # printed anyway.
2285 #
2289 #
2286 # Par Msg Comment
2290 # Par Msg Comment
2287 # N N y additional topo root
2291 # N N y additional topo root
2288 #
2292 #
2289 # B N y additional branch root
2293 # B N y additional branch root
2290 # C N y additional topo head
2294 # C N y additional topo head
2291 # H N n usual case
2295 # H N n usual case
2292 #
2296 #
2293 # B B y weird additional branch root
2297 # B B y weird additional branch root
2294 # C B y branch merge
2298 # C B y branch merge
2295 # H B n merge with named branch
2299 # H B n merge with named branch
2296 #
2300 #
2297 # C C y additional head from merge
2301 # C C y additional head from merge
2298 # C H n merge with a head
2302 # C H n merge with a head
2299 #
2303 #
2300 # H H n head merge: head count decreases
2304 # H H n head merge: head count decreases
2301
2305
2302 if not opts.get('close_branch'):
2306 if not opts.get('close_branch'):
2303 for r in parents:
2307 for r in parents:
2304 if r.closesbranch() and r.branch() == branch:
2308 if r.closesbranch() and r.branch() == branch:
2305 repo.ui.status(_('reopening closed branch head %d\n') % r)
2309 repo.ui.status(_('reopening closed branch head %d\n') % r)
2306
2310
2307 if repo.ui.debugflag:
2311 if repo.ui.debugflag:
2308 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
2312 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
2309 elif repo.ui.verbose:
2313 elif repo.ui.verbose:
2310 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
2314 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
2311
2315
2312 def revert(ui, repo, ctx, parents, *pats, **opts):
2316 def revert(ui, repo, ctx, parents, *pats, **opts):
2313 parent, p2 = parents
2317 parent, p2 = parents
2314 node = ctx.node()
2318 node = ctx.node()
2315
2319
2316 mf = ctx.manifest()
2320 mf = ctx.manifest()
2317 if node == p2:
2321 if node == p2:
2318 parent = p2
2322 parent = p2
2319 if node == parent:
2323 if node == parent:
2320 pmf = mf
2324 pmf = mf
2321 else:
2325 else:
2322 pmf = None
2326 pmf = None
2323
2327
2324 # need all matching names in dirstate and manifest of target rev,
2328 # need all matching names in dirstate and manifest of target rev,
2325 # so have to walk both. do not print errors if files exist in one
2329 # so have to walk both. do not print errors if files exist in one
2326 # but not other.
2330 # but not other.
2327
2331
2328 # `names` is a mapping for all elements in working copy and target revision
2332 # `names` is a mapping for all elements in working copy and target revision
2329 # The mapping is in the form:
2333 # The mapping is in the form:
2330 # <asb path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2334 # <asb path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2331 names = {}
2335 names = {}
2332
2336
2333 wlock = repo.wlock()
2337 wlock = repo.wlock()
2334 try:
2338 try:
2335 ## filling of the `names` mapping
2339 ## filling of the `names` mapping
2336 # walk dirstate to fill `names`
2340 # walk dirstate to fill `names`
2337
2341
2338 m = scmutil.match(repo[None], pats, opts)
2342 m = scmutil.match(repo[None], pats, opts)
2339 m.bad = lambda x, y: False
2343 m.bad = lambda x, y: False
2340 for abs in repo.walk(m):
2344 for abs in repo.walk(m):
2341 names[abs] = m.rel(abs), m.exact(abs)
2345 names[abs] = m.rel(abs), m.exact(abs)
2342
2346
2343 # walk target manifest to fill `names`
2347 # walk target manifest to fill `names`
2344
2348
2345 def badfn(path, msg):
2349 def badfn(path, msg):
2346 if path in names:
2350 if path in names:
2347 return
2351 return
2348 if path in ctx.substate:
2352 if path in ctx.substate:
2349 return
2353 return
2350 path_ = path + '/'
2354 path_ = path + '/'
2351 for f in names:
2355 for f in names:
2352 if f.startswith(path_):
2356 if f.startswith(path_):
2353 return
2357 return
2354 ui.warn("%s: %s\n" % (m.rel(path), msg))
2358 ui.warn("%s: %s\n" % (m.rel(path), msg))
2355
2359
2356 m = scmutil.match(ctx, pats, opts)
2360 m = scmutil.match(ctx, pats, opts)
2357 m.bad = badfn
2361 m.bad = badfn
2358 for abs in ctx.walk(m):
2362 for abs in ctx.walk(m):
2359 if abs not in names:
2363 if abs not in names:
2360 names[abs] = m.rel(abs), m.exact(abs)
2364 names[abs] = m.rel(abs), m.exact(abs)
2361
2365
2362 # get the list of subrepos that must be reverted
2366 # get the list of subrepos that must be reverted
2363 targetsubs = sorted(s for s in ctx.substate if m(s))
2367 targetsubs = sorted(s for s in ctx.substate if m(s))
2364
2368
2365 # Find status of all file in `names`. (Against working directory parent)
2369 # Find status of all file in `names`. (Against working directory parent)
2366 m = scmutil.matchfiles(repo, names)
2370 m = scmutil.matchfiles(repo, names)
2367 changes = repo.status(node1=parent, match=m)[:4]
2371 changes = repo.status(node1=parent, match=m)[:4]
2368 modified, added, removed, deleted = map(set, changes)
2372 modified, added, removed, deleted = map(set, changes)
2369
2373
2370 # if f is a rename, update `names` to also revert the source
2374 # if f is a rename, update `names` to also revert the source
2371 cwd = repo.getcwd()
2375 cwd = repo.getcwd()
2372 for f in added:
2376 for f in added:
2373 src = repo.dirstate.copied(f)
2377 src = repo.dirstate.copied(f)
2374 if src and src not in names and repo.dirstate[src] == 'r':
2378 if src and src not in names and repo.dirstate[src] == 'r':
2375 removed.add(src)
2379 removed.add(src)
2376 names[src] = (repo.pathto(src, cwd), True)
2380 names[src] = (repo.pathto(src, cwd), True)
2377
2381
2378 ## computation of the action to performs on `names` content.
2382 ## computation of the action to performs on `names` content.
2379
2383
2380 def removeforget(abs):
2384 def removeforget(abs):
2381 if repo.dirstate[abs] == 'a':
2385 if repo.dirstate[abs] == 'a':
2382 return _('forgetting %s\n')
2386 return _('forgetting %s\n')
2383 return _('removing %s\n')
2387 return _('removing %s\n')
2384
2388
2385 # action to be actually performed by revert
2389 # action to be actually performed by revert
2386 # (<list of file>, message>) tuple
2390 # (<list of file>, message>) tuple
2387 actions = {'revert': ([], _('reverting %s\n')),
2391 actions = {'revert': ([], _('reverting %s\n')),
2388 'add': ([], _('adding %s\n')),
2392 'add': ([], _('adding %s\n')),
2389 'remove': ([], removeforget),
2393 'remove': ([], removeforget),
2390 'undelete': ([], _('undeleting %s\n'))}
2394 'undelete': ([], _('undeleting %s\n'))}
2391
2395
2392 disptable = (
2396 disptable = (
2393 # dispatch table:
2397 # dispatch table:
2394 # file state
2398 # file state
2395 # action if in target manifest
2399 # action if in target manifest
2396 # action if not in target manifest
2400 # action if not in target manifest
2397 # make backup if in target manifest
2401 # make backup if in target manifest
2398 # make backup if not in target manifest
2402 # make backup if not in target manifest
2399 (modified, (actions['revert'], True),
2403 (modified, (actions['revert'], True),
2400 (actions['remove'], True)),
2404 (actions['remove'], True)),
2401 (added, (actions['revert'], True),
2405 (added, (actions['revert'], True),
2402 (actions['remove'], False)),
2406 (actions['remove'], False)),
2403 (removed, (actions['undelete'], True),
2407 (removed, (actions['undelete'], True),
2404 (None, False)),
2408 (None, False)),
2405 (deleted, (actions['revert'], False),
2409 (deleted, (actions['revert'], False),
2406 (actions['remove'], False)),
2410 (actions['remove'], False)),
2407 )
2411 )
2408
2412
2409 for abs, (rel, exact) in sorted(names.items()):
2413 for abs, (rel, exact) in sorted(names.items()):
2410 # hash on file in target manifest (or None if missing from target)
2414 # hash on file in target manifest (or None if missing from target)
2411 mfentry = mf.get(abs)
2415 mfentry = mf.get(abs)
2412 # target file to be touch on disk (relative to cwd)
2416 # target file to be touch on disk (relative to cwd)
2413 target = repo.wjoin(abs)
2417 target = repo.wjoin(abs)
2414 def handle(xlist, dobackup):
2418 def handle(xlist, dobackup):
2415 xlist[0].append(abs)
2419 xlist[0].append(abs)
2416 if (dobackup and not opts.get('no_backup') and
2420 if (dobackup and not opts.get('no_backup') and
2417 os.path.lexists(target) and
2421 os.path.lexists(target) and
2418 abs in ctx and repo[None][abs].cmp(ctx[abs])):
2422 abs in ctx and repo[None][abs].cmp(ctx[abs])):
2419 bakname = "%s.orig" % rel
2423 bakname = "%s.orig" % rel
2420 ui.note(_('saving current version of %s as %s\n') %
2424 ui.note(_('saving current version of %s as %s\n') %
2421 (rel, bakname))
2425 (rel, bakname))
2422 if not opts.get('dry_run'):
2426 if not opts.get('dry_run'):
2423 util.rename(target, bakname)
2427 util.rename(target, bakname)
2424 if ui.verbose or not exact:
2428 if ui.verbose or not exact:
2425 msg = xlist[1]
2429 msg = xlist[1]
2426 if not isinstance(msg, basestring):
2430 if not isinstance(msg, basestring):
2427 msg = msg(abs)
2431 msg = msg(abs)
2428 ui.status(msg % rel)
2432 ui.status(msg % rel)
2429 # search the entry in the dispatch table.
2433 # search the entry in the dispatch table.
2430 # if the file is in any of this sets, it was touched in the working
2434 # if the file is in any of this sets, it was touched in the working
2431 # directory parent and we are sure it needs to be reverted.
2435 # directory parent and we are sure it needs to be reverted.
2432 for table, hit, miss in disptable:
2436 for table, hit, miss in disptable:
2433 if abs not in table:
2437 if abs not in table:
2434 continue
2438 continue
2435 # file has changed in dirstate
2439 # file has changed in dirstate
2436 if mfentry:
2440 if mfentry:
2437 handle(*hit)
2441 handle(*hit)
2438 elif miss[0] is not None:
2442 elif miss[0] is not None:
2439 handle(*miss)
2443 handle(*miss)
2440 break
2444 break
2441 else:
2445 else:
2442 # Not touched in current dirstate.
2446 # Not touched in current dirstate.
2443
2447
2444 # file is unknown in parent, restore older version or ignore.
2448 # file is unknown in parent, restore older version or ignore.
2445 if abs not in repo.dirstate:
2449 if abs not in repo.dirstate:
2446 if mfentry:
2450 if mfentry:
2447 handle(actions['add'], True)
2451 handle(actions['add'], True)
2448 elif exact:
2452 elif exact:
2449 ui.warn(_('file not managed: %s\n') % rel)
2453 ui.warn(_('file not managed: %s\n') % rel)
2450 continue
2454 continue
2451
2455
2452 # parent is target, no changes mean no changes
2456 # parent is target, no changes mean no changes
2453 if node == parent:
2457 if node == parent:
2454 if exact:
2458 if exact:
2455 ui.warn(_('no changes needed to %s\n') % rel)
2459 ui.warn(_('no changes needed to %s\n') % rel)
2456 continue
2460 continue
2457 # no change in dirstate but parent and target may differ
2461 # no change in dirstate but parent and target may differ
2458 if pmf is None:
2462 if pmf is None:
2459 # only need parent manifest in this unlikely case,
2463 # only need parent manifest in this unlikely case,
2460 # so do not read by default
2464 # so do not read by default
2461 pmf = repo[parent].manifest()
2465 pmf = repo[parent].manifest()
2462 if abs in pmf and mfentry:
2466 if abs in pmf and mfentry:
2463 # if version of file is same in parent and target
2467 # if version of file is same in parent and target
2464 # manifests, do nothing
2468 # manifests, do nothing
2465 if (pmf[abs] != mfentry or
2469 if (pmf[abs] != mfentry or
2466 pmf.flags(abs) != mf.flags(abs)):
2470 pmf.flags(abs) != mf.flags(abs)):
2467 handle(actions['revert'], False)
2471 handle(actions['revert'], False)
2468 else:
2472 else:
2469 handle(actions['remove'], False)
2473 handle(actions['remove'], False)
2470
2474
2471 if not opts.get('dry_run'):
2475 if not opts.get('dry_run'):
2472 _performrevert(repo, parents, ctx, actions)
2476 _performrevert(repo, parents, ctx, actions)
2473
2477
2474 if targetsubs:
2478 if targetsubs:
2475 # Revert the subrepos on the revert list
2479 # Revert the subrepos on the revert list
2476 for sub in targetsubs:
2480 for sub in targetsubs:
2477 ctx.sub(sub).revert(ui, ctx.substate[sub], *pats, **opts)
2481 ctx.sub(sub).revert(ui, ctx.substate[sub], *pats, **opts)
2478 finally:
2482 finally:
2479 wlock.release()
2483 wlock.release()
2480
2484
2481 def _performrevert(repo, parents, ctx, actions):
2485 def _performrevert(repo, parents, ctx, actions):
2482 """function that actually perform all the actions computed for revert
2486 """function that actually perform all the actions computed for revert
2483
2487
2484 This is an independent function to let extension to plug in and react to
2488 This is an independent function to let extension to plug in and react to
2485 the imminent revert.
2489 the imminent revert.
2486
2490
2487 Make sure you have the working directory locked when calling this function.
2491 Make sure you have the working directory locked when calling this function.
2488 """
2492 """
2489 parent, p2 = parents
2493 parent, p2 = parents
2490 node = ctx.node()
2494 node = ctx.node()
2491 def checkout(f):
2495 def checkout(f):
2492 fc = ctx[f]
2496 fc = ctx[f]
2493 repo.wwrite(f, fc.data(), fc.flags())
2497 repo.wwrite(f, fc.data(), fc.flags())
2494
2498
2495 audit_path = pathutil.pathauditor(repo.root)
2499 audit_path = pathutil.pathauditor(repo.root)
2496 for f in actions['remove'][0]:
2500 for f in actions['remove'][0]:
2497 if repo.dirstate[f] == 'a':
2501 if repo.dirstate[f] == 'a':
2498 repo.dirstate.drop(f)
2502 repo.dirstate.drop(f)
2499 continue
2503 continue
2500 audit_path(f)
2504 audit_path(f)
2501 try:
2505 try:
2502 util.unlinkpath(repo.wjoin(f))
2506 util.unlinkpath(repo.wjoin(f))
2503 except OSError:
2507 except OSError:
2504 pass
2508 pass
2505 repo.dirstate.remove(f)
2509 repo.dirstate.remove(f)
2506
2510
2507 normal = None
2511 normal = None
2508 if node == parent:
2512 if node == parent:
2509 # We're reverting to our parent. If possible, we'd like status
2513 # We're reverting to our parent. If possible, we'd like status
2510 # to report the file as clean. We have to use normallookup for
2514 # to report the file as clean. We have to use normallookup for
2511 # merges to avoid losing information about merged/dirty files.
2515 # merges to avoid losing information about merged/dirty files.
2512 if p2 != nullid:
2516 if p2 != nullid:
2513 normal = repo.dirstate.normallookup
2517 normal = repo.dirstate.normallookup
2514 else:
2518 else:
2515 normal = repo.dirstate.normal
2519 normal = repo.dirstate.normal
2516 for f in actions['revert'][0]:
2520 for f in actions['revert'][0]:
2517 checkout(f)
2521 checkout(f)
2518 if normal:
2522 if normal:
2519 normal(f)
2523 normal(f)
2520
2524
2521 for f in actions['add'][0]:
2525 for f in actions['add'][0]:
2522 checkout(f)
2526 checkout(f)
2523 repo.dirstate.add(f)
2527 repo.dirstate.add(f)
2524
2528
2525 normal = repo.dirstate.normallookup
2529 normal = repo.dirstate.normallookup
2526 if node == parent and p2 == nullid:
2530 if node == parent and p2 == nullid:
2527 normal = repo.dirstate.normal
2531 normal = repo.dirstate.normal
2528 for f in actions['undelete'][0]:
2532 for f in actions['undelete'][0]:
2529 checkout(f)
2533 checkout(f)
2530 normal(f)
2534 normal(f)
2531
2535
2532 copied = copies.pathcopies(repo[parent], ctx)
2536 copied = copies.pathcopies(repo[parent], ctx)
2533
2537
2534 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
2538 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
2535 if f in copied:
2539 if f in copied:
2536 repo.dirstate.copy(copied[f], f)
2540 repo.dirstate.copy(copied[f], f)
2537
2541
2538 def command(table):
2542 def command(table):
2539 """Returns a function object to be used as a decorator for making commands.
2543 """Returns a function object to be used as a decorator for making commands.
2540
2544
2541 This function receives a command table as its argument. The table should
2545 This function receives a command table as its argument. The table should
2542 be a dict.
2546 be a dict.
2543
2547
2544 The returned function can be used as a decorator for adding commands
2548 The returned function can be used as a decorator for adding commands
2545 to that command table. This function accepts multiple arguments to define
2549 to that command table. This function accepts multiple arguments to define
2546 a command.
2550 a command.
2547
2551
2548 The first argument is the command name.
2552 The first argument is the command name.
2549
2553
2550 The options argument is an iterable of tuples defining command arguments.
2554 The options argument is an iterable of tuples defining command arguments.
2551 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
2555 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
2552
2556
2553 The synopsis argument defines a short, one line summary of how to use the
2557 The synopsis argument defines a short, one line summary of how to use the
2554 command. This shows up in the help output.
2558 command. This shows up in the help output.
2555
2559
2556 The norepo argument defines whether the command does not require a
2560 The norepo argument defines whether the command does not require a
2557 local repository. Most commands operate against a repository, thus the
2561 local repository. Most commands operate against a repository, thus the
2558 default is False.
2562 default is False.
2559
2563
2560 The optionalrepo argument defines whether the command optionally requires
2564 The optionalrepo argument defines whether the command optionally requires
2561 a local repository.
2565 a local repository.
2562
2566
2563 The inferrepo argument defines whether to try to find a repository from the
2567 The inferrepo argument defines whether to try to find a repository from the
2564 command line arguments. If True, arguments will be examined for potential
2568 command line arguments. If True, arguments will be examined for potential
2565 repository locations. See ``findrepo()``. If a repository is found, it
2569 repository locations. See ``findrepo()``. If a repository is found, it
2566 will be used.
2570 will be used.
2567 """
2571 """
2568 def cmd(name, options=(), synopsis=None, norepo=False, optionalrepo=False,
2572 def cmd(name, options=(), synopsis=None, norepo=False, optionalrepo=False,
2569 inferrepo=False):
2573 inferrepo=False):
2570 def decorator(func):
2574 def decorator(func):
2571 if synopsis:
2575 if synopsis:
2572 table[name] = func, list(options), synopsis
2576 table[name] = func, list(options), synopsis
2573 else:
2577 else:
2574 table[name] = func, list(options)
2578 table[name] = func, list(options)
2575
2579
2576 if norepo:
2580 if norepo:
2577 # Avoid import cycle.
2581 # Avoid import cycle.
2578 import commands
2582 import commands
2579 commands.norepo += ' %s' % ' '.join(parsealiases(name))
2583 commands.norepo += ' %s' % ' '.join(parsealiases(name))
2580
2584
2581 if optionalrepo:
2585 if optionalrepo:
2582 import commands
2586 import commands
2583 commands.optionalrepo += ' %s' % ' '.join(parsealiases(name))
2587 commands.optionalrepo += ' %s' % ' '.join(parsealiases(name))
2584
2588
2585 if inferrepo:
2589 if inferrepo:
2586 import commands
2590 import commands
2587 commands.inferrepo += ' %s' % ' '.join(parsealiases(name))
2591 commands.inferrepo += ' %s' % ' '.join(parsealiases(name))
2588
2592
2589 return func
2593 return func
2590 return decorator
2594 return decorator
2591
2595
2592 return cmd
2596 return cmd
2593
2597
2594 # a list of (ui, repo, otherpeer, opts, missing) functions called by
2598 # a list of (ui, repo, otherpeer, opts, missing) functions called by
2595 # commands.outgoing. "missing" is "missing" of the result of
2599 # commands.outgoing. "missing" is "missing" of the result of
2596 # "findcommonoutgoing()"
2600 # "findcommonoutgoing()"
2597 outgoinghooks = util.hooks()
2601 outgoinghooks = util.hooks()
2598
2602
2599 # a list of (ui, repo) functions called by commands.summary
2603 # a list of (ui, repo) functions called by commands.summary
2600 summaryhooks = util.hooks()
2604 summaryhooks = util.hooks()
2601
2605
2602 # a list of (ui, repo, opts, changes) functions called by commands.summary.
2606 # a list of (ui, repo, opts, changes) functions called by commands.summary.
2603 #
2607 #
2604 # functions should return tuple of booleans below, if 'changes' is None:
2608 # functions should return tuple of booleans below, if 'changes' is None:
2605 # (whether-incomings-are-needed, whether-outgoings-are-needed)
2609 # (whether-incomings-are-needed, whether-outgoings-are-needed)
2606 #
2610 #
2607 # otherwise, 'changes' is a tuple of tuples below:
2611 # otherwise, 'changes' is a tuple of tuples below:
2608 # - (sourceurl, sourcebranch, sourcepeer, incoming)
2612 # - (sourceurl, sourcebranch, sourcepeer, incoming)
2609 # - (desturl, destbranch, destpeer, outgoing)
2613 # - (desturl, destbranch, destpeer, outgoing)
2610 summaryremotehooks = util.hooks()
2614 summaryremotehooks = util.hooks()
2611
2615
2612 # A list of state files kept by multistep operations like graft.
2616 # A list of state files kept by multistep operations like graft.
2613 # Since graft cannot be aborted, it is considered 'clearable' by update.
2617 # Since graft cannot be aborted, it is considered 'clearable' by update.
2614 # note: bisect is intentionally excluded
2618 # note: bisect is intentionally excluded
2615 # (state file, clearable, allowcommit, error, hint)
2619 # (state file, clearable, allowcommit, error, hint)
2616 unfinishedstates = [
2620 unfinishedstates = [
2617 ('graftstate', True, False, _('graft in progress'),
2621 ('graftstate', True, False, _('graft in progress'),
2618 _("use 'hg graft --continue' or 'hg update' to abort")),
2622 _("use 'hg graft --continue' or 'hg update' to abort")),
2619 ('updatestate', True, False, _('last update was interrupted'),
2623 ('updatestate', True, False, _('last update was interrupted'),
2620 _("use 'hg update' to get a consistent checkout"))
2624 _("use 'hg update' to get a consistent checkout"))
2621 ]
2625 ]
2622
2626
2623 def checkunfinished(repo, commit=False):
2627 def checkunfinished(repo, commit=False):
2624 '''Look for an unfinished multistep operation, like graft, and abort
2628 '''Look for an unfinished multistep operation, like graft, and abort
2625 if found. It's probably good to check this right before
2629 if found. It's probably good to check this right before
2626 bailifchanged().
2630 bailifchanged().
2627 '''
2631 '''
2628 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2632 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2629 if commit and allowcommit:
2633 if commit and allowcommit:
2630 continue
2634 continue
2631 if repo.vfs.exists(f):
2635 if repo.vfs.exists(f):
2632 raise util.Abort(msg, hint=hint)
2636 raise util.Abort(msg, hint=hint)
2633
2637
2634 def clearunfinished(repo):
2638 def clearunfinished(repo):
2635 '''Check for unfinished operations (as above), and clear the ones
2639 '''Check for unfinished operations (as above), and clear the ones
2636 that are clearable.
2640 that are clearable.
2637 '''
2641 '''
2638 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2642 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2639 if not clearable and repo.vfs.exists(f):
2643 if not clearable and repo.vfs.exists(f):
2640 raise util.Abort(msg, hint=hint)
2644 raise util.Abort(msg, hint=hint)
2641 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2645 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2642 if clearable and repo.vfs.exists(f):
2646 if clearable and repo.vfs.exists(f):
2643 util.unlink(repo.join(f))
2647 util.unlink(repo.join(f))
@@ -1,1668 +1,1679 b''
1 The Mercurial system uses a set of configuration files to control
1 The Mercurial system uses a set of configuration files to control
2 aspects of its behavior.
2 aspects of its behavior.
3
3
4 The configuration files use a simple ini-file format. A configuration
4 The configuration files use a simple ini-file format. A configuration
5 file consists of sections, led by a ``[section]`` header and followed
5 file consists of sections, led by a ``[section]`` header and followed
6 by ``name = value`` entries::
6 by ``name = value`` entries::
7
7
8 [ui]
8 [ui]
9 username = Firstname Lastname <firstname.lastname@example.net>
9 username = Firstname Lastname <firstname.lastname@example.net>
10 verbose = True
10 verbose = True
11
11
12 The above entries will be referred to as ``ui.username`` and
12 The above entries will be referred to as ``ui.username`` and
13 ``ui.verbose``, respectively. See the Syntax section below.
13 ``ui.verbose``, respectively. See the Syntax section below.
14
14
15 Files
15 Files
16 =====
16 =====
17
17
18 Mercurial reads configuration data from several files, if they exist.
18 Mercurial reads configuration data from several files, if they exist.
19 These files do not exist by default and you will have to create the
19 These files do not exist by default and you will have to create the
20 appropriate configuration files yourself: global configuration like
20 appropriate configuration files yourself: global configuration like
21 the username setting is typically put into
21 the username setting is typically put into
22 ``%USERPROFILE%\mercurial.ini`` or ``$HOME/.hgrc`` and local
22 ``%USERPROFILE%\mercurial.ini`` or ``$HOME/.hgrc`` and local
23 configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
23 configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
24
24
25 The names of these files depend on the system on which Mercurial is
25 The names of these files depend on the system on which Mercurial is
26 installed. ``*.rc`` files from a single directory are read in
26 installed. ``*.rc`` files from a single directory are read in
27 alphabetical order, later ones overriding earlier ones. Where multiple
27 alphabetical order, later ones overriding earlier ones. Where multiple
28 paths are given below, settings from earlier paths override later
28 paths are given below, settings from earlier paths override later
29 ones.
29 ones.
30
30
31 | (All) ``<repo>/.hg/hgrc``
31 | (All) ``<repo>/.hg/hgrc``
32
32
33 Per-repository configuration options that only apply in a
33 Per-repository configuration options that only apply in a
34 particular repository. This file is not version-controlled, and
34 particular repository. This file is not version-controlled, and
35 will not get transferred during a "clone" operation. Options in
35 will not get transferred during a "clone" operation. Options in
36 this file override options in all other configuration files. On
36 this file override options in all other configuration files. On
37 Plan 9 and Unix, most of this file will be ignored if it doesn't
37 Plan 9 and Unix, most of this file will be ignored if it doesn't
38 belong to a trusted user or to a trusted group. See the documentation
38 belong to a trusted user or to a trusted group. See the documentation
39 for the ``[trusted]`` section below for more details.
39 for the ``[trusted]`` section below for more details.
40
40
41 | (Plan 9) ``$home/lib/hgrc``
41 | (Plan 9) ``$home/lib/hgrc``
42 | (Unix) ``$HOME/.hgrc``
42 | (Unix) ``$HOME/.hgrc``
43 | (Windows) ``%USERPROFILE%\.hgrc``
43 | (Windows) ``%USERPROFILE%\.hgrc``
44 | (Windows) ``%USERPROFILE%\Mercurial.ini``
44 | (Windows) ``%USERPROFILE%\Mercurial.ini``
45 | (Windows) ``%HOME%\.hgrc``
45 | (Windows) ``%HOME%\.hgrc``
46 | (Windows) ``%HOME%\Mercurial.ini``
46 | (Windows) ``%HOME%\Mercurial.ini``
47
47
48 Per-user configuration file(s), for the user running Mercurial. On
48 Per-user configuration file(s), for the user running Mercurial. On
49 Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
49 Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
50 files apply to all Mercurial commands executed by this user in any
50 files apply to all Mercurial commands executed by this user in any
51 directory. Options in these files override per-system and per-installation
51 directory. Options in these files override per-system and per-installation
52 options.
52 options.
53
53
54 | (Plan 9) ``/lib/mercurial/hgrc``
54 | (Plan 9) ``/lib/mercurial/hgrc``
55 | (Plan 9) ``/lib/mercurial/hgrc.d/*.rc``
55 | (Plan 9) ``/lib/mercurial/hgrc.d/*.rc``
56 | (Unix) ``/etc/mercurial/hgrc``
56 | (Unix) ``/etc/mercurial/hgrc``
57 | (Unix) ``/etc/mercurial/hgrc.d/*.rc``
57 | (Unix) ``/etc/mercurial/hgrc.d/*.rc``
58
58
59 Per-system configuration files, for the system on which Mercurial
59 Per-system configuration files, for the system on which Mercurial
60 is running. Options in these files apply to all Mercurial commands
60 is running. Options in these files apply to all Mercurial commands
61 executed by any user in any directory. Options in these files
61 executed by any user in any directory. Options in these files
62 override per-installation options.
62 override per-installation options.
63
63
64 | (Plan 9) ``<install-root>/lib/mercurial/hgrc``
64 | (Plan 9) ``<install-root>/lib/mercurial/hgrc``
65 | (Plan 9) ``<install-root>/lib/mercurial/hgrc.d/*.rc``
65 | (Plan 9) ``<install-root>/lib/mercurial/hgrc.d/*.rc``
66 | (Unix) ``<install-root>/etc/mercurial/hgrc``
66 | (Unix) ``<install-root>/etc/mercurial/hgrc``
67 | (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
67 | (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
68
68
69 Per-installation configuration files, searched for in the
69 Per-installation configuration files, searched for in the
70 directory where Mercurial is installed. ``<install-root>`` is the
70 directory where Mercurial is installed. ``<install-root>`` is the
71 parent directory of the **hg** executable (or symlink) being run. For
71 parent directory of the **hg** executable (or symlink) being run. For
72 example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
72 example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
73 in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
73 in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
74 to all Mercurial commands executed by any user in any directory.
74 to all Mercurial commands executed by any user in any directory.
75
75
76 | (Windows) ``<install-dir>\Mercurial.ini`` **or**
76 | (Windows) ``<install-dir>\Mercurial.ini`` **or**
77 | (Windows) ``<install-dir>\hgrc.d\*.rc`` **or**
77 | (Windows) ``<install-dir>\hgrc.d\*.rc`` **or**
78 | (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial``
78 | (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial``
79
79
80 Per-installation/system configuration files, for the system on
80 Per-installation/system configuration files, for the system on
81 which Mercurial is running. Options in these files apply to all
81 which Mercurial is running. Options in these files apply to all
82 Mercurial commands executed by any user in any directory. Registry
82 Mercurial commands executed by any user in any directory. Registry
83 keys contain PATH-like strings, every part of which must reference
83 keys contain PATH-like strings, every part of which must reference
84 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
84 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
85 be read. Mercurial checks each of these locations in the specified
85 be read. Mercurial checks each of these locations in the specified
86 order until one or more configuration files are detected.
86 order until one or more configuration files are detected.
87
87
88 .. note::
88 .. note::
89
89
90 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
90 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
91 is used when running 32-bit Python on 64-bit Windows.
91 is used when running 32-bit Python on 64-bit Windows.
92
92
93 Syntax
93 Syntax
94 ======
94 ======
95
95
96 A configuration file consists of sections, led by a ``[section]`` header
96 A configuration file consists of sections, led by a ``[section]`` header
97 and followed by ``name = value`` entries (sometimes called
97 and followed by ``name = value`` entries (sometimes called
98 ``configuration keys``)::
98 ``configuration keys``)::
99
99
100 [spam]
100 [spam]
101 eggs=ham
101 eggs=ham
102 green=
102 green=
103 eggs
103 eggs
104
104
105 Each line contains one entry. If the lines that follow are indented,
105 Each line contains one entry. If the lines that follow are indented,
106 they are treated as continuations of that entry. Leading whitespace is
106 they are treated as continuations of that entry. Leading whitespace is
107 removed from values. Empty lines are skipped. Lines beginning with
107 removed from values. Empty lines are skipped. Lines beginning with
108 ``#`` or ``;`` are ignored and may be used to provide comments.
108 ``#`` or ``;`` are ignored and may be used to provide comments.
109
109
110 Configuration keys can be set multiple times, in which case Mercurial
110 Configuration keys can be set multiple times, in which case Mercurial
111 will use the value that was configured last. As an example::
111 will use the value that was configured last. As an example::
112
112
113 [spam]
113 [spam]
114 eggs=large
114 eggs=large
115 ham=serrano
115 ham=serrano
116 eggs=small
116 eggs=small
117
117
118 This would set the configuration key named ``eggs`` to ``small``.
118 This would set the configuration key named ``eggs`` to ``small``.
119
119
120 It is also possible to define a section multiple times. A section can
120 It is also possible to define a section multiple times. A section can
121 be redefined on the same and/or on different configuration files. For
121 be redefined on the same and/or on different configuration files. For
122 example::
122 example::
123
123
124 [foo]
124 [foo]
125 eggs=large
125 eggs=large
126 ham=serrano
126 ham=serrano
127 eggs=small
127 eggs=small
128
128
129 [bar]
129 [bar]
130 eggs=ham
130 eggs=ham
131 green=
131 green=
132 eggs
132 eggs
133
133
134 [foo]
134 [foo]
135 ham=prosciutto
135 ham=prosciutto
136 eggs=medium
136 eggs=medium
137 bread=toasted
137 bread=toasted
138
138
139 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
139 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
140 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
140 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
141 respectively. As you can see there only thing that matters is the last
141 respectively. As you can see there only thing that matters is the last
142 value that was set for each of the configuration keys.
142 value that was set for each of the configuration keys.
143
143
144 If a configuration key is set multiple times in different
144 If a configuration key is set multiple times in different
145 configuration files the final value will depend on the order in which
145 configuration files the final value will depend on the order in which
146 the different configuration files are read, with settings from earlier
146 the different configuration files are read, with settings from earlier
147 paths overriding later ones as described on the ``Files`` section
147 paths overriding later ones as described on the ``Files`` section
148 above.
148 above.
149
149
150 A line of the form ``%include file`` will include ``file`` into the
150 A line of the form ``%include file`` will include ``file`` into the
151 current configuration file. The inclusion is recursive, which means
151 current configuration file. The inclusion is recursive, which means
152 that included files can include other files. Filenames are relative to
152 that included files can include other files. Filenames are relative to
153 the configuration file in which the ``%include`` directive is found.
153 the configuration file in which the ``%include`` directive is found.
154 Environment variables and ``~user`` constructs are expanded in
154 Environment variables and ``~user`` constructs are expanded in
155 ``file``. This lets you do something like::
155 ``file``. This lets you do something like::
156
156
157 %include ~/.hgrc.d/$HOST.rc
157 %include ~/.hgrc.d/$HOST.rc
158
158
159 to include a different configuration file on each computer you use.
159 to include a different configuration file on each computer you use.
160
160
161 A line with ``%unset name`` will remove ``name`` from the current
161 A line with ``%unset name`` will remove ``name`` from the current
162 section, if it has been set previously.
162 section, if it has been set previously.
163
163
164 The values are either free-form text strings, lists of text strings,
164 The values are either free-form text strings, lists of text strings,
165 or Boolean values. Boolean values can be set to true using any of "1",
165 or Boolean values. Boolean values can be set to true using any of "1",
166 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
166 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
167 (all case insensitive).
167 (all case insensitive).
168
168
169 List values are separated by whitespace or comma, except when values are
169 List values are separated by whitespace or comma, except when values are
170 placed in double quotation marks::
170 placed in double quotation marks::
171
171
172 allow_read = "John Doe, PhD", brian, betty
172 allow_read = "John Doe, PhD", brian, betty
173
173
174 Quotation marks can be escaped by prefixing them with a backslash. Only
174 Quotation marks can be escaped by prefixing them with a backslash. Only
175 quotation marks at the beginning of a word is counted as a quotation
175 quotation marks at the beginning of a word is counted as a quotation
176 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
176 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
177
177
178 Sections
178 Sections
179 ========
179 ========
180
180
181 This section describes the different sections that may appear in a
181 This section describes the different sections that may appear in a
182 Mercurial configuration file, the purpose of each section, its possible
182 Mercurial configuration file, the purpose of each section, its possible
183 keys, and their possible values.
183 keys, and their possible values.
184
184
185 ``alias``
185 ``alias``
186 ---------
186 ---------
187
187
188 Defines command aliases.
188 Defines command aliases.
189 Aliases allow you to define your own commands in terms of other
189 Aliases allow you to define your own commands in terms of other
190 commands (or aliases), optionally including arguments. Positional
190 commands (or aliases), optionally including arguments. Positional
191 arguments in the form of ``$1``, ``$2``, etc in the alias definition
191 arguments in the form of ``$1``, ``$2``, etc in the alias definition
192 are expanded by Mercurial before execution. Positional arguments not
192 are expanded by Mercurial before execution. Positional arguments not
193 already used by ``$N`` in the definition are put at the end of the
193 already used by ``$N`` in the definition are put at the end of the
194 command to be executed.
194 command to be executed.
195
195
196 Alias definitions consist of lines of the form::
196 Alias definitions consist of lines of the form::
197
197
198 <alias> = <command> [<argument>]...
198 <alias> = <command> [<argument>]...
199
199
200 For example, this definition::
200 For example, this definition::
201
201
202 latest = log --limit 5
202 latest = log --limit 5
203
203
204 creates a new command ``latest`` that shows only the five most recent
204 creates a new command ``latest`` that shows only the five most recent
205 changesets. You can define subsequent aliases using earlier ones::
205 changesets. You can define subsequent aliases using earlier ones::
206
206
207 stable5 = latest -b stable
207 stable5 = latest -b stable
208
208
209 .. note::
209 .. note::
210
210
211 It is possible to create aliases with the same names as
211 It is possible to create aliases with the same names as
212 existing commands, which will then override the original
212 existing commands, which will then override the original
213 definitions. This is almost always a bad idea!
213 definitions. This is almost always a bad idea!
214
214
215 An alias can start with an exclamation point (``!``) to make it a
215 An alias can start with an exclamation point (``!``) to make it a
216 shell alias. A shell alias is executed with the shell and will let you
216 shell alias. A shell alias is executed with the shell and will let you
217 run arbitrary commands. As an example, ::
217 run arbitrary commands. As an example, ::
218
218
219 echo = !echo $@
219 echo = !echo $@
220
220
221 will let you do ``hg echo foo`` to have ``foo`` printed in your
221 will let you do ``hg echo foo`` to have ``foo`` printed in your
222 terminal. A better example might be::
222 terminal. A better example might be::
223
223
224 purge = !$HG status --no-status --unknown -0 | xargs -0 rm
224 purge = !$HG status --no-status --unknown -0 | xargs -0 rm
225
225
226 which will make ``hg purge`` delete all unknown files in the
226 which will make ``hg purge`` delete all unknown files in the
227 repository in the same manner as the purge extension.
227 repository in the same manner as the purge extension.
228
228
229 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
229 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
230 expand to the command arguments. Unmatched arguments are
230 expand to the command arguments. Unmatched arguments are
231 removed. ``$0`` expands to the alias name and ``$@`` expands to all
231 removed. ``$0`` expands to the alias name and ``$@`` expands to all
232 arguments separated by a space. These expansions happen before the
232 arguments separated by a space. These expansions happen before the
233 command is passed to the shell.
233 command is passed to the shell.
234
234
235 Shell aliases are executed in an environment where ``$HG`` expands to
235 Shell aliases are executed in an environment where ``$HG`` expands to
236 the path of the Mercurial that was used to execute the alias. This is
236 the path of the Mercurial that was used to execute the alias. This is
237 useful when you want to call further Mercurial commands in a shell
237 useful when you want to call further Mercurial commands in a shell
238 alias, as was done above for the purge alias. In addition,
238 alias, as was done above for the purge alias. In addition,
239 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
239 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
240 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
240 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
241
241
242 .. note::
242 .. note::
243
243
244 Some global configuration options such as ``-R`` are
244 Some global configuration options such as ``-R`` are
245 processed before shell aliases and will thus not be passed to
245 processed before shell aliases and will thus not be passed to
246 aliases.
246 aliases.
247
247
248
248
249 ``annotate``
249 ``annotate``
250 ------------
250 ------------
251
251
252 Settings used when displaying file annotations. All values are
252 Settings used when displaying file annotations. All values are
253 Booleans and default to False. See ``diff`` section for related
253 Booleans and default to False. See ``diff`` section for related
254 options for the diff command.
254 options for the diff command.
255
255
256 ``ignorews``
256 ``ignorews``
257 Ignore white space when comparing lines.
257 Ignore white space when comparing lines.
258
258
259 ``ignorewsamount``
259 ``ignorewsamount``
260 Ignore changes in the amount of white space.
260 Ignore changes in the amount of white space.
261
261
262 ``ignoreblanklines``
262 ``ignoreblanklines``
263 Ignore changes whose lines are all blank.
263 Ignore changes whose lines are all blank.
264
264
265
265
266 ``auth``
266 ``auth``
267 --------
267 --------
268
268
269 Authentication credentials for HTTP authentication. This section
269 Authentication credentials for HTTP authentication. This section
270 allows you to store usernames and passwords for use when logging
270 allows you to store usernames and passwords for use when logging
271 *into* HTTP servers. See the ``[web]`` configuration section if
271 *into* HTTP servers. See the ``[web]`` configuration section if
272 you want to configure *who* can login to your HTTP server.
272 you want to configure *who* can login to your HTTP server.
273
273
274 Each line has the following format::
274 Each line has the following format::
275
275
276 <name>.<argument> = <value>
276 <name>.<argument> = <value>
277
277
278 where ``<name>`` is used to group arguments into authentication
278 where ``<name>`` is used to group arguments into authentication
279 entries. Example::
279 entries. Example::
280
280
281 foo.prefix = hg.intevation.org/mercurial
281 foo.prefix = hg.intevation.org/mercurial
282 foo.username = foo
282 foo.username = foo
283 foo.password = bar
283 foo.password = bar
284 foo.schemes = http https
284 foo.schemes = http https
285
285
286 bar.prefix = secure.example.org
286 bar.prefix = secure.example.org
287 bar.key = path/to/file.key
287 bar.key = path/to/file.key
288 bar.cert = path/to/file.cert
288 bar.cert = path/to/file.cert
289 bar.schemes = https
289 bar.schemes = https
290
290
291 Supported arguments:
291 Supported arguments:
292
292
293 ``prefix``
293 ``prefix``
294 Either ``*`` or a URI prefix with or without the scheme part.
294 Either ``*`` or a URI prefix with or without the scheme part.
295 The authentication entry with the longest matching prefix is used
295 The authentication entry with the longest matching prefix is used
296 (where ``*`` matches everything and counts as a match of length
296 (where ``*`` matches everything and counts as a match of length
297 1). If the prefix doesn't include a scheme, the match is performed
297 1). If the prefix doesn't include a scheme, the match is performed
298 against the URI with its scheme stripped as well, and the schemes
298 against the URI with its scheme stripped as well, and the schemes
299 argument, q.v., is then subsequently consulted.
299 argument, q.v., is then subsequently consulted.
300
300
301 ``username``
301 ``username``
302 Optional. Username to authenticate with. If not given, and the
302 Optional. Username to authenticate with. If not given, and the
303 remote site requires basic or digest authentication, the user will
303 remote site requires basic or digest authentication, the user will
304 be prompted for it. Environment variables are expanded in the
304 be prompted for it. Environment variables are expanded in the
305 username letting you do ``foo.username = $USER``. If the URI
305 username letting you do ``foo.username = $USER``. If the URI
306 includes a username, only ``[auth]`` entries with a matching
306 includes a username, only ``[auth]`` entries with a matching
307 username or without a username will be considered.
307 username or without a username will be considered.
308
308
309 ``password``
309 ``password``
310 Optional. Password to authenticate with. If not given, and the
310 Optional. Password to authenticate with. If not given, and the
311 remote site requires basic or digest authentication, the user
311 remote site requires basic or digest authentication, the user
312 will be prompted for it.
312 will be prompted for it.
313
313
314 ``key``
314 ``key``
315 Optional. PEM encoded client certificate key file. Environment
315 Optional. PEM encoded client certificate key file. Environment
316 variables are expanded in the filename.
316 variables are expanded in the filename.
317
317
318 ``cert``
318 ``cert``
319 Optional. PEM encoded client certificate chain file. Environment
319 Optional. PEM encoded client certificate chain file. Environment
320 variables are expanded in the filename.
320 variables are expanded in the filename.
321
321
322 ``schemes``
322 ``schemes``
323 Optional. Space separated list of URI schemes to use this
323 Optional. Space separated list of URI schemes to use this
324 authentication entry with. Only used if the prefix doesn't include
324 authentication entry with. Only used if the prefix doesn't include
325 a scheme. Supported schemes are http and https. They will match
325 a scheme. Supported schemes are http and https. They will match
326 static-http and static-https respectively, as well.
326 static-http and static-https respectively, as well.
327 Default: https.
327 Default: https.
328
328
329 If no suitable authentication entry is found, the user is prompted
329 If no suitable authentication entry is found, the user is prompted
330 for credentials as usual if required by the remote.
330 for credentials as usual if required by the remote.
331
331
332
332
333 ``committemplate``
333 ``committemplate``
334 ------------------
334 ------------------
335
335
336 ``changeset`` configuration in this section is used as the template to
336 ``changeset`` configuration in this section is used as the template to
337 customize the text shown in the editor when committing.
337 customize the text shown in the editor when committing.
338
338
339 In addition to pre-defined template keywords, commit log specific one
339 In addition to pre-defined template keywords, commit log specific one
340 below can be used for customization:
340 below can be used for customization:
341
341
342 ``extramsg``
342 ``extramsg``
343 String: Extra message (typically 'Leave message empty to abort
343 String: Extra message (typically 'Leave message empty to abort
344 commit.'). This may be changed by some commands or extensions.
344 commit.'). This may be changed by some commands or extensions.
345
345
346 For example, the template configuration below shows as same text as
346 For example, the template configuration below shows as same text as
347 one shown by default::
347 one shown by default::
348
348
349 [committemplate]
349 [committemplate]
350 changeset = {desc}\n\n
350 changeset = {desc}\n\n
351 HG: Enter commit message. Lines beginning with 'HG:' are removed.
351 HG: Enter commit message. Lines beginning with 'HG:' are removed.
352 HG: {extramsg}
352 HG: {extramsg}
353 HG: --
353 HG: --
354 HG: user: {author}\n{ifeq(p2rev, "-1", "",
354 HG: user: {author}\n{ifeq(p2rev, "-1", "",
355 "HG: branch merge\n")
355 "HG: branch merge\n")
356 }HG: branch '{branch}'\n{if(currentbookmark,
356 }HG: branch '{branch}'\n{if(currentbookmark,
357 "HG: bookmark '{currentbookmark}'\n") }{subrepos %
357 "HG: bookmark '{currentbookmark}'\n") }{subrepos %
358 "HG: subrepo {subrepo}\n" }{file_adds %
358 "HG: subrepo {subrepo}\n" }{file_adds %
359 "HG: added {file}\n" }{file_mods %
359 "HG: added {file}\n" }{file_mods %
360 "HG: changed {file}\n" }{file_dels %
360 "HG: changed {file}\n" }{file_dels %
361 "HG: removed {file}\n" }{if(files, "",
361 "HG: removed {file}\n" }{if(files, "",
362 "HG: no files changed\n")}
362 "HG: no files changed\n")}
363
363
364 .. note::
364 .. note::
365
365
366 For some problematic encodings (see :hg:`help win32mbcs` for
366 For some problematic encodings (see :hg:`help win32mbcs` for
367 detail), this customization should be configured carefully, to
367 detail), this customization should be configured carefully, to
368 avoid showing broken characters.
368 avoid showing broken characters.
369
369
370 For example, if multibyte character ending with backslash (0x5c) is
370 For example, if multibyte character ending with backslash (0x5c) is
371 followed by ASCII character 'n' in the customized template,
371 followed by ASCII character 'n' in the customized template,
372 sequence of backslash and 'n' is treated as line-feed unexpectedly
372 sequence of backslash and 'n' is treated as line-feed unexpectedly
373 (and multibyte character is broken, too).
373 (and multibyte character is broken, too).
374
374
375 Customized template is used for commands below (``--edit`` may be
375 Customized template is used for commands below (``--edit`` may be
376 required):
376 required):
377
377
378 - :hg:`backout`
378 - :hg:`backout`
379 - :hg:`commit`
379 - :hg:`commit`
380 - :hg:`fetch` (for merge commit only)
380 - :hg:`fetch` (for merge commit only)
381 - :hg:`graft`
381 - :hg:`graft`
382 - :hg:`histedit`
382 - :hg:`histedit`
383 - :hg:`import`
383 - :hg:`import`
384 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
384 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
385 - :hg:`rebase`
385 - :hg:`rebase`
386 - :hg:`shelve`
386 - :hg:`shelve`
387 - :hg:`sign`
387 - :hg:`sign`
388 - :hg:`tag`
388 - :hg:`tag`
389 - :hg:`transplant`
389 - :hg:`transplant`
390
390
391 Configuring items below instead of ``changeset`` allows showing
391 Configuring items below instead of ``changeset`` allows showing
392 customized message only for specific actions, or showing different
392 customized message only for specific actions, or showing different
393 messages for each actions.
393 messages for each actions.
394
394
395 - ``changeset.backout`` for :hg:`backout`
395 - ``changeset.backout`` for :hg:`backout`
396 - ``changeset.commit.amend`` for :hg:`commit --amend`
396 - ``changeset.commit.amend`` for :hg:`commit --amend`
397 - ``changeset.commit.normal`` for :hg:`commit` without ``--amend``
397 - ``changeset.commit.normal`` for :hg:`commit` without ``--amend``
398 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
398 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
399 - ``changeset.gpg.sign`` for :hg:`sign`
399 - ``changeset.gpg.sign`` for :hg:`sign`
400 - ``changeset.graft`` for :hg:`graft`
400 - ``changeset.graft`` for :hg:`graft`
401 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
401 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
402 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
402 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
403 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
403 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
404 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
404 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
405 - ``changeset.import.bypass`` for :hg:`import --bypass`
405 - ``changeset.import.bypass`` for :hg:`import --bypass`
406 - ``changeset.import.normal`` for :hg:`import` without ``--bypass``
406 - ``changeset.import.normal`` for :hg:`import` without ``--bypass``
407 - ``changeset.mq.qnew`` for :hg:`qnew`
407 - ``changeset.mq.qnew`` for :hg:`qnew`
408 - ``changeset.mq.qfold`` for :hg:`qfold`
408 - ``changeset.mq.qfold`` for :hg:`qfold`
409 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
409 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
410 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
410 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
411 - ``changeset.rebase.normal`` for :hg:`rebase` without ``--collapse``
411 - ``changeset.rebase.normal`` for :hg:`rebase` without ``--collapse``
412 - ``changeset.shelve.shelve`` for :hg:`shelve`
412 - ``changeset.shelve.shelve`` for :hg:`shelve`
413 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
413 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
414 - ``changeset.tag.remove`` for :hg:`tag --remove`
414 - ``changeset.tag.remove`` for :hg:`tag --remove`
415 - ``changeset.transplant`` for :hg:`transplant`
415 - ``changeset.transplant`` for :hg:`transplant`
416
416
417 These dot-separated lists of names are treated as hierarchical ones.
417 These dot-separated lists of names are treated as hierarchical ones.
418 For example, ``changeset.tag.remove`` customizes the commit message
418 For example, ``changeset.tag.remove`` customizes the commit message
419 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
419 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
420 commit message for :hg:`tag` regardless of ``--remove`` option.
420 commit message for :hg:`tag` regardless of ``--remove`` option.
421
421
422 In this section, items other than ``changeset`` can be referred from
423 others. For example, the configuration to list committed files up
424 below can be referred as ``{listupfiles}``::
425
426 [committemplate]
427 listupfiles = {file_adds %
428 "HG: added {file}\n" }{file_mods %
429 "HG: changed {file}\n" }{file_dels %
430 "HG: removed {file}\n" }{if(files, "",
431 "HG: no files changed\n")}
432
422 ``decode/encode``
433 ``decode/encode``
423 -----------------
434 -----------------
424
435
425 Filters for transforming files on checkout/checkin. This would
436 Filters for transforming files on checkout/checkin. This would
426 typically be used for newline processing or other
437 typically be used for newline processing or other
427 localization/canonicalization of files.
438 localization/canonicalization of files.
428
439
429 Filters consist of a filter pattern followed by a filter command.
440 Filters consist of a filter pattern followed by a filter command.
430 Filter patterns are globs by default, rooted at the repository root.
441 Filter patterns are globs by default, rooted at the repository root.
431 For example, to match any file ending in ``.txt`` in the root
442 For example, to match any file ending in ``.txt`` in the root
432 directory only, use the pattern ``*.txt``. To match any file ending
443 directory only, use the pattern ``*.txt``. To match any file ending
433 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
444 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
434 For each file only the first matching filter applies.
445 For each file only the first matching filter applies.
435
446
436 The filter command can start with a specifier, either ``pipe:`` or
447 The filter command can start with a specifier, either ``pipe:`` or
437 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
448 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
438
449
439 A ``pipe:`` command must accept data on stdin and return the transformed
450 A ``pipe:`` command must accept data on stdin and return the transformed
440 data on stdout.
451 data on stdout.
441
452
442 Pipe example::
453 Pipe example::
443
454
444 [encode]
455 [encode]
445 # uncompress gzip files on checkin to improve delta compression
456 # uncompress gzip files on checkin to improve delta compression
446 # note: not necessarily a good idea, just an example
457 # note: not necessarily a good idea, just an example
447 *.gz = pipe: gunzip
458 *.gz = pipe: gunzip
448
459
449 [decode]
460 [decode]
450 # recompress gzip files when writing them to the working dir (we
461 # recompress gzip files when writing them to the working dir (we
451 # can safely omit "pipe:", because it's the default)
462 # can safely omit "pipe:", because it's the default)
452 *.gz = gzip
463 *.gz = gzip
453
464
454 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
465 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
455 with the name of a temporary file that contains the data to be
466 with the name of a temporary file that contains the data to be
456 filtered by the command. The string ``OUTFILE`` is replaced with the name
467 filtered by the command. The string ``OUTFILE`` is replaced with the name
457 of an empty temporary file, where the filtered data must be written by
468 of an empty temporary file, where the filtered data must be written by
458 the command.
469 the command.
459
470
460 .. note::
471 .. note::
461
472
462 The tempfile mechanism is recommended for Windows systems,
473 The tempfile mechanism is recommended for Windows systems,
463 where the standard shell I/O redirection operators often have
474 where the standard shell I/O redirection operators often have
464 strange effects and may corrupt the contents of your files.
475 strange effects and may corrupt the contents of your files.
465
476
466 This filter mechanism is used internally by the ``eol`` extension to
477 This filter mechanism is used internally by the ``eol`` extension to
467 translate line ending characters between Windows (CRLF) and Unix (LF)
478 translate line ending characters between Windows (CRLF) and Unix (LF)
468 format. We suggest you use the ``eol`` extension for convenience.
479 format. We suggest you use the ``eol`` extension for convenience.
469
480
470
481
471 ``defaults``
482 ``defaults``
472 ------------
483 ------------
473
484
474 (defaults are deprecated. Don't use them. Use aliases instead)
485 (defaults are deprecated. Don't use them. Use aliases instead)
475
486
476 Use the ``[defaults]`` section to define command defaults, i.e. the
487 Use the ``[defaults]`` section to define command defaults, i.e. the
477 default options/arguments to pass to the specified commands.
488 default options/arguments to pass to the specified commands.
478
489
479 The following example makes :hg:`log` run in verbose mode, and
490 The following example makes :hg:`log` run in verbose mode, and
480 :hg:`status` show only the modified files, by default::
491 :hg:`status` show only the modified files, by default::
481
492
482 [defaults]
493 [defaults]
483 log = -v
494 log = -v
484 status = -m
495 status = -m
485
496
486 The actual commands, instead of their aliases, must be used when
497 The actual commands, instead of their aliases, must be used when
487 defining command defaults. The command defaults will also be applied
498 defining command defaults. The command defaults will also be applied
488 to the aliases of the commands defined.
499 to the aliases of the commands defined.
489
500
490
501
491 ``diff``
502 ``diff``
492 --------
503 --------
493
504
494 Settings used when displaying diffs. Everything except for ``unified``
505 Settings used when displaying diffs. Everything except for ``unified``
495 is a Boolean and defaults to False. See ``annotate`` section for
506 is a Boolean and defaults to False. See ``annotate`` section for
496 related options for the annotate command.
507 related options for the annotate command.
497
508
498 ``git``
509 ``git``
499 Use git extended diff format.
510 Use git extended diff format.
500
511
501 ``nodates``
512 ``nodates``
502 Don't include dates in diff headers.
513 Don't include dates in diff headers.
503
514
504 ``showfunc``
515 ``showfunc``
505 Show which function each change is in.
516 Show which function each change is in.
506
517
507 ``ignorews``
518 ``ignorews``
508 Ignore white space when comparing lines.
519 Ignore white space when comparing lines.
509
520
510 ``ignorewsamount``
521 ``ignorewsamount``
511 Ignore changes in the amount of white space.
522 Ignore changes in the amount of white space.
512
523
513 ``ignoreblanklines``
524 ``ignoreblanklines``
514 Ignore changes whose lines are all blank.
525 Ignore changes whose lines are all blank.
515
526
516 ``unified``
527 ``unified``
517 Number of lines of context to show.
528 Number of lines of context to show.
518
529
519 ``email``
530 ``email``
520 ---------
531 ---------
521
532
522 Settings for extensions that send email messages.
533 Settings for extensions that send email messages.
523
534
524 ``from``
535 ``from``
525 Optional. Email address to use in "From" header and SMTP envelope
536 Optional. Email address to use in "From" header and SMTP envelope
526 of outgoing messages.
537 of outgoing messages.
527
538
528 ``to``
539 ``to``
529 Optional. Comma-separated list of recipients' email addresses.
540 Optional. Comma-separated list of recipients' email addresses.
530
541
531 ``cc``
542 ``cc``
532 Optional. Comma-separated list of carbon copy recipients'
543 Optional. Comma-separated list of carbon copy recipients'
533 email addresses.
544 email addresses.
534
545
535 ``bcc``
546 ``bcc``
536 Optional. Comma-separated list of blind carbon copy recipients'
547 Optional. Comma-separated list of blind carbon copy recipients'
537 email addresses.
548 email addresses.
538
549
539 ``method``
550 ``method``
540 Optional. Method to use to send email messages. If value is ``smtp``
551 Optional. Method to use to send email messages. If value is ``smtp``
541 (default), use SMTP (see the ``[smtp]`` section for configuration).
552 (default), use SMTP (see the ``[smtp]`` section for configuration).
542 Otherwise, use as name of program to run that acts like sendmail
553 Otherwise, use as name of program to run that acts like sendmail
543 (takes ``-f`` option for sender, list of recipients on command line,
554 (takes ``-f`` option for sender, list of recipients on command line,
544 message on stdin). Normally, setting this to ``sendmail`` or
555 message on stdin). Normally, setting this to ``sendmail`` or
545 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
556 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
546
557
547 ``charsets``
558 ``charsets``
548 Optional. Comma-separated list of character sets considered
559 Optional. Comma-separated list of character sets considered
549 convenient for recipients. Addresses, headers, and parts not
560 convenient for recipients. Addresses, headers, and parts not
550 containing patches of outgoing messages will be encoded in the
561 containing patches of outgoing messages will be encoded in the
551 first character set to which conversion from local encoding
562 first character set to which conversion from local encoding
552 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
563 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
553 conversion fails, the text in question is sent as is. Defaults to
564 conversion fails, the text in question is sent as is. Defaults to
554 empty (explicit) list.
565 empty (explicit) list.
555
566
556 Order of outgoing email character sets:
567 Order of outgoing email character sets:
557
568
558 1. ``us-ascii``: always first, regardless of settings
569 1. ``us-ascii``: always first, regardless of settings
559 2. ``email.charsets``: in order given by user
570 2. ``email.charsets``: in order given by user
560 3. ``ui.fallbackencoding``: if not in email.charsets
571 3. ``ui.fallbackencoding``: if not in email.charsets
561 4. ``$HGENCODING``: if not in email.charsets
572 4. ``$HGENCODING``: if not in email.charsets
562 5. ``utf-8``: always last, regardless of settings
573 5. ``utf-8``: always last, regardless of settings
563
574
564 Email example::
575 Email example::
565
576
566 [email]
577 [email]
567 from = Joseph User <joe.user@example.com>
578 from = Joseph User <joe.user@example.com>
568 method = /usr/sbin/sendmail
579 method = /usr/sbin/sendmail
569 # charsets for western Europeans
580 # charsets for western Europeans
570 # us-ascii, utf-8 omitted, as they are tried first and last
581 # us-ascii, utf-8 omitted, as they are tried first and last
571 charsets = iso-8859-1, iso-8859-15, windows-1252
582 charsets = iso-8859-1, iso-8859-15, windows-1252
572
583
573
584
574 ``extensions``
585 ``extensions``
575 --------------
586 --------------
576
587
577 Mercurial has an extension mechanism for adding new features. To
588 Mercurial has an extension mechanism for adding new features. To
578 enable an extension, create an entry for it in this section.
589 enable an extension, create an entry for it in this section.
579
590
580 If you know that the extension is already in Python's search path,
591 If you know that the extension is already in Python's search path,
581 you can give the name of the module, followed by ``=``, with nothing
592 you can give the name of the module, followed by ``=``, with nothing
582 after the ``=``.
593 after the ``=``.
583
594
584 Otherwise, give a name that you choose, followed by ``=``, followed by
595 Otherwise, give a name that you choose, followed by ``=``, followed by
585 the path to the ``.py`` file (including the file name extension) that
596 the path to the ``.py`` file (including the file name extension) that
586 defines the extension.
597 defines the extension.
587
598
588 To explicitly disable an extension that is enabled in an hgrc of
599 To explicitly disable an extension that is enabled in an hgrc of
589 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
600 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
590 or ``foo = !`` when path is not supplied.
601 or ``foo = !`` when path is not supplied.
591
602
592 Example for ``~/.hgrc``::
603 Example for ``~/.hgrc``::
593
604
594 [extensions]
605 [extensions]
595 # (the progress extension will get loaded from Mercurial's path)
606 # (the progress extension will get loaded from Mercurial's path)
596 progress =
607 progress =
597 # (this extension will get loaded from the file specified)
608 # (this extension will get loaded from the file specified)
598 myfeature = ~/.hgext/myfeature.py
609 myfeature = ~/.hgext/myfeature.py
599
610
600
611
601 ``format``
612 ``format``
602 ----------
613 ----------
603
614
604 ``usestore``
615 ``usestore``
605 Enable or disable the "store" repository format which improves
616 Enable or disable the "store" repository format which improves
606 compatibility with systems that fold case or otherwise mangle
617 compatibility with systems that fold case or otherwise mangle
607 filenames. Enabled by default. Disabling this option will allow
618 filenames. Enabled by default. Disabling this option will allow
608 you to store longer filenames in some situations at the expense of
619 you to store longer filenames in some situations at the expense of
609 compatibility and ensures that the on-disk format of newly created
620 compatibility and ensures that the on-disk format of newly created
610 repositories will be compatible with Mercurial before version 0.9.4.
621 repositories will be compatible with Mercurial before version 0.9.4.
611
622
612 ``usefncache``
623 ``usefncache``
613 Enable or disable the "fncache" repository format which enhances
624 Enable or disable the "fncache" repository format which enhances
614 the "store" repository format (which has to be enabled to use
625 the "store" repository format (which has to be enabled to use
615 fncache) to allow longer filenames and avoids using Windows
626 fncache) to allow longer filenames and avoids using Windows
616 reserved names, e.g. "nul". Enabled by default. Disabling this
627 reserved names, e.g. "nul". Enabled by default. Disabling this
617 option ensures that the on-disk format of newly created
628 option ensures that the on-disk format of newly created
618 repositories will be compatible with Mercurial before version 1.1.
629 repositories will be compatible with Mercurial before version 1.1.
619
630
620 ``dotencode``
631 ``dotencode``
621 Enable or disable the "dotencode" repository format which enhances
632 Enable or disable the "dotencode" repository format which enhances
622 the "fncache" repository format (which has to be enabled to use
633 the "fncache" repository format (which has to be enabled to use
623 dotencode) to avoid issues with filenames starting with ._ on
634 dotencode) to avoid issues with filenames starting with ._ on
624 Mac OS X and spaces on Windows. Enabled by default. Disabling this
635 Mac OS X and spaces on Windows. Enabled by default. Disabling this
625 option ensures that the on-disk format of newly created
636 option ensures that the on-disk format of newly created
626 repositories will be compatible with Mercurial before version 1.7.
637 repositories will be compatible with Mercurial before version 1.7.
627
638
628 ``graph``
639 ``graph``
629 ---------
640 ---------
630
641
631 Web graph view configuration. This section let you change graph
642 Web graph view configuration. This section let you change graph
632 elements display properties by branches, for instance to make the
643 elements display properties by branches, for instance to make the
633 ``default`` branch stand out.
644 ``default`` branch stand out.
634
645
635 Each line has the following format::
646 Each line has the following format::
636
647
637 <branch>.<argument> = <value>
648 <branch>.<argument> = <value>
638
649
639 where ``<branch>`` is the name of the branch being
650 where ``<branch>`` is the name of the branch being
640 customized. Example::
651 customized. Example::
641
652
642 [graph]
653 [graph]
643 # 2px width
654 # 2px width
644 default.width = 2
655 default.width = 2
645 # red color
656 # red color
646 default.color = FF0000
657 default.color = FF0000
647
658
648 Supported arguments:
659 Supported arguments:
649
660
650 ``width``
661 ``width``
651 Set branch edges width in pixels.
662 Set branch edges width in pixels.
652
663
653 ``color``
664 ``color``
654 Set branch edges color in hexadecimal RGB notation.
665 Set branch edges color in hexadecimal RGB notation.
655
666
656 ``hooks``
667 ``hooks``
657 ---------
668 ---------
658
669
659 Commands or Python functions that get automatically executed by
670 Commands or Python functions that get automatically executed by
660 various actions such as starting or finishing a commit. Multiple
671 various actions such as starting or finishing a commit. Multiple
661 hooks can be run for the same action by appending a suffix to the
672 hooks can be run for the same action by appending a suffix to the
662 action. Overriding a site-wide hook can be done by changing its
673 action. Overriding a site-wide hook can be done by changing its
663 value or setting it to an empty string. Hooks can be prioritized
674 value or setting it to an empty string. Hooks can be prioritized
664 by adding a prefix of ``priority`` to the hook name on a new line
675 by adding a prefix of ``priority`` to the hook name on a new line
665 and setting the priority. The default priority is 0 if
676 and setting the priority. The default priority is 0 if
666 not specified.
677 not specified.
667
678
668 Example ``.hg/hgrc``::
679 Example ``.hg/hgrc``::
669
680
670 [hooks]
681 [hooks]
671 # update working directory after adding changesets
682 # update working directory after adding changesets
672 changegroup.update = hg update
683 changegroup.update = hg update
673 # do not use the site-wide hook
684 # do not use the site-wide hook
674 incoming =
685 incoming =
675 incoming.email = /my/email/hook
686 incoming.email = /my/email/hook
676 incoming.autobuild = /my/build/hook
687 incoming.autobuild = /my/build/hook
677 # force autobuild hook to run before other incoming hooks
688 # force autobuild hook to run before other incoming hooks
678 priority.incoming.autobuild = 1
689 priority.incoming.autobuild = 1
679
690
680 Most hooks are run with environment variables set that give useful
691 Most hooks are run with environment variables set that give useful
681 additional information. For each hook below, the environment
692 additional information. For each hook below, the environment
682 variables it is passed are listed with names of the form ``$HG_foo``.
693 variables it is passed are listed with names of the form ``$HG_foo``.
683
694
684 ``changegroup``
695 ``changegroup``
685 Run after a changegroup has been added via push, pull or unbundle.
696 Run after a changegroup has been added via push, pull or unbundle.
686 ID of the first new changeset is in ``$HG_NODE``. URL from which
697 ID of the first new changeset is in ``$HG_NODE``. URL from which
687 changes came is in ``$HG_URL``.
698 changes came is in ``$HG_URL``.
688
699
689 ``commit``
700 ``commit``
690 Run after a changeset has been created in the local repository. ID
701 Run after a changeset has been created in the local repository. ID
691 of the newly created changeset is in ``$HG_NODE``. Parent changeset
702 of the newly created changeset is in ``$HG_NODE``. Parent changeset
692 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
703 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
693
704
694 ``incoming``
705 ``incoming``
695 Run after a changeset has been pulled, pushed, or unbundled into
706 Run after a changeset has been pulled, pushed, or unbundled into
696 the local repository. The ID of the newly arrived changeset is in
707 the local repository. The ID of the newly arrived changeset is in
697 ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
708 ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
698
709
699 ``outgoing``
710 ``outgoing``
700 Run after sending changes from local repository to another. ID of
711 Run after sending changes from local repository to another. ID of
701 first changeset sent is in ``$HG_NODE``. Source of operation is in
712 first changeset sent is in ``$HG_NODE``. Source of operation is in
702 ``$HG_SOURCE``; see "preoutgoing" hook for description.
713 ``$HG_SOURCE``; see "preoutgoing" hook for description.
703
714
704 ``post-<command>``
715 ``post-<command>``
705 Run after successful invocations of the associated command. The
716 Run after successful invocations of the associated command. The
706 contents of the command line are passed as ``$HG_ARGS`` and the result
717 contents of the command line are passed as ``$HG_ARGS`` and the result
707 code in ``$HG_RESULT``. Parsed command line arguments are passed as
718 code in ``$HG_RESULT``. Parsed command line arguments are passed as
708 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
719 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
709 the python data internally passed to <command>. ``$HG_OPTS`` is a
720 the python data internally passed to <command>. ``$HG_OPTS`` is a
710 dictionary of options (with unspecified options set to their defaults).
721 dictionary of options (with unspecified options set to their defaults).
711 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
722 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
712
723
713 ``pre-<command>``
724 ``pre-<command>``
714 Run before executing the associated command. The contents of the
725 Run before executing the associated command. The contents of the
715 command line are passed as ``$HG_ARGS``. Parsed command line arguments
726 command line are passed as ``$HG_ARGS``. Parsed command line arguments
716 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
727 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
717 representations of the data internally passed to <command>. ``$HG_OPTS``
728 representations of the data internally passed to <command>. ``$HG_OPTS``
718 is a dictionary of options (with unspecified options set to their
729 is a dictionary of options (with unspecified options set to their
719 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
730 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
720 failure, the command doesn't execute and Mercurial returns the failure
731 failure, the command doesn't execute and Mercurial returns the failure
721 code.
732 code.
722
733
723 ``prechangegroup``
734 ``prechangegroup``
724 Run before a changegroup is added via push, pull or unbundle. Exit
735 Run before a changegroup is added via push, pull or unbundle. Exit
725 status 0 allows the changegroup to proceed. Non-zero status will
736 status 0 allows the changegroup to proceed. Non-zero status will
726 cause the push, pull or unbundle to fail. URL from which changes
737 cause the push, pull or unbundle to fail. URL from which changes
727 will come is in ``$HG_URL``.
738 will come is in ``$HG_URL``.
728
739
729 ``precommit``
740 ``precommit``
730 Run before starting a local commit. Exit status 0 allows the
741 Run before starting a local commit. Exit status 0 allows the
731 commit to proceed. Non-zero status will cause the commit to fail.
742 commit to proceed. Non-zero status will cause the commit to fail.
732 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
743 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
733
744
734 ``prelistkeys``
745 ``prelistkeys``
735 Run before listing pushkeys (like bookmarks) in the
746 Run before listing pushkeys (like bookmarks) in the
736 repository. Non-zero status will cause failure. The key namespace is
747 repository. Non-zero status will cause failure. The key namespace is
737 in ``$HG_NAMESPACE``.
748 in ``$HG_NAMESPACE``.
738
749
739 ``preoutgoing``
750 ``preoutgoing``
740 Run before collecting changes to send from the local repository to
751 Run before collecting changes to send from the local repository to
741 another. Non-zero status will cause failure. This lets you prevent
752 another. Non-zero status will cause failure. This lets you prevent
742 pull over HTTP or SSH. Also prevents against local pull, push
753 pull over HTTP or SSH. Also prevents against local pull, push
743 (outbound) or bundle commands, but not effective, since you can
754 (outbound) or bundle commands, but not effective, since you can
744 just copy files instead then. Source of operation is in
755 just copy files instead then. Source of operation is in
745 ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
756 ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
746 SSH or HTTP repository. If "push", "pull" or "bundle", operation
757 SSH or HTTP repository. If "push", "pull" or "bundle", operation
747 is happening on behalf of repository on same system.
758 is happening on behalf of repository on same system.
748
759
749 ``prepushkey``
760 ``prepushkey``
750 Run before a pushkey (like a bookmark) is added to the
761 Run before a pushkey (like a bookmark) is added to the
751 repository. Non-zero status will cause the key to be rejected. The
762 repository. Non-zero status will cause the key to be rejected. The
752 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
763 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
753 the old value (if any) is in ``$HG_OLD``, and the new value is in
764 the old value (if any) is in ``$HG_OLD``, and the new value is in
754 ``$HG_NEW``.
765 ``$HG_NEW``.
755
766
756 ``pretag``
767 ``pretag``
757 Run before creating a tag. Exit status 0 allows the tag to be
768 Run before creating a tag. Exit status 0 allows the tag to be
758 created. Non-zero status will cause the tag to fail. ID of
769 created. Non-zero status will cause the tag to fail. ID of
759 changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
770 changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
760 local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
771 local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
761
772
762 ``pretxnchangegroup``
773 ``pretxnchangegroup``
763 Run after a changegroup has been added via push, pull or unbundle,
774 Run after a changegroup has been added via push, pull or unbundle,
764 but before the transaction has been committed. Changegroup is
775 but before the transaction has been committed. Changegroup is
765 visible to hook program. This lets you validate incoming changes
776 visible to hook program. This lets you validate incoming changes
766 before accepting them. Passed the ID of the first new changeset in
777 before accepting them. Passed the ID of the first new changeset in
767 ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
778 ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
768 status will cause the transaction to be rolled back and the push,
779 status will cause the transaction to be rolled back and the push,
769 pull or unbundle will fail. URL that was source of changes is in
780 pull or unbundle will fail. URL that was source of changes is in
770 ``$HG_URL``.
781 ``$HG_URL``.
771
782
772 ``pretxncommit``
783 ``pretxncommit``
773 Run after a changeset has been created but the transaction not yet
784 Run after a changeset has been created but the transaction not yet
774 committed. Changeset is visible to hook program. This lets you
785 committed. Changeset is visible to hook program. This lets you
775 validate commit message and changes. Exit status 0 allows the
786 validate commit message and changes. Exit status 0 allows the
776 commit to proceed. Non-zero status will cause the transaction to
787 commit to proceed. Non-zero status will cause the transaction to
777 be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
788 be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
778 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
789 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
779
790
780 ``preupdate``
791 ``preupdate``
781 Run before updating the working directory. Exit status 0 allows
792 Run before updating the working directory. Exit status 0 allows
782 the update to proceed. Non-zero status will prevent the update.
793 the update to proceed. Non-zero status will prevent the update.
783 Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
794 Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
784 of second new parent is in ``$HG_PARENT2``.
795 of second new parent is in ``$HG_PARENT2``.
785
796
786 ``listkeys``
797 ``listkeys``
787 Run after listing pushkeys (like bookmarks) in the repository. The
798 Run after listing pushkeys (like bookmarks) in the repository. The
788 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
799 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
789 dictionary containing the keys and values.
800 dictionary containing the keys and values.
790
801
791 ``pushkey``
802 ``pushkey``
792 Run after a pushkey (like a bookmark) is added to the
803 Run after a pushkey (like a bookmark) is added to the
793 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
804 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
794 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
805 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
795 value is in ``$HG_NEW``.
806 value is in ``$HG_NEW``.
796
807
797 ``tag``
808 ``tag``
798 Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
809 Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
799 Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
810 Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
800 repository if ``$HG_LOCAL=0``.
811 repository if ``$HG_LOCAL=0``.
801
812
802 ``update``
813 ``update``
803 Run after updating the working directory. Changeset ID of first
814 Run after updating the working directory. Changeset ID of first
804 new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
815 new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
805 in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
816 in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
806 update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
817 update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
807
818
808 .. note::
819 .. note::
809
820
810 It is generally better to use standard hooks rather than the
821 It is generally better to use standard hooks rather than the
811 generic pre- and post- command hooks as they are guaranteed to be
822 generic pre- and post- command hooks as they are guaranteed to be
812 called in the appropriate contexts for influencing transactions.
823 called in the appropriate contexts for influencing transactions.
813 Also, hooks like "commit" will be called in all contexts that
824 Also, hooks like "commit" will be called in all contexts that
814 generate a commit (e.g. tag) and not just the commit command.
825 generate a commit (e.g. tag) and not just the commit command.
815
826
816 .. note::
827 .. note::
817
828
818 Environment variables with empty values may not be passed to
829 Environment variables with empty values may not be passed to
819 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
830 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
820 will have an empty value under Unix-like platforms for non-merge
831 will have an empty value under Unix-like platforms for non-merge
821 changesets, while it will not be available at all under Windows.
832 changesets, while it will not be available at all under Windows.
822
833
823 The syntax for Python hooks is as follows::
834 The syntax for Python hooks is as follows::
824
835
825 hookname = python:modulename.submodule.callable
836 hookname = python:modulename.submodule.callable
826 hookname = python:/path/to/python/module.py:callable
837 hookname = python:/path/to/python/module.py:callable
827
838
828 Python hooks are run within the Mercurial process. Each hook is
839 Python hooks are run within the Mercurial process. Each hook is
829 called with at least three keyword arguments: a ui object (keyword
840 called with at least three keyword arguments: a ui object (keyword
830 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
841 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
831 keyword that tells what kind of hook is used. Arguments listed as
842 keyword that tells what kind of hook is used. Arguments listed as
832 environment variables above are passed as keyword arguments, with no
843 environment variables above are passed as keyword arguments, with no
833 ``HG_`` prefix, and names in lower case.
844 ``HG_`` prefix, and names in lower case.
834
845
835 If a Python hook returns a "true" value or raises an exception, this
846 If a Python hook returns a "true" value or raises an exception, this
836 is treated as a failure.
847 is treated as a failure.
837
848
838
849
839 ``hostfingerprints``
850 ``hostfingerprints``
840 --------------------
851 --------------------
841
852
842 Fingerprints of the certificates of known HTTPS servers.
853 Fingerprints of the certificates of known HTTPS servers.
843 A HTTPS connection to a server with a fingerprint configured here will
854 A HTTPS connection to a server with a fingerprint configured here will
844 only succeed if the servers certificate matches the fingerprint.
855 only succeed if the servers certificate matches the fingerprint.
845 This is very similar to how ssh known hosts works.
856 This is very similar to how ssh known hosts works.
846 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
857 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
847 The CA chain and web.cacerts is not used for servers with a fingerprint.
858 The CA chain and web.cacerts is not used for servers with a fingerprint.
848
859
849 For example::
860 For example::
850
861
851 [hostfingerprints]
862 [hostfingerprints]
852 hg.intevation.org = fa:1f:d9:48:f1:e7:74:30:38:8d:d8:58:b6:94:b8:58:28:7d:8b:d0
863 hg.intevation.org = fa:1f:d9:48:f1:e7:74:30:38:8d:d8:58:b6:94:b8:58:28:7d:8b:d0
853
864
854 This feature is only supported when using Python 2.6 or later.
865 This feature is only supported when using Python 2.6 or later.
855
866
856
867
857 ``http_proxy``
868 ``http_proxy``
858 --------------
869 --------------
859
870
860 Used to access web-based Mercurial repositories through a HTTP
871 Used to access web-based Mercurial repositories through a HTTP
861 proxy.
872 proxy.
862
873
863 ``host``
874 ``host``
864 Host name and (optional) port of the proxy server, for example
875 Host name and (optional) port of the proxy server, for example
865 "myproxy:8000".
876 "myproxy:8000".
866
877
867 ``no``
878 ``no``
868 Optional. Comma-separated list of host names that should bypass
879 Optional. Comma-separated list of host names that should bypass
869 the proxy.
880 the proxy.
870
881
871 ``passwd``
882 ``passwd``
872 Optional. Password to authenticate with at the proxy server.
883 Optional. Password to authenticate with at the proxy server.
873
884
874 ``user``
885 ``user``
875 Optional. User name to authenticate with at the proxy server.
886 Optional. User name to authenticate with at the proxy server.
876
887
877 ``always``
888 ``always``
878 Optional. Always use the proxy, even for localhost and any entries
889 Optional. Always use the proxy, even for localhost and any entries
879 in ``http_proxy.no``. True or False. Default: False.
890 in ``http_proxy.no``. True or False. Default: False.
880
891
881 ``merge-patterns``
892 ``merge-patterns``
882 ------------------
893 ------------------
883
894
884 This section specifies merge tools to associate with particular file
895 This section specifies merge tools to associate with particular file
885 patterns. Tools matched here will take precedence over the default
896 patterns. Tools matched here will take precedence over the default
886 merge tool. Patterns are globs by default, rooted at the repository
897 merge tool. Patterns are globs by default, rooted at the repository
887 root.
898 root.
888
899
889 Example::
900 Example::
890
901
891 [merge-patterns]
902 [merge-patterns]
892 **.c = kdiff3
903 **.c = kdiff3
893 **.jpg = myimgmerge
904 **.jpg = myimgmerge
894
905
895 ``merge-tools``
906 ``merge-tools``
896 ---------------
907 ---------------
897
908
898 This section configures external merge tools to use for file-level
909 This section configures external merge tools to use for file-level
899 merges. This section has likely been preconfigured at install time.
910 merges. This section has likely been preconfigured at install time.
900 Use :hg:`config merge-tools` to check the existing configuration.
911 Use :hg:`config merge-tools` to check the existing configuration.
901 Also see :hg:`help merge-tools` for more details.
912 Also see :hg:`help merge-tools` for more details.
902
913
903 Example ``~/.hgrc``::
914 Example ``~/.hgrc``::
904
915
905 [merge-tools]
916 [merge-tools]
906 # Override stock tool location
917 # Override stock tool location
907 kdiff3.executable = ~/bin/kdiff3
918 kdiff3.executable = ~/bin/kdiff3
908 # Specify command line
919 # Specify command line
909 kdiff3.args = $base $local $other -o $output
920 kdiff3.args = $base $local $other -o $output
910 # Give higher priority
921 # Give higher priority
911 kdiff3.priority = 1
922 kdiff3.priority = 1
912
923
913 # Changing the priority of preconfigured tool
924 # Changing the priority of preconfigured tool
914 vimdiff.priority = 0
925 vimdiff.priority = 0
915
926
916 # Define new tool
927 # Define new tool
917 myHtmlTool.args = -m $local $other $base $output
928 myHtmlTool.args = -m $local $other $base $output
918 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
929 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
919 myHtmlTool.priority = 1
930 myHtmlTool.priority = 1
920
931
921 Supported arguments:
932 Supported arguments:
922
933
923 ``priority``
934 ``priority``
924 The priority in which to evaluate this tool.
935 The priority in which to evaluate this tool.
925 Default: 0.
936 Default: 0.
926
937
927 ``executable``
938 ``executable``
928 Either just the name of the executable or its pathname. On Windows,
939 Either just the name of the executable or its pathname. On Windows,
929 the path can use environment variables with ${ProgramFiles} syntax.
940 the path can use environment variables with ${ProgramFiles} syntax.
930 Default: the tool name.
941 Default: the tool name.
931
942
932 ``args``
943 ``args``
933 The arguments to pass to the tool executable. You can refer to the
944 The arguments to pass to the tool executable. You can refer to the
934 files being merged as well as the output file through these
945 files being merged as well as the output file through these
935 variables: ``$base``, ``$local``, ``$other``, ``$output``. The meaning
946 variables: ``$base``, ``$local``, ``$other``, ``$output``. The meaning
936 of ``$local`` and ``$other`` can vary depending on which action is being
947 of ``$local`` and ``$other`` can vary depending on which action is being
937 performed. During and update or merge, ``$local`` represents the original
948 performed. During and update or merge, ``$local`` represents the original
938 state of the file, while ``$other`` represents the commit you are updating
949 state of the file, while ``$other`` represents the commit you are updating
939 to or the commit you are merging with. During a rebase ``$local``
950 to or the commit you are merging with. During a rebase ``$local``
940 represents the destination of the rebase, and ``$other`` represents the
951 represents the destination of the rebase, and ``$other`` represents the
941 commit being rebased.
952 commit being rebased.
942 Default: ``$local $base $other``
953 Default: ``$local $base $other``
943
954
944 ``premerge``
955 ``premerge``
945 Attempt to run internal non-interactive 3-way merge tool before
956 Attempt to run internal non-interactive 3-way merge tool before
946 launching external tool. Options are ``true``, ``false``, or ``keep``
957 launching external tool. Options are ``true``, ``false``, or ``keep``
947 to leave markers in the file if the premerge fails.
958 to leave markers in the file if the premerge fails.
948 Default: True
959 Default: True
949
960
950 ``binary``
961 ``binary``
951 This tool can merge binary files. Defaults to False, unless tool
962 This tool can merge binary files. Defaults to False, unless tool
952 was selected by file pattern match.
963 was selected by file pattern match.
953
964
954 ``symlink``
965 ``symlink``
955 This tool can merge symlinks. Defaults to False, even if tool was
966 This tool can merge symlinks. Defaults to False, even if tool was
956 selected by file pattern match.
967 selected by file pattern match.
957
968
958 ``check``
969 ``check``
959 A list of merge success-checking options:
970 A list of merge success-checking options:
960
971
961 ``changed``
972 ``changed``
962 Ask whether merge was successful when the merged file shows no changes.
973 Ask whether merge was successful when the merged file shows no changes.
963 ``conflicts``
974 ``conflicts``
964 Check whether there are conflicts even though the tool reported success.
975 Check whether there are conflicts even though the tool reported success.
965 ``prompt``
976 ``prompt``
966 Always prompt for merge success, regardless of success reported by tool.
977 Always prompt for merge success, regardless of success reported by tool.
967
978
968 ``fixeol``
979 ``fixeol``
969 Attempt to fix up EOL changes caused by the merge tool.
980 Attempt to fix up EOL changes caused by the merge tool.
970 Default: False
981 Default: False
971
982
972 ``gui``
983 ``gui``
973 This tool requires a graphical interface to run. Default: False
984 This tool requires a graphical interface to run. Default: False
974
985
975 ``regkey``
986 ``regkey``
976 Windows registry key which describes install location of this
987 Windows registry key which describes install location of this
977 tool. Mercurial will search for this key first under
988 tool. Mercurial will search for this key first under
978 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
989 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
979 Default: None
990 Default: None
980
991
981 ``regkeyalt``
992 ``regkeyalt``
982 An alternate Windows registry key to try if the first key is not
993 An alternate Windows registry key to try if the first key is not
983 found. The alternate key uses the same ``regname`` and ``regappend``
994 found. The alternate key uses the same ``regname`` and ``regappend``
984 semantics of the primary key. The most common use for this key
995 semantics of the primary key. The most common use for this key
985 is to search for 32bit applications on 64bit operating systems.
996 is to search for 32bit applications on 64bit operating systems.
986 Default: None
997 Default: None
987
998
988 ``regname``
999 ``regname``
989 Name of value to read from specified registry key. Defaults to the
1000 Name of value to read from specified registry key. Defaults to the
990 unnamed (default) value.
1001 unnamed (default) value.
991
1002
992 ``regappend``
1003 ``regappend``
993 String to append to the value read from the registry, typically
1004 String to append to the value read from the registry, typically
994 the executable name of the tool.
1005 the executable name of the tool.
995 Default: None
1006 Default: None
996
1007
997
1008
998 ``patch``
1009 ``patch``
999 ---------
1010 ---------
1000
1011
1001 Settings used when applying patches, for instance through the 'import'
1012 Settings used when applying patches, for instance through the 'import'
1002 command or with Mercurial Queues extension.
1013 command or with Mercurial Queues extension.
1003
1014
1004 ``eol``
1015 ``eol``
1005 When set to 'strict' patch content and patched files end of lines
1016 When set to 'strict' patch content and patched files end of lines
1006 are preserved. When set to ``lf`` or ``crlf``, both files end of
1017 are preserved. When set to ``lf`` or ``crlf``, both files end of
1007 lines are ignored when patching and the result line endings are
1018 lines are ignored when patching and the result line endings are
1008 normalized to either LF (Unix) or CRLF (Windows). When set to
1019 normalized to either LF (Unix) or CRLF (Windows). When set to
1009 ``auto``, end of lines are again ignored while patching but line
1020 ``auto``, end of lines are again ignored while patching but line
1010 endings in patched files are normalized to their original setting
1021 endings in patched files are normalized to their original setting
1011 on a per-file basis. If target file does not exist or has no end
1022 on a per-file basis. If target file does not exist or has no end
1012 of line, patch line endings are preserved.
1023 of line, patch line endings are preserved.
1013 Default: strict.
1024 Default: strict.
1014
1025
1015
1026
1016 ``paths``
1027 ``paths``
1017 ---------
1028 ---------
1018
1029
1019 Assigns symbolic names to repositories. The left side is the
1030 Assigns symbolic names to repositories. The left side is the
1020 symbolic name, and the right gives the directory or URL that is the
1031 symbolic name, and the right gives the directory or URL that is the
1021 location of the repository. Default paths can be declared by setting
1032 location of the repository. Default paths can be declared by setting
1022 the following entries.
1033 the following entries.
1023
1034
1024 ``default``
1035 ``default``
1025 Directory or URL to use when pulling if no source is specified.
1036 Directory or URL to use when pulling if no source is specified.
1026 Default is set to repository from which the current repository was
1037 Default is set to repository from which the current repository was
1027 cloned.
1038 cloned.
1028
1039
1029 ``default-push``
1040 ``default-push``
1030 Optional. Directory or URL to use when pushing if no destination
1041 Optional. Directory or URL to use when pushing if no destination
1031 is specified.
1042 is specified.
1032
1043
1033 Custom paths can be defined by assigning the path to a name that later can be
1044 Custom paths can be defined by assigning the path to a name that later can be
1034 used from the command line. Example::
1045 used from the command line. Example::
1035
1046
1036 [paths]
1047 [paths]
1037 my_path = http://example.com/path
1048 my_path = http://example.com/path
1038
1049
1039 To push to the path defined in ``my_path`` run the command::
1050 To push to the path defined in ``my_path`` run the command::
1040
1051
1041 hg push my_path
1052 hg push my_path
1042
1053
1043
1054
1044 ``phases``
1055 ``phases``
1045 ----------
1056 ----------
1046
1057
1047 Specifies default handling of phases. See :hg:`help phases` for more
1058 Specifies default handling of phases. See :hg:`help phases` for more
1048 information about working with phases.
1059 information about working with phases.
1049
1060
1050 ``publish``
1061 ``publish``
1051 Controls draft phase behavior when working as a server. When true,
1062 Controls draft phase behavior when working as a server. When true,
1052 pushed changesets are set to public in both client and server and
1063 pushed changesets are set to public in both client and server and
1053 pulled or cloned changesets are set to public in the client.
1064 pulled or cloned changesets are set to public in the client.
1054 Default: True
1065 Default: True
1055
1066
1056 ``new-commit``
1067 ``new-commit``
1057 Phase of newly-created commits.
1068 Phase of newly-created commits.
1058 Default: draft
1069 Default: draft
1059
1070
1060 ``checksubrepos``
1071 ``checksubrepos``
1061 Check the phase of the current revision of each subrepository. Allowed
1072 Check the phase of the current revision of each subrepository. Allowed
1062 values are "ignore", "follow" and "abort". For settings other than
1073 values are "ignore", "follow" and "abort". For settings other than
1063 "ignore", the phase of the current revision of each subrepository is
1074 "ignore", the phase of the current revision of each subrepository is
1064 checked before committing the parent repository. If any of those phases is
1075 checked before committing the parent repository. If any of those phases is
1065 greater than the phase of the parent repository (e.g. if a subrepo is in a
1076 greater than the phase of the parent repository (e.g. if a subrepo is in a
1066 "secret" phase while the parent repo is in "draft" phase), the commit is
1077 "secret" phase while the parent repo is in "draft" phase), the commit is
1067 either aborted (if checksubrepos is set to "abort") or the higher phase is
1078 either aborted (if checksubrepos is set to "abort") or the higher phase is
1068 used for the parent repository commit (if set to "follow").
1079 used for the parent repository commit (if set to "follow").
1069 Default: "follow"
1080 Default: "follow"
1070
1081
1071
1082
1072 ``profiling``
1083 ``profiling``
1073 -------------
1084 -------------
1074
1085
1075 Specifies profiling type, format, and file output. Two profilers are
1086 Specifies profiling type, format, and file output. Two profilers are
1076 supported: an instrumenting profiler (named ``ls``), and a sampling
1087 supported: an instrumenting profiler (named ``ls``), and a sampling
1077 profiler (named ``stat``).
1088 profiler (named ``stat``).
1078
1089
1079 In this section description, 'profiling data' stands for the raw data
1090 In this section description, 'profiling data' stands for the raw data
1080 collected during profiling, while 'profiling report' stands for a
1091 collected during profiling, while 'profiling report' stands for a
1081 statistical text report generated from the profiling data. The
1092 statistical text report generated from the profiling data. The
1082 profiling is done using lsprof.
1093 profiling is done using lsprof.
1083
1094
1084 ``type``
1095 ``type``
1085 The type of profiler to use.
1096 The type of profiler to use.
1086 Default: ls.
1097 Default: ls.
1087
1098
1088 ``ls``
1099 ``ls``
1089 Use Python's built-in instrumenting profiler. This profiler
1100 Use Python's built-in instrumenting profiler. This profiler
1090 works on all platforms, but each line number it reports is the
1101 works on all platforms, but each line number it reports is the
1091 first line of a function. This restriction makes it difficult to
1102 first line of a function. This restriction makes it difficult to
1092 identify the expensive parts of a non-trivial function.
1103 identify the expensive parts of a non-trivial function.
1093 ``stat``
1104 ``stat``
1094 Use a third-party statistical profiler, statprof. This profiler
1105 Use a third-party statistical profiler, statprof. This profiler
1095 currently runs only on Unix systems, and is most useful for
1106 currently runs only on Unix systems, and is most useful for
1096 profiling commands that run for longer than about 0.1 seconds.
1107 profiling commands that run for longer than about 0.1 seconds.
1097
1108
1098 ``format``
1109 ``format``
1099 Profiling format. Specific to the ``ls`` instrumenting profiler.
1110 Profiling format. Specific to the ``ls`` instrumenting profiler.
1100 Default: text.
1111 Default: text.
1101
1112
1102 ``text``
1113 ``text``
1103 Generate a profiling report. When saving to a file, it should be
1114 Generate a profiling report. When saving to a file, it should be
1104 noted that only the report is saved, and the profiling data is
1115 noted that only the report is saved, and the profiling data is
1105 not kept.
1116 not kept.
1106 ``kcachegrind``
1117 ``kcachegrind``
1107 Format profiling data for kcachegrind use: when saving to a
1118 Format profiling data for kcachegrind use: when saving to a
1108 file, the generated file can directly be loaded into
1119 file, the generated file can directly be loaded into
1109 kcachegrind.
1120 kcachegrind.
1110
1121
1111 ``frequency``
1122 ``frequency``
1112 Sampling frequency. Specific to the ``stat`` sampling profiler.
1123 Sampling frequency. Specific to the ``stat`` sampling profiler.
1113 Default: 1000.
1124 Default: 1000.
1114
1125
1115 ``output``
1126 ``output``
1116 File path where profiling data or report should be saved. If the
1127 File path where profiling data or report should be saved. If the
1117 file exists, it is replaced. Default: None, data is printed on
1128 file exists, it is replaced. Default: None, data is printed on
1118 stderr
1129 stderr
1119
1130
1120 ``sort``
1131 ``sort``
1121 Sort field. Specific to the ``ls`` instrumenting profiler.
1132 Sort field. Specific to the ``ls`` instrumenting profiler.
1122 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1133 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1123 ``inlinetime``.
1134 ``inlinetime``.
1124 Default: inlinetime.
1135 Default: inlinetime.
1125
1136
1126 ``limit``
1137 ``limit``
1127 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1138 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1128 Default: 30.
1139 Default: 30.
1129
1140
1130 ``nested``
1141 ``nested``
1131 Show at most this number of lines of drill-down info after each main entry.
1142 Show at most this number of lines of drill-down info after each main entry.
1132 This can help explain the difference between Total and Inline.
1143 This can help explain the difference between Total and Inline.
1133 Specific to the ``ls`` instrumenting profiler.
1144 Specific to the ``ls`` instrumenting profiler.
1134 Default: 5.
1145 Default: 5.
1135
1146
1136 ``revsetalias``
1147 ``revsetalias``
1137 ---------------
1148 ---------------
1138
1149
1139 Alias definitions for revsets. See :hg:`help revsets` for details.
1150 Alias definitions for revsets. See :hg:`help revsets` for details.
1140
1151
1141 ``server``
1152 ``server``
1142 ----------
1153 ----------
1143
1154
1144 Controls generic server settings.
1155 Controls generic server settings.
1145
1156
1146 ``uncompressed``
1157 ``uncompressed``
1147 Whether to allow clients to clone a repository using the
1158 Whether to allow clients to clone a repository using the
1148 uncompressed streaming protocol. This transfers about 40% more
1159 uncompressed streaming protocol. This transfers about 40% more
1149 data than a regular clone, but uses less memory and CPU on both
1160 data than a regular clone, but uses less memory and CPU on both
1150 server and client. Over a LAN (100 Mbps or better) or a very fast
1161 server and client. Over a LAN (100 Mbps or better) or a very fast
1151 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1162 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1152 regular clone. Over most WAN connections (anything slower than
1163 regular clone. Over most WAN connections (anything slower than
1153 about 6 Mbps), uncompressed streaming is slower, because of the
1164 about 6 Mbps), uncompressed streaming is slower, because of the
1154 extra data transfer overhead. This mode will also temporarily hold
1165 extra data transfer overhead. This mode will also temporarily hold
1155 the write lock while determining what data to transfer.
1166 the write lock while determining what data to transfer.
1156 Default is True.
1167 Default is True.
1157
1168
1158 ``preferuncompressed``
1169 ``preferuncompressed``
1159 When set, clients will try to use the uncompressed streaming
1170 When set, clients will try to use the uncompressed streaming
1160 protocol. Default is False.
1171 protocol. Default is False.
1161
1172
1162 ``validate``
1173 ``validate``
1163 Whether to validate the completeness of pushed changesets by
1174 Whether to validate the completeness of pushed changesets by
1164 checking that all new file revisions specified in manifests are
1175 checking that all new file revisions specified in manifests are
1165 present. Default is False.
1176 present. Default is False.
1166
1177
1167 ``smtp``
1178 ``smtp``
1168 --------
1179 --------
1169
1180
1170 Configuration for extensions that need to send email messages.
1181 Configuration for extensions that need to send email messages.
1171
1182
1172 ``host``
1183 ``host``
1173 Host name of mail server, e.g. "mail.example.com".
1184 Host name of mail server, e.g. "mail.example.com".
1174
1185
1175 ``port``
1186 ``port``
1176 Optional. Port to connect to on mail server. Default: 465 (if
1187 Optional. Port to connect to on mail server. Default: 465 (if
1177 ``tls`` is smtps) or 25 (otherwise).
1188 ``tls`` is smtps) or 25 (otherwise).
1178
1189
1179 ``tls``
1190 ``tls``
1180 Optional. Method to enable TLS when connecting to mail server: starttls,
1191 Optional. Method to enable TLS when connecting to mail server: starttls,
1181 smtps or none. Default: none.
1192 smtps or none. Default: none.
1182
1193
1183 ``verifycert``
1194 ``verifycert``
1184 Optional. Verification for the certificate of mail server, when
1195 Optional. Verification for the certificate of mail server, when
1185 ``tls`` is starttls or smtps. "strict", "loose" or False. For
1196 ``tls`` is starttls or smtps. "strict", "loose" or False. For
1186 "strict" or "loose", the certificate is verified as same as the
1197 "strict" or "loose", the certificate is verified as same as the
1187 verification for HTTPS connections (see ``[hostfingerprints]`` and
1198 verification for HTTPS connections (see ``[hostfingerprints]`` and
1188 ``[web] cacerts`` also). For "strict", sending email is also
1199 ``[web] cacerts`` also). For "strict", sending email is also
1189 aborted, if there is no configuration for mail server in
1200 aborted, if there is no configuration for mail server in
1190 ``[hostfingerprints]`` and ``[web] cacerts``. --insecure for
1201 ``[hostfingerprints]`` and ``[web] cacerts``. --insecure for
1191 :hg:`email` overwrites this as "loose". Default: "strict".
1202 :hg:`email` overwrites this as "loose". Default: "strict".
1192
1203
1193 ``username``
1204 ``username``
1194 Optional. User name for authenticating with the SMTP server.
1205 Optional. User name for authenticating with the SMTP server.
1195 Default: none.
1206 Default: none.
1196
1207
1197 ``password``
1208 ``password``
1198 Optional. Password for authenticating with the SMTP server. If not
1209 Optional. Password for authenticating with the SMTP server. If not
1199 specified, interactive sessions will prompt the user for a
1210 specified, interactive sessions will prompt the user for a
1200 password; non-interactive sessions will fail. Default: none.
1211 password; non-interactive sessions will fail. Default: none.
1201
1212
1202 ``local_hostname``
1213 ``local_hostname``
1203 Optional. It's the hostname that the sender can use to identify
1214 Optional. It's the hostname that the sender can use to identify
1204 itself to the MTA.
1215 itself to the MTA.
1205
1216
1206
1217
1207 ``subpaths``
1218 ``subpaths``
1208 ------------
1219 ------------
1209
1220
1210 Subrepository source URLs can go stale if a remote server changes name
1221 Subrepository source URLs can go stale if a remote server changes name
1211 or becomes temporarily unavailable. This section lets you define
1222 or becomes temporarily unavailable. This section lets you define
1212 rewrite rules of the form::
1223 rewrite rules of the form::
1213
1224
1214 <pattern> = <replacement>
1225 <pattern> = <replacement>
1215
1226
1216 where ``pattern`` is a regular expression matching a subrepository
1227 where ``pattern`` is a regular expression matching a subrepository
1217 source URL and ``replacement`` is the replacement string used to
1228 source URL and ``replacement`` is the replacement string used to
1218 rewrite it. Groups can be matched in ``pattern`` and referenced in
1229 rewrite it. Groups can be matched in ``pattern`` and referenced in
1219 ``replacements``. For instance::
1230 ``replacements``. For instance::
1220
1231
1221 http://server/(.*)-hg/ = http://hg.server/\1/
1232 http://server/(.*)-hg/ = http://hg.server/\1/
1222
1233
1223 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
1234 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
1224
1235
1225 Relative subrepository paths are first made absolute, and the
1236 Relative subrepository paths are first made absolute, and the
1226 rewrite rules are then applied on the full (absolute) path. The rules
1237 rewrite rules are then applied on the full (absolute) path. The rules
1227 are applied in definition order.
1238 are applied in definition order.
1228
1239
1229 ``trusted``
1240 ``trusted``
1230 -----------
1241 -----------
1231
1242
1232 Mercurial will not use the settings in the
1243 Mercurial will not use the settings in the
1233 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
1244 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
1234 user or to a trusted group, as various hgrc features allow arbitrary
1245 user or to a trusted group, as various hgrc features allow arbitrary
1235 commands to be run. This issue is often encountered when configuring
1246 commands to be run. This issue is often encountered when configuring
1236 hooks or extensions for shared repositories or servers. However,
1247 hooks or extensions for shared repositories or servers. However,
1237 the web interface will use some safe settings from the ``[web]``
1248 the web interface will use some safe settings from the ``[web]``
1238 section.
1249 section.
1239
1250
1240 This section specifies what users and groups are trusted. The
1251 This section specifies what users and groups are trusted. The
1241 current user is always trusted. To trust everybody, list a user or a
1252 current user is always trusted. To trust everybody, list a user or a
1242 group with name ``*``. These settings must be placed in an
1253 group with name ``*``. These settings must be placed in an
1243 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
1254 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
1244 user or service running Mercurial.
1255 user or service running Mercurial.
1245
1256
1246 ``users``
1257 ``users``
1247 Comma-separated list of trusted users.
1258 Comma-separated list of trusted users.
1248
1259
1249 ``groups``
1260 ``groups``
1250 Comma-separated list of trusted groups.
1261 Comma-separated list of trusted groups.
1251
1262
1252
1263
1253 ``ui``
1264 ``ui``
1254 ------
1265 ------
1255
1266
1256 User interface controls.
1267 User interface controls.
1257
1268
1258 ``archivemeta``
1269 ``archivemeta``
1259 Whether to include the .hg_archival.txt file containing meta data
1270 Whether to include the .hg_archival.txt file containing meta data
1260 (hashes for the repository base and for tip) in archives created
1271 (hashes for the repository base and for tip) in archives created
1261 by the :hg:`archive` command or downloaded via hgweb.
1272 by the :hg:`archive` command or downloaded via hgweb.
1262 Default is True.
1273 Default is True.
1263
1274
1264 ``askusername``
1275 ``askusername``
1265 Whether to prompt for a username when committing. If True, and
1276 Whether to prompt for a username when committing. If True, and
1266 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
1277 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
1267 be prompted to enter a username. If no username is entered, the
1278 be prompted to enter a username. If no username is entered, the
1268 default ``USER@HOST`` is used instead.
1279 default ``USER@HOST`` is used instead.
1269 Default is False.
1280 Default is False.
1270
1281
1271 ``commitsubrepos``
1282 ``commitsubrepos``
1272 Whether to commit modified subrepositories when committing the
1283 Whether to commit modified subrepositories when committing the
1273 parent repository. If False and one subrepository has uncommitted
1284 parent repository. If False and one subrepository has uncommitted
1274 changes, abort the commit.
1285 changes, abort the commit.
1275 Default is False.
1286 Default is False.
1276
1287
1277 ``debug``
1288 ``debug``
1278 Print debugging information. True or False. Default is False.
1289 Print debugging information. True or False. Default is False.
1279
1290
1280 ``editor``
1291 ``editor``
1281 The editor to use during a commit. Default is ``$EDITOR`` or ``vi``.
1292 The editor to use during a commit. Default is ``$EDITOR`` or ``vi``.
1282
1293
1283 ``fallbackencoding``
1294 ``fallbackencoding``
1284 Encoding to try if it's not possible to decode the changelog using
1295 Encoding to try if it's not possible to decode the changelog using
1285 UTF-8. Default is ISO-8859-1.
1296 UTF-8. Default is ISO-8859-1.
1286
1297
1287 ``ignore``
1298 ``ignore``
1288 A file to read per-user ignore patterns from. This file should be
1299 A file to read per-user ignore patterns from. This file should be
1289 in the same format as a repository-wide .hgignore file. This
1300 in the same format as a repository-wide .hgignore file. This
1290 option supports hook syntax, so if you want to specify multiple
1301 option supports hook syntax, so if you want to specify multiple
1291 ignore files, you can do so by setting something like
1302 ignore files, you can do so by setting something like
1292 ``ignore.other = ~/.hgignore2``. For details of the ignore file
1303 ``ignore.other = ~/.hgignore2``. For details of the ignore file
1293 format, see the ``hgignore(5)`` man page.
1304 format, see the ``hgignore(5)`` man page.
1294
1305
1295 ``interactive``
1306 ``interactive``
1296 Allow to prompt the user. True or False. Default is True.
1307 Allow to prompt the user. True or False. Default is True.
1297
1308
1298 ``logtemplate``
1309 ``logtemplate``
1299 Template string for commands that print changesets.
1310 Template string for commands that print changesets.
1300
1311
1301 ``merge``
1312 ``merge``
1302 The conflict resolution program to use during a manual merge.
1313 The conflict resolution program to use during a manual merge.
1303 For more information on merge tools see :hg:`help merge-tools`.
1314 For more information on merge tools see :hg:`help merge-tools`.
1304 For configuring merge tools see the ``[merge-tools]`` section.
1315 For configuring merge tools see the ``[merge-tools]`` section.
1305
1316
1306 ``mergemarkers``
1317 ``mergemarkers``
1307 Sets the merge conflict marker label styling. The ``detailed``
1318 Sets the merge conflict marker label styling. The ``detailed``
1308 style uses the ``mergemarkertemplate`` setting to style the labels.
1319 style uses the ``mergemarkertemplate`` setting to style the labels.
1309 The ``basic`` style just uses 'local' and 'other' as the marker label.
1320 The ``basic`` style just uses 'local' and 'other' as the marker label.
1310 One of ``basic`` or ``detailed``.
1321 One of ``basic`` or ``detailed``.
1311 Default is ``basic``.
1322 Default is ``basic``.
1312
1323
1313 ``mergemarkertemplate``
1324 ``mergemarkertemplate``
1314 The template used to print the commit description next to each conflict
1325 The template used to print the commit description next to each conflict
1315 marker during merge conflicts. See :hg:`help templates` for the template
1326 marker during merge conflicts. See :hg:`help templates` for the template
1316 format.
1327 format.
1317 Defaults to showing the hash, tags, branches, bookmarks, author, and
1328 Defaults to showing the hash, tags, branches, bookmarks, author, and
1318 the first line of the commit description.
1329 the first line of the commit description.
1319 You have to pay attention to encodings of managed files, if you
1330 You have to pay attention to encodings of managed files, if you
1320 use non-ASCII characters in tags, branches, bookmarks, author
1331 use non-ASCII characters in tags, branches, bookmarks, author
1321 and/or commit descriptions. At template expansion, non-ASCII
1332 and/or commit descriptions. At template expansion, non-ASCII
1322 characters use the encoding specified by ``--encoding`` global
1333 characters use the encoding specified by ``--encoding`` global
1323 option, ``HGENCODING`` or other locale setting environment
1334 option, ``HGENCODING`` or other locale setting environment
1324 variables. The difference of encoding between merged file and
1335 variables. The difference of encoding between merged file and
1325 conflict markers causes serious problem.
1336 conflict markers causes serious problem.
1326
1337
1327 ``portablefilenames``
1338 ``portablefilenames``
1328 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
1339 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
1329 Default is ``warn``.
1340 Default is ``warn``.
1330 If set to ``warn`` (or ``true``), a warning message is printed on POSIX
1341 If set to ``warn`` (or ``true``), a warning message is printed on POSIX
1331 platforms, if a file with a non-portable filename is added (e.g. a file
1342 platforms, if a file with a non-portable filename is added (e.g. a file
1332 with a name that can't be created on Windows because it contains reserved
1343 with a name that can't be created on Windows because it contains reserved
1333 parts like ``AUX``, reserved characters like ``:``, or would cause a case
1344 parts like ``AUX``, reserved characters like ``:``, or would cause a case
1334 collision with an existing file).
1345 collision with an existing file).
1335 If set to ``ignore`` (or ``false``), no warning is printed.
1346 If set to ``ignore`` (or ``false``), no warning is printed.
1336 If set to ``abort``, the command is aborted.
1347 If set to ``abort``, the command is aborted.
1337 On Windows, this configuration option is ignored and the command aborted.
1348 On Windows, this configuration option is ignored and the command aborted.
1338
1349
1339 ``quiet``
1350 ``quiet``
1340 Reduce the amount of output printed. True or False. Default is False.
1351 Reduce the amount of output printed. True or False. Default is False.
1341
1352
1342 ``remotecmd``
1353 ``remotecmd``
1343 remote command to use for clone/push/pull operations. Default is ``hg``.
1354 remote command to use for clone/push/pull operations. Default is ``hg``.
1344
1355
1345 ``reportoldssl``
1356 ``reportoldssl``
1346 Warn if an SSL certificate is unable to be due to using Python
1357 Warn if an SSL certificate is unable to be due to using Python
1347 2.5 or earlier. True or False. Default is True.
1358 2.5 or earlier. True or False. Default is True.
1348
1359
1349 ``report_untrusted``
1360 ``report_untrusted``
1350 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
1361 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
1351 trusted user or group. True or False. Default is True.
1362 trusted user or group. True or False. Default is True.
1352
1363
1353 ``slash``
1364 ``slash``
1354 Display paths using a slash (``/``) as the path separator. This
1365 Display paths using a slash (``/``) as the path separator. This
1355 only makes a difference on systems where the default path
1366 only makes a difference on systems where the default path
1356 separator is not the slash character (e.g. Windows uses the
1367 separator is not the slash character (e.g. Windows uses the
1357 backslash character (``\``)).
1368 backslash character (``\``)).
1358 Default is False.
1369 Default is False.
1359
1370
1360 ``ssh``
1371 ``ssh``
1361 command to use for SSH connections. Default is ``ssh``.
1372 command to use for SSH connections. Default is ``ssh``.
1362
1373
1363 ``strict``
1374 ``strict``
1364 Require exact command names, instead of allowing unambiguous
1375 Require exact command names, instead of allowing unambiguous
1365 abbreviations. True or False. Default is False.
1376 abbreviations. True or False. Default is False.
1366
1377
1367 ``style``
1378 ``style``
1368 Name of style to use for command output.
1379 Name of style to use for command output.
1369
1380
1370 ``timeout``
1381 ``timeout``
1371 The timeout used when a lock is held (in seconds), a negative value
1382 The timeout used when a lock is held (in seconds), a negative value
1372 means no timeout. Default is 600.
1383 means no timeout. Default is 600.
1373
1384
1374 ``traceback``
1385 ``traceback``
1375 Mercurial always prints a traceback when an unknown exception
1386 Mercurial always prints a traceback when an unknown exception
1376 occurs. Setting this to True will make Mercurial print a traceback
1387 occurs. Setting this to True will make Mercurial print a traceback
1377 on all exceptions, even those recognized by Mercurial (such as
1388 on all exceptions, even those recognized by Mercurial (such as
1378 IOError or MemoryError). Default is False.
1389 IOError or MemoryError). Default is False.
1379
1390
1380 ``username``
1391 ``username``
1381 The committer of a changeset created when running "commit".
1392 The committer of a changeset created when running "commit".
1382 Typically a person's name and email address, e.g. ``Fred Widget
1393 Typically a person's name and email address, e.g. ``Fred Widget
1383 <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. If
1394 <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. If
1384 the username in hgrc is empty, it has to be specified manually or
1395 the username in hgrc is empty, it has to be specified manually or
1385 in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set
1396 in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set
1386 ``username =`` in the system hgrc). Environment variables in the
1397 ``username =`` in the system hgrc). Environment variables in the
1387 username are expanded.
1398 username are expanded.
1388
1399
1389 ``verbose``
1400 ``verbose``
1390 Increase the amount of output printed. True or False. Default is False.
1401 Increase the amount of output printed. True or False. Default is False.
1391
1402
1392
1403
1393 ``web``
1404 ``web``
1394 -------
1405 -------
1395
1406
1396 Web interface configuration. The settings in this section apply to
1407 Web interface configuration. The settings in this section apply to
1397 both the builtin webserver (started by :hg:`serve`) and the script you
1408 both the builtin webserver (started by :hg:`serve`) and the script you
1398 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
1409 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
1399 and WSGI).
1410 and WSGI).
1400
1411
1401 The Mercurial webserver does no authentication (it does not prompt for
1412 The Mercurial webserver does no authentication (it does not prompt for
1402 usernames and passwords to validate *who* users are), but it does do
1413 usernames and passwords to validate *who* users are), but it does do
1403 authorization (it grants or denies access for *authenticated users*
1414 authorization (it grants or denies access for *authenticated users*
1404 based on settings in this section). You must either configure your
1415 based on settings in this section). You must either configure your
1405 webserver to do authentication for you, or disable the authorization
1416 webserver to do authentication for you, or disable the authorization
1406 checks.
1417 checks.
1407
1418
1408 For a quick setup in a trusted environment, e.g., a private LAN, where
1419 For a quick setup in a trusted environment, e.g., a private LAN, where
1409 you want it to accept pushes from anybody, you can use the following
1420 you want it to accept pushes from anybody, you can use the following
1410 command line::
1421 command line::
1411
1422
1412 $ hg --config web.allow_push=* --config web.push_ssl=False serve
1423 $ hg --config web.allow_push=* --config web.push_ssl=False serve
1413
1424
1414 Note that this will allow anybody to push anything to the server and
1425 Note that this will allow anybody to push anything to the server and
1415 that this should not be used for public servers.
1426 that this should not be used for public servers.
1416
1427
1417 The full set of options is:
1428 The full set of options is:
1418
1429
1419 ``accesslog``
1430 ``accesslog``
1420 Where to output the access log. Default is stdout.
1431 Where to output the access log. Default is stdout.
1421
1432
1422 ``address``
1433 ``address``
1423 Interface address to bind to. Default is all.
1434 Interface address to bind to. Default is all.
1424
1435
1425 ``allow_archive``
1436 ``allow_archive``
1426 List of archive format (bz2, gz, zip) allowed for downloading.
1437 List of archive format (bz2, gz, zip) allowed for downloading.
1427 Default is empty.
1438 Default is empty.
1428
1439
1429 ``allowbz2``
1440 ``allowbz2``
1430 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
1441 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
1431 revisions.
1442 revisions.
1432 Default is False.
1443 Default is False.
1433
1444
1434 ``allowgz``
1445 ``allowgz``
1435 (DEPRECATED) Whether to allow .tar.gz downloading of repository
1446 (DEPRECATED) Whether to allow .tar.gz downloading of repository
1436 revisions.
1447 revisions.
1437 Default is False.
1448 Default is False.
1438
1449
1439 ``allowpull``
1450 ``allowpull``
1440 Whether to allow pulling from the repository. Default is True.
1451 Whether to allow pulling from the repository. Default is True.
1441
1452
1442 ``allow_push``
1453 ``allow_push``
1443 Whether to allow pushing to the repository. If empty or not set,
1454 Whether to allow pushing to the repository. If empty or not set,
1444 push is not allowed. If the special value ``*``, any remote user can
1455 push is not allowed. If the special value ``*``, any remote user can
1445 push, including unauthenticated users. Otherwise, the remote user
1456 push, including unauthenticated users. Otherwise, the remote user
1446 must have been authenticated, and the authenticated user name must
1457 must have been authenticated, and the authenticated user name must
1447 be present in this list. The contents of the allow_push list are
1458 be present in this list. The contents of the allow_push list are
1448 examined after the deny_push list.
1459 examined after the deny_push list.
1449
1460
1450 ``allow_read``
1461 ``allow_read``
1451 If the user has not already been denied repository access due to
1462 If the user has not already been denied repository access due to
1452 the contents of deny_read, this list determines whether to grant
1463 the contents of deny_read, this list determines whether to grant
1453 repository access to the user. If this list is not empty, and the
1464 repository access to the user. If this list is not empty, and the
1454 user is unauthenticated or not present in the list, then access is
1465 user is unauthenticated or not present in the list, then access is
1455 denied for the user. If the list is empty or not set, then access
1466 denied for the user. If the list is empty or not set, then access
1456 is permitted to all users by default. Setting allow_read to the
1467 is permitted to all users by default. Setting allow_read to the
1457 special value ``*`` is equivalent to it not being set (i.e. access
1468 special value ``*`` is equivalent to it not being set (i.e. access
1458 is permitted to all users). The contents of the allow_read list are
1469 is permitted to all users). The contents of the allow_read list are
1459 examined after the deny_read list.
1470 examined after the deny_read list.
1460
1471
1461 ``allowzip``
1472 ``allowzip``
1462 (DEPRECATED) Whether to allow .zip downloading of repository
1473 (DEPRECATED) Whether to allow .zip downloading of repository
1463 revisions. Default is False. This feature creates temporary files.
1474 revisions. Default is False. This feature creates temporary files.
1464
1475
1465 ``archivesubrepos``
1476 ``archivesubrepos``
1466 Whether to recurse into subrepositories when archiving. Default is
1477 Whether to recurse into subrepositories when archiving. Default is
1467 False.
1478 False.
1468
1479
1469 ``baseurl``
1480 ``baseurl``
1470 Base URL to use when publishing URLs in other locations, so
1481 Base URL to use when publishing URLs in other locations, so
1471 third-party tools like email notification hooks can construct
1482 third-party tools like email notification hooks can construct
1472 URLs. Example: ``http://hgserver/repos/``.
1483 URLs. Example: ``http://hgserver/repos/``.
1473
1484
1474 ``cacerts``
1485 ``cacerts``
1475 Path to file containing a list of PEM encoded certificate
1486 Path to file containing a list of PEM encoded certificate
1476 authority certificates. Environment variables and ``~user``
1487 authority certificates. Environment variables and ``~user``
1477 constructs are expanded in the filename. If specified on the
1488 constructs are expanded in the filename. If specified on the
1478 client, then it will verify the identity of remote HTTPS servers
1489 client, then it will verify the identity of remote HTTPS servers
1479 with these certificates.
1490 with these certificates.
1480
1491
1481 This feature is only supported when using Python 2.6 or later. If you wish
1492 This feature is only supported when using Python 2.6 or later. If you wish
1482 to use it with earlier versions of Python, install the backported
1493 to use it with earlier versions of Python, install the backported
1483 version of the ssl library that is available from
1494 version of the ssl library that is available from
1484 ``http://pypi.python.org``.
1495 ``http://pypi.python.org``.
1485
1496
1486 To disable SSL verification temporarily, specify ``--insecure`` from
1497 To disable SSL verification temporarily, specify ``--insecure`` from
1487 command line.
1498 command line.
1488
1499
1489 You can use OpenSSL's CA certificate file if your platform has
1500 You can use OpenSSL's CA certificate file if your platform has
1490 one. On most Linux systems this will be
1501 one. On most Linux systems this will be
1491 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
1502 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
1492 generate this file manually. The form must be as follows::
1503 generate this file manually. The form must be as follows::
1493
1504
1494 -----BEGIN CERTIFICATE-----
1505 -----BEGIN CERTIFICATE-----
1495 ... (certificate in base64 PEM encoding) ...
1506 ... (certificate in base64 PEM encoding) ...
1496 -----END CERTIFICATE-----
1507 -----END CERTIFICATE-----
1497 -----BEGIN CERTIFICATE-----
1508 -----BEGIN CERTIFICATE-----
1498 ... (certificate in base64 PEM encoding) ...
1509 ... (certificate in base64 PEM encoding) ...
1499 -----END CERTIFICATE-----
1510 -----END CERTIFICATE-----
1500
1511
1501 ``cache``
1512 ``cache``
1502 Whether to support caching in hgweb. Defaults to True.
1513 Whether to support caching in hgweb. Defaults to True.
1503
1514
1504 ``collapse``
1515 ``collapse``
1505 With ``descend`` enabled, repositories in subdirectories are shown at
1516 With ``descend`` enabled, repositories in subdirectories are shown at
1506 a single level alongside repositories in the current path. With
1517 a single level alongside repositories in the current path. With
1507 ``collapse`` also enabled, repositories residing at a deeper level than
1518 ``collapse`` also enabled, repositories residing at a deeper level than
1508 the current path are grouped behind navigable directory entries that
1519 the current path are grouped behind navigable directory entries that
1509 lead to the locations of these repositories. In effect, this setting
1520 lead to the locations of these repositories. In effect, this setting
1510 collapses each collection of repositories found within a subdirectory
1521 collapses each collection of repositories found within a subdirectory
1511 into a single entry for that subdirectory. Default is False.
1522 into a single entry for that subdirectory. Default is False.
1512
1523
1513 ``comparisoncontext``
1524 ``comparisoncontext``
1514 Number of lines of context to show in side-by-side file comparison. If
1525 Number of lines of context to show in side-by-side file comparison. If
1515 negative or the value ``full``, whole files are shown. Default is 5.
1526 negative or the value ``full``, whole files are shown. Default is 5.
1516 This setting can be overridden by a ``context`` request parameter to the
1527 This setting can be overridden by a ``context`` request parameter to the
1517 ``comparison`` command, taking the same values.
1528 ``comparison`` command, taking the same values.
1518
1529
1519 ``contact``
1530 ``contact``
1520 Name or email address of the person in charge of the repository.
1531 Name or email address of the person in charge of the repository.
1521 Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
1532 Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
1522
1533
1523 ``deny_push``
1534 ``deny_push``
1524 Whether to deny pushing to the repository. If empty or not set,
1535 Whether to deny pushing to the repository. If empty or not set,
1525 push is not denied. If the special value ``*``, all remote users are
1536 push is not denied. If the special value ``*``, all remote users are
1526 denied push. Otherwise, unauthenticated users are all denied, and
1537 denied push. Otherwise, unauthenticated users are all denied, and
1527 any authenticated user name present in this list is also denied. The
1538 any authenticated user name present in this list is also denied. The
1528 contents of the deny_push list are examined before the allow_push list.
1539 contents of the deny_push list are examined before the allow_push list.
1529
1540
1530 ``deny_read``
1541 ``deny_read``
1531 Whether to deny reading/viewing of the repository. If this list is
1542 Whether to deny reading/viewing of the repository. If this list is
1532 not empty, unauthenticated users are all denied, and any
1543 not empty, unauthenticated users are all denied, and any
1533 authenticated user name present in this list is also denied access to
1544 authenticated user name present in this list is also denied access to
1534 the repository. If set to the special value ``*``, all remote users
1545 the repository. If set to the special value ``*``, all remote users
1535 are denied access (rarely needed ;). If deny_read is empty or not set,
1546 are denied access (rarely needed ;). If deny_read is empty or not set,
1536 the determination of repository access depends on the presence and
1547 the determination of repository access depends on the presence and
1537 content of the allow_read list (see description). If both
1548 content of the allow_read list (see description). If both
1538 deny_read and allow_read are empty or not set, then access is
1549 deny_read and allow_read are empty or not set, then access is
1539 permitted to all users by default. If the repository is being
1550 permitted to all users by default. If the repository is being
1540 served via hgwebdir, denied users will not be able to see it in
1551 served via hgwebdir, denied users will not be able to see it in
1541 the list of repositories. The contents of the deny_read list have
1552 the list of repositories. The contents of the deny_read list have
1542 priority over (are examined before) the contents of the allow_read
1553 priority over (are examined before) the contents of the allow_read
1543 list.
1554 list.
1544
1555
1545 ``descend``
1556 ``descend``
1546 hgwebdir indexes will not descend into subdirectories. Only repositories
1557 hgwebdir indexes will not descend into subdirectories. Only repositories
1547 directly in the current path will be shown (other repositories are still
1558 directly in the current path will be shown (other repositories are still
1548 available from the index corresponding to their containing path).
1559 available from the index corresponding to their containing path).
1549
1560
1550 ``description``
1561 ``description``
1551 Textual description of the repository's purpose or contents.
1562 Textual description of the repository's purpose or contents.
1552 Default is "unknown".
1563 Default is "unknown".
1553
1564
1554 ``encoding``
1565 ``encoding``
1555 Character encoding name. Default is the current locale charset.
1566 Character encoding name. Default is the current locale charset.
1556 Example: "UTF-8"
1567 Example: "UTF-8"
1557
1568
1558 ``errorlog``
1569 ``errorlog``
1559 Where to output the error log. Default is stderr.
1570 Where to output the error log. Default is stderr.
1560
1571
1561 ``guessmime``
1572 ``guessmime``
1562 Control MIME types for raw download of file content.
1573 Control MIME types for raw download of file content.
1563 Set to True to let hgweb guess the content type from the file
1574 Set to True to let hgweb guess the content type from the file
1564 extension. This will serve HTML files as ``text/html`` and might
1575 extension. This will serve HTML files as ``text/html`` and might
1565 allow cross-site scripting attacks when serving untrusted
1576 allow cross-site scripting attacks when serving untrusted
1566 repositories. Default is False.
1577 repositories. Default is False.
1567
1578
1568 ``hidden``
1579 ``hidden``
1569 Whether to hide the repository in the hgwebdir index.
1580 Whether to hide the repository in the hgwebdir index.
1570 Default is False.
1581 Default is False.
1571
1582
1572 ``ipv6``
1583 ``ipv6``
1573 Whether to use IPv6. Default is False.
1584 Whether to use IPv6. Default is False.
1574
1585
1575 ``logoimg``
1586 ``logoimg``
1576 File name of the logo image that some templates display on each page.
1587 File name of the logo image that some templates display on each page.
1577 The file name is relative to ``staticurl``. That is, the full path to
1588 The file name is relative to ``staticurl``. That is, the full path to
1578 the logo image is "staticurl/logoimg".
1589 the logo image is "staticurl/logoimg".
1579 If unset, ``hglogo.png`` will be used.
1590 If unset, ``hglogo.png`` will be used.
1580
1591
1581 ``logourl``
1592 ``logourl``
1582 Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``
1593 Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``
1583 will be used.
1594 will be used.
1584
1595
1585 ``maxchanges``
1596 ``maxchanges``
1586 Maximum number of changes to list on the changelog. Default is 10.
1597 Maximum number of changes to list on the changelog. Default is 10.
1587
1598
1588 ``maxfiles``
1599 ``maxfiles``
1589 Maximum number of files to list per changeset. Default is 10.
1600 Maximum number of files to list per changeset. Default is 10.
1590
1601
1591 ``maxshortchanges``
1602 ``maxshortchanges``
1592 Maximum number of changes to list on the shortlog, graph or filelog
1603 Maximum number of changes to list on the shortlog, graph or filelog
1593 pages. Default is 60.
1604 pages. Default is 60.
1594
1605
1595 ``name``
1606 ``name``
1596 Repository name to use in the web interface. Default is current
1607 Repository name to use in the web interface. Default is current
1597 working directory.
1608 working directory.
1598
1609
1599 ``port``
1610 ``port``
1600 Port to listen on. Default is 8000.
1611 Port to listen on. Default is 8000.
1601
1612
1602 ``prefix``
1613 ``prefix``
1603 Prefix path to serve from. Default is '' (server root).
1614 Prefix path to serve from. Default is '' (server root).
1604
1615
1605 ``push_ssl``
1616 ``push_ssl``
1606 Whether to require that inbound pushes be transported over SSL to
1617 Whether to require that inbound pushes be transported over SSL to
1607 prevent password sniffing. Default is True.
1618 prevent password sniffing. Default is True.
1608
1619
1609 ``staticurl``
1620 ``staticurl``
1610 Base URL to use for static files. If unset, static files (e.g. the
1621 Base URL to use for static files. If unset, static files (e.g. the
1611 hgicon.png favicon) will be served by the CGI script itself. Use
1622 hgicon.png favicon) will be served by the CGI script itself. Use
1612 this setting to serve them directly with the HTTP server.
1623 this setting to serve them directly with the HTTP server.
1613 Example: ``http://hgserver/static/``.
1624 Example: ``http://hgserver/static/``.
1614
1625
1615 ``stripes``
1626 ``stripes``
1616 How many lines a "zebra stripe" should span in multi-line output.
1627 How many lines a "zebra stripe" should span in multi-line output.
1617 Default is 1; set to 0 to disable.
1628 Default is 1; set to 0 to disable.
1618
1629
1619 ``style``
1630 ``style``
1620 Which template map style to use.
1631 Which template map style to use.
1621
1632
1622 ``templates``
1633 ``templates``
1623 Where to find the HTML templates. Default is install path.
1634 Where to find the HTML templates. Default is install path.
1624
1635
1625 ``websub``
1636 ``websub``
1626 ----------
1637 ----------
1627
1638
1628 Web substitution filter definition. You can use this section to
1639 Web substitution filter definition. You can use this section to
1629 define a set of regular expression substitution patterns which
1640 define a set of regular expression substitution patterns which
1630 let you automatically modify the hgweb server output.
1641 let you automatically modify the hgweb server output.
1631
1642
1632 The default hgweb templates only apply these substitution patterns
1643 The default hgweb templates only apply these substitution patterns
1633 on the revision description fields. You can apply them anywhere
1644 on the revision description fields. You can apply them anywhere
1634 you want when you create your own templates by adding calls to the
1645 you want when you create your own templates by adding calls to the
1635 "websub" filter (usually after calling the "escape" filter).
1646 "websub" filter (usually after calling the "escape" filter).
1636
1647
1637 This can be used, for example, to convert issue references to links
1648 This can be used, for example, to convert issue references to links
1638 to your issue tracker, or to convert "markdown-like" syntax into
1649 to your issue tracker, or to convert "markdown-like" syntax into
1639 HTML (see the examples below).
1650 HTML (see the examples below).
1640
1651
1641 Each entry in this section names a substitution filter.
1652 Each entry in this section names a substitution filter.
1642 The value of each entry defines the substitution expression itself.
1653 The value of each entry defines the substitution expression itself.
1643 The websub expressions follow the old interhg extension syntax,
1654 The websub expressions follow the old interhg extension syntax,
1644 which in turn imitates the Unix sed replacement syntax::
1655 which in turn imitates the Unix sed replacement syntax::
1645
1656
1646 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
1657 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
1647
1658
1648 You can use any separator other than "/". The final "i" is optional
1659 You can use any separator other than "/". The final "i" is optional
1649 and indicates that the search must be case insensitive.
1660 and indicates that the search must be case insensitive.
1650
1661
1651 Examples::
1662 Examples::
1652
1663
1653 [websub]
1664 [websub]
1654 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
1665 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
1655 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
1666 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
1656 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
1667 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
1657
1668
1658 ``worker``
1669 ``worker``
1659 ----------
1670 ----------
1660
1671
1661 Parallel master/worker configuration. We currently perform working
1672 Parallel master/worker configuration. We currently perform working
1662 directory updates in parallel on Unix-like systems, which greatly
1673 directory updates in parallel on Unix-like systems, which greatly
1663 helps performance.
1674 helps performance.
1664
1675
1665 ``numcpus``
1676 ``numcpus``
1666 Number of CPUs to use for parallel operations. Default is 4 or the
1677 Number of CPUs to use for parallel operations. Default is 4 or the
1667 number of CPUs on the system, whichever is larger. A zero or
1678 number of CPUs on the system, whichever is larger. A zero or
1668 negative value is treated as ``use the default``.
1679 negative value is treated as ``use the default``.
@@ -1,191 +1,193 b''
1 Environment setup for MQ
1 Environment setup for MQ
2
2
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "mq=" >> $HGRCPATH
4 $ echo "mq=" >> $HGRCPATH
5 $ hg init
5 $ hg init
6 $ hg qinit
6 $ hg qinit
7
7
8 Should fail if no patches applied
8 Should fail if no patches applied
9 (this tests also that editor is not invoked if '--edit' is not
9 (this tests also that editor is not invoked if '--edit' is not
10 specified)
10 specified)
11
11
12 $ hg qrefresh
12 $ hg qrefresh
13 no patches applied
13 no patches applied
14 [1]
14 [1]
15 $ hg qrefresh -e
15 $ hg qrefresh -e
16 no patches applied
16 no patches applied
17 [1]
17 [1]
18 $ hg qnew -m "First commit message" first-patch
18 $ hg qnew -m "First commit message" first-patch
19 $ echo aaaa > file
19 $ echo aaaa > file
20 $ hg add file
20 $ hg add file
21 $ HGEDITOR=cat hg qrefresh
21 $ HGEDITOR=cat hg qrefresh
22
22
23 Should display 'First commit message'
23 Should display 'First commit message'
24
24
25 $ hg log -l1 --template "{desc}\n"
25 $ hg log -l1 --template "{desc}\n"
26 First commit message
26 First commit message
27
27
28 Testing changing message with -m
28 Testing changing message with -m
29 (this tests also that '--edit' can be used with '--message', and
29 (this tests also that '--edit' can be used with '--message', and
30 that '[committemplate] changeset' definition and commit log specific
30 that '[committemplate] changeset' definition and commit log specific
31 template keyword 'extramsg' work well)
31 template keyword 'extramsg' work well)
32
32
33 $ cat >> .hg/hgrc <<EOF
33 $ cat >> .hg/hgrc <<EOF
34 > [committemplate]
34 > [committemplate]
35 > listupfiles = {file_adds %
36 > "HG: added {file}\n" }{file_mods %
37 > "HG: changed {file}\n" }{file_dels %
38 > "HG: removed {file}\n" }{if(files, "",
39 > "HG: no files changed\n")}
40 >
35 > changeset = HG: this is customized commit template
41 > changeset = HG: this is customized commit template
36 > {desc}\n\n
42 > {desc}\n\n
37 > HG: Enter commit message. Lines beginning with 'HG:' are removed.
43 > HG: Enter commit message. Lines beginning with 'HG:' are removed.
38 > HG: {extramsg}
44 > HG: {extramsg}
39 > HG: --
45 > HG: --
40 > HG: user: {author}
46 > HG: user: {author}
41 > HG: branch '{branch}'\n{file_adds %
47 > HG: branch '{branch}'\n{listupfiles}
42 > "HG: added {file}\n" }{file_mods %
43 > "HG: changed {file}\n" }{file_dels %
44 > "HG: removed {file}\n" }{if(files, "",
45 > "HG: no files changed\n")}
46 > EOF
48 > EOF
47
49
48 $ echo bbbb > file
50 $ echo bbbb > file
49 $ HGEDITOR=cat hg qrefresh -m "Second commit message" -e
51 $ HGEDITOR=cat hg qrefresh -m "Second commit message" -e
50 HG: this is customized commit template
52 HG: this is customized commit template
51 Second commit message
53 Second commit message
52
54
53
55
54 HG: Enter commit message. Lines beginning with 'HG:' are removed.
56 HG: Enter commit message. Lines beginning with 'HG:' are removed.
55 HG: Leave message empty to use default message.
57 HG: Leave message empty to use default message.
56 HG: --
58 HG: --
57 HG: user: test
59 HG: user: test
58 HG: branch 'default'
60 HG: branch 'default'
59 HG: added file
61 HG: added file
60
62
61 $ cat >> .hg/hgrc <<EOF
63 $ cat >> .hg/hgrc <<EOF
62 > # disable customizing for subsequent tests
64 > # disable customizing for subsequent tests
63 > [committemplate]
65 > [committemplate]
64 > changeset =
66 > changeset =
65 > EOF
67 > EOF
66
68
67 Should display 'Second commit message'
69 Should display 'Second commit message'
68
70
69 $ hg log -l1 --template "{desc}\n"
71 $ hg log -l1 --template "{desc}\n"
70 Second commit message
72 Second commit message
71
73
72 Testing changing message with -l
74 Testing changing message with -l
73
75
74 $ echo "Third commit message" > logfile
76 $ echo "Third commit message" > logfile
75 $ echo " This is the 3rd log message" >> logfile
77 $ echo " This is the 3rd log message" >> logfile
76 $ echo bbbb > file
78 $ echo bbbb > file
77 $ hg qrefresh -l logfile
79 $ hg qrefresh -l logfile
78
80
79 Should display 'Third commit message\\\n This is the 3rd log message'
81 Should display 'Third commit message\\\n This is the 3rd log message'
80
82
81 $ hg log -l1 --template "{desc}\n"
83 $ hg log -l1 --template "{desc}\n"
82 Third commit message
84 Third commit message
83 This is the 3rd log message
85 This is the 3rd log message
84
86
85 Testing changing message with -l-
87 Testing changing message with -l-
86
88
87 $ hg qnew -m "First commit message" second-patch
89 $ hg qnew -m "First commit message" second-patch
88 $ echo aaaa > file2
90 $ echo aaaa > file2
89 $ hg add file2
91 $ hg add file2
90 $ echo bbbb > file2
92 $ echo bbbb > file2
91 $ (echo "Fifth commit message"; echo " This is the 5th log message") | hg qrefresh -l-
93 $ (echo "Fifth commit message"; echo " This is the 5th log message") | hg qrefresh -l-
92
94
93 Should display 'Fifth commit message\\\n This is the 5th log message'
95 Should display 'Fifth commit message\\\n This is the 5th log message'
94
96
95 $ hg log -l1 --template "{desc}\n"
97 $ hg log -l1 --template "{desc}\n"
96 Fifth commit message
98 Fifth commit message
97 This is the 5th log message
99 This is the 5th log message
98
100
99 Test saving last-message.txt:
101 Test saving last-message.txt:
100
102
101 $ cat > $TESTTMP/editor.sh << EOF
103 $ cat > $TESTTMP/editor.sh << EOF
102 > echo "==== before editing"
104 > echo "==== before editing"
103 > cat \$1
105 > cat \$1
104 > echo "===="
106 > echo "===="
105 > (echo; echo "test saving last-message.txt") >> \$1
107 > (echo; echo "test saving last-message.txt") >> \$1
106 > EOF
108 > EOF
107
109
108 $ cat > $TESTTMP/commitfailure.py <<EOF
110 $ cat > $TESTTMP/commitfailure.py <<EOF
109 > from mercurial import util
111 > from mercurial import util
110 > def reposetup(ui, repo):
112 > def reposetup(ui, repo):
111 > class commitfailure(repo.__class__):
113 > class commitfailure(repo.__class__):
112 > def commit(self, *args, **kwargs):
114 > def commit(self, *args, **kwargs):
113 > raise util.Abort('emulating unexpected abort')
115 > raise util.Abort('emulating unexpected abort')
114 > repo.__class__ = commitfailure
116 > repo.__class__ = commitfailure
115 > EOF
117 > EOF
116
118
117 $ cat >> .hg/hgrc <<EOF
119 $ cat >> .hg/hgrc <<EOF
118 > [extensions]
120 > [extensions]
119 > # this failure occurs before editor invocation
121 > # this failure occurs before editor invocation
120 > commitfailure = $TESTTMP/commitfailure.py
122 > commitfailure = $TESTTMP/commitfailure.py
121 > EOF
123 > EOF
122
124
123 $ hg qapplied
125 $ hg qapplied
124 first-patch
126 first-patch
125 second-patch
127 second-patch
126 $ hg tip --template "{files}\n"
128 $ hg tip --template "{files}\n"
127 file2
129 file2
128
130
129 (test that editor is not invoked before transaction starting)
131 (test that editor is not invoked before transaction starting)
130
132
131 $ rm -f .hg/last-message.txt
133 $ rm -f .hg/last-message.txt
132 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qrefresh -e
134 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qrefresh -e
133 refresh interrupted while patch was popped! (revert --all, qpush to recover)
135 refresh interrupted while patch was popped! (revert --all, qpush to recover)
134 abort: emulating unexpected abort
136 abort: emulating unexpected abort
135 [255]
137 [255]
136 $ test -f .hg/last-message.txt
138 $ test -f .hg/last-message.txt
137 [1]
139 [1]
138
140
139 (reset applied patches and directory status)
141 (reset applied patches and directory status)
140
142
141 $ cat >> .hg/hgrc <<EOF
143 $ cat >> .hg/hgrc <<EOF
142 > [extensions]
144 > [extensions]
143 > commitfailure = !
145 > commitfailure = !
144 > EOF
146 > EOF
145
147
146 $ hg qapplied
148 $ hg qapplied
147 first-patch
149 first-patch
148 $ hg status -A file2
150 $ hg status -A file2
149 ? file2
151 ? file2
150 $ rm file2
152 $ rm file2
151 $ hg qpush -q second-patch
153 $ hg qpush -q second-patch
152 now at: second-patch
154 now at: second-patch
153
155
154 (test that editor is invoked and commit message is saved into
156 (test that editor is invoked and commit message is saved into
155 "last-message.txt")
157 "last-message.txt")
156
158
157 $ cat >> .hg/hgrc <<EOF
159 $ cat >> .hg/hgrc <<EOF
158 > [hooks]
160 > [hooks]
159 > # this failure occurs after editor invocation
161 > # this failure occurs after editor invocation
160 > pretxncommit.unexpectedabort = false
162 > pretxncommit.unexpectedabort = false
161 > EOF
163 > EOF
162
164
163 $ rm -f .hg/last-message.txt
165 $ rm -f .hg/last-message.txt
164 $ hg status --rev "second-patch^1" -arm
166 $ hg status --rev "second-patch^1" -arm
165 A file2
167 A file2
166 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qrefresh -e
168 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qrefresh -e
167 ==== before editing
169 ==== before editing
168 Fifth commit message
170 Fifth commit message
169 This is the 5th log message
171 This is the 5th log message
170
172
171
173
172 HG: Enter commit message. Lines beginning with 'HG:' are removed.
174 HG: Enter commit message. Lines beginning with 'HG:' are removed.
173 HG: Leave message empty to use default message.
175 HG: Leave message empty to use default message.
174 HG: --
176 HG: --
175 HG: user: test
177 HG: user: test
176 HG: branch 'default'
178 HG: branch 'default'
177 HG: added file2
179 HG: added file2
178 ====
180 ====
179 transaction abort!
181 transaction abort!
180 rollback completed
182 rollback completed
181 note: commit message saved in .hg/last-message.txt
183 note: commit message saved in .hg/last-message.txt
182 refresh interrupted while patch was popped! (revert --all, qpush to recover)
184 refresh interrupted while patch was popped! (revert --all, qpush to recover)
183 abort: pretxncommit.unexpectedabort hook exited with status 1
185 abort: pretxncommit.unexpectedabort hook exited with status 1
184 [255]
186 [255]
185 $ cat .hg/last-message.txt
187 $ cat .hg/last-message.txt
186 Fifth commit message
188 Fifth commit message
187 This is the 5th log message
189 This is the 5th log message
188
190
189
191
190
192
191 test saving last-message.txt
193 test saving last-message.txt
General Comments 0
You need to be logged in to leave comments. Login now