##// END OF EJS Templates
Add notes about diff/merge asymmetry to export, diff, and log
Matt Mackall -
r3822:28134d82 default
parent child Browse files
Show More
@@ -1,3146 +1,3164 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from demandload import demandload
8 from demandload import demandload
9 from node import *
9 from node import *
10 from i18n import gettext as _
10 from i18n import gettext as _
11 demandload(globals(), "bisect os re sys signal imp urllib pdb shlex stat")
11 demandload(globals(), "bisect os re sys signal imp urllib pdb shlex stat")
12 demandload(globals(), "fancyopts ui hg util lock revlog bundlerepo")
12 demandload(globals(), "fancyopts ui hg util lock revlog bundlerepo")
13 demandload(globals(), "difflib patch time help")
13 demandload(globals(), "difflib patch time help")
14 demandload(globals(), "traceback errno version atexit")
14 demandload(globals(), "traceback errno version atexit")
15 demandload(globals(), "archival changegroup cmdutil hgweb.server sshserver")
15 demandload(globals(), "archival changegroup cmdutil hgweb.server sshserver")
16
16
17 class UnknownCommand(Exception):
17 class UnknownCommand(Exception):
18 """Exception raised if command is not in the command table."""
18 """Exception raised if command is not in the command table."""
19 class AmbiguousCommand(Exception):
19 class AmbiguousCommand(Exception):
20 """Exception raised if command shortcut matches more than one command."""
20 """Exception raised if command shortcut matches more than one command."""
21
21
22 def bail_if_changed(repo):
22 def bail_if_changed(repo):
23 modified, added, removed, deleted = repo.status()[:4]
23 modified, added, removed, deleted = repo.status()[:4]
24 if modified or added or removed or deleted:
24 if modified or added or removed or deleted:
25 raise util.Abort(_("outstanding uncommitted changes"))
25 raise util.Abort(_("outstanding uncommitted changes"))
26
26
27 def logmessage(opts):
27 def logmessage(opts):
28 """ get the log message according to -m and -l option """
28 """ get the log message according to -m and -l option """
29 message = opts['message']
29 message = opts['message']
30 logfile = opts['logfile']
30 logfile = opts['logfile']
31
31
32 if message and logfile:
32 if message and logfile:
33 raise util.Abort(_('options --message and --logfile are mutually '
33 raise util.Abort(_('options --message and --logfile are mutually '
34 'exclusive'))
34 'exclusive'))
35 if not message and logfile:
35 if not message and logfile:
36 try:
36 try:
37 if logfile == '-':
37 if logfile == '-':
38 message = sys.stdin.read()
38 message = sys.stdin.read()
39 else:
39 else:
40 message = open(logfile).read()
40 message = open(logfile).read()
41 except IOError, inst:
41 except IOError, inst:
42 raise util.Abort(_("can't read commit message '%s': %s") %
42 raise util.Abort(_("can't read commit message '%s': %s") %
43 (logfile, inst.strerror))
43 (logfile, inst.strerror))
44 return message
44 return message
45
45
46 def setremoteconfig(ui, opts):
46 def setremoteconfig(ui, opts):
47 "copy remote options to ui tree"
47 "copy remote options to ui tree"
48 if opts.get('ssh'):
48 if opts.get('ssh'):
49 ui.setconfig("ui", "ssh", opts['ssh'])
49 ui.setconfig("ui", "ssh", opts['ssh'])
50 if opts.get('remotecmd'):
50 if opts.get('remotecmd'):
51 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
51 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
52
52
53 # Commands start here, listed alphabetically
53 # Commands start here, listed alphabetically
54
54
55 def add(ui, repo, *pats, **opts):
55 def add(ui, repo, *pats, **opts):
56 """add the specified files on the next commit
56 """add the specified files on the next commit
57
57
58 Schedule files to be version controlled and added to the repository.
58 Schedule files to be version controlled and added to the repository.
59
59
60 The files will be added to the repository at the next commit.
60 The files will be added to the repository at the next commit.
61
61
62 If no names are given, add all files in the repository.
62 If no names are given, add all files in the repository.
63 """
63 """
64
64
65 names = []
65 names = []
66 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
66 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
67 if exact:
67 if exact:
68 if ui.verbose:
68 if ui.verbose:
69 ui.status(_('adding %s\n') % rel)
69 ui.status(_('adding %s\n') % rel)
70 names.append(abs)
70 names.append(abs)
71 elif repo.dirstate.state(abs) == '?':
71 elif repo.dirstate.state(abs) == '?':
72 ui.status(_('adding %s\n') % rel)
72 ui.status(_('adding %s\n') % rel)
73 names.append(abs)
73 names.append(abs)
74 if not opts.get('dry_run'):
74 if not opts.get('dry_run'):
75 repo.add(names)
75 repo.add(names)
76
76
77 def addremove(ui, repo, *pats, **opts):
77 def addremove(ui, repo, *pats, **opts):
78 """add all new files, delete all missing files
78 """add all new files, delete all missing files
79
79
80 Add all new files and remove all missing files from the repository.
80 Add all new files and remove all missing files from the repository.
81
81
82 New files are ignored if they match any of the patterns in .hgignore. As
82 New files are ignored if they match any of the patterns in .hgignore. As
83 with add, these changes take effect at the next commit.
83 with add, these changes take effect at the next commit.
84
84
85 Use the -s option to detect renamed files. With a parameter > 0,
85 Use the -s option to detect renamed files. With a parameter > 0,
86 this compares every removed file with every added file and records
86 this compares every removed file with every added file and records
87 those similar enough as renames. This option takes a percentage
87 those similar enough as renames. This option takes a percentage
88 between 0 (disabled) and 100 (files must be identical) as its
88 between 0 (disabled) and 100 (files must be identical) as its
89 parameter. Detecting renamed files this way can be expensive.
89 parameter. Detecting renamed files this way can be expensive.
90 """
90 """
91 sim = float(opts.get('similarity') or 0)
91 sim = float(opts.get('similarity') or 0)
92 if sim < 0 or sim > 100:
92 if sim < 0 or sim > 100:
93 raise util.Abort(_('similarity must be between 0 and 100'))
93 raise util.Abort(_('similarity must be between 0 and 100'))
94 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
94 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
95
95
96 def annotate(ui, repo, *pats, **opts):
96 def annotate(ui, repo, *pats, **opts):
97 """show changeset information per file line
97 """show changeset information per file line
98
98
99 List changes in files, showing the revision id responsible for each line
99 List changes in files, showing the revision id responsible for each line
100
100
101 This command is useful to discover who did a change or when a change took
101 This command is useful to discover who did a change or when a change took
102 place.
102 place.
103
103
104 Without the -a option, annotate will avoid processing files it
104 Without the -a option, annotate will avoid processing files it
105 detects as binary. With -a, annotate will generate an annotation
105 detects as binary. With -a, annotate will generate an annotation
106 anyway, probably with undesirable results.
106 anyway, probably with undesirable results.
107 """
107 """
108 getdate = util.cachefunc(lambda x: util.datestr(x.date()))
108 getdate = util.cachefunc(lambda x: util.datestr(x.date()))
109
109
110 if not pats:
110 if not pats:
111 raise util.Abort(_('at least one file name or pattern required'))
111 raise util.Abort(_('at least one file name or pattern required'))
112
112
113 opmap = [['user', lambda x: ui.shortuser(x.user())],
113 opmap = [['user', lambda x: ui.shortuser(x.user())],
114 ['number', lambda x: str(x.rev())],
114 ['number', lambda x: str(x.rev())],
115 ['changeset', lambda x: short(x.node())],
115 ['changeset', lambda x: short(x.node())],
116 ['date', getdate], ['follow', lambda x: x.path()]]
116 ['date', getdate], ['follow', lambda x: x.path()]]
117 if (not opts['user'] and not opts['changeset'] and not opts['date']
117 if (not opts['user'] and not opts['changeset'] and not opts['date']
118 and not opts['follow']):
118 and not opts['follow']):
119 opts['number'] = 1
119 opts['number'] = 1
120
120
121 ctx = repo.changectx(opts['rev'])
121 ctx = repo.changectx(opts['rev'])
122
122
123 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
123 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
124 node=ctx.node()):
124 node=ctx.node()):
125 fctx = ctx.filectx(abs)
125 fctx = ctx.filectx(abs)
126 if not opts['text'] and util.binary(fctx.data()):
126 if not opts['text'] and util.binary(fctx.data()):
127 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
127 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
128 continue
128 continue
129
129
130 lines = fctx.annotate(follow=opts.get('follow'))
130 lines = fctx.annotate(follow=opts.get('follow'))
131 pieces = []
131 pieces = []
132
132
133 for o, f in opmap:
133 for o, f in opmap:
134 if opts[o]:
134 if opts[o]:
135 l = [f(n) for n, dummy in lines]
135 l = [f(n) for n, dummy in lines]
136 if l:
136 if l:
137 m = max(map(len, l))
137 m = max(map(len, l))
138 pieces.append(["%*s" % (m, x) for x in l])
138 pieces.append(["%*s" % (m, x) for x in l])
139
139
140 if pieces:
140 if pieces:
141 for p, l in zip(zip(*pieces), lines):
141 for p, l in zip(zip(*pieces), lines):
142 ui.write("%s: %s" % (" ".join(p), l[1]))
142 ui.write("%s: %s" % (" ".join(p), l[1]))
143
143
144 def archive(ui, repo, dest, **opts):
144 def archive(ui, repo, dest, **opts):
145 '''create unversioned archive of a repository revision
145 '''create unversioned archive of a repository revision
146
146
147 By default, the revision used is the parent of the working
147 By default, the revision used is the parent of the working
148 directory; use "-r" to specify a different revision.
148 directory; use "-r" to specify a different revision.
149
149
150 To specify the type of archive to create, use "-t". Valid
150 To specify the type of archive to create, use "-t". Valid
151 types are:
151 types are:
152
152
153 "files" (default): a directory full of files
153 "files" (default): a directory full of files
154 "tar": tar archive, uncompressed
154 "tar": tar archive, uncompressed
155 "tbz2": tar archive, compressed using bzip2
155 "tbz2": tar archive, compressed using bzip2
156 "tgz": tar archive, compressed using gzip
156 "tgz": tar archive, compressed using gzip
157 "uzip": zip archive, uncompressed
157 "uzip": zip archive, uncompressed
158 "zip": zip archive, compressed using deflate
158 "zip": zip archive, compressed using deflate
159
159
160 The exact name of the destination archive or directory is given
160 The exact name of the destination archive or directory is given
161 using a format string; see "hg help export" for details.
161 using a format string; see "hg help export" for details.
162
162
163 Each member added to an archive file has a directory prefix
163 Each member added to an archive file has a directory prefix
164 prepended. Use "-p" to specify a format string for the prefix.
164 prepended. Use "-p" to specify a format string for the prefix.
165 The default is the basename of the archive, with suffixes removed.
165 The default is the basename of the archive, with suffixes removed.
166 '''
166 '''
167
167
168 node = repo.changectx(opts['rev']).node()
168 node = repo.changectx(opts['rev']).node()
169 dest = cmdutil.make_filename(repo, dest, node)
169 dest = cmdutil.make_filename(repo, dest, node)
170 if os.path.realpath(dest) == repo.root:
170 if os.path.realpath(dest) == repo.root:
171 raise util.Abort(_('repository root cannot be destination'))
171 raise util.Abort(_('repository root cannot be destination'))
172 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
172 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
173 kind = opts.get('type') or 'files'
173 kind = opts.get('type') or 'files'
174 prefix = opts['prefix']
174 prefix = opts['prefix']
175 if dest == '-':
175 if dest == '-':
176 if kind == 'files':
176 if kind == 'files':
177 raise util.Abort(_('cannot archive plain files to stdout'))
177 raise util.Abort(_('cannot archive plain files to stdout'))
178 dest = sys.stdout
178 dest = sys.stdout
179 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
179 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
180 prefix = cmdutil.make_filename(repo, prefix, node)
180 prefix = cmdutil.make_filename(repo, prefix, node)
181 archival.archive(repo, dest, node, kind, not opts['no_decode'],
181 archival.archive(repo, dest, node, kind, not opts['no_decode'],
182 matchfn, prefix)
182 matchfn, prefix)
183
183
184 def backout(ui, repo, rev, **opts):
184 def backout(ui, repo, rev, **opts):
185 '''reverse effect of earlier changeset
185 '''reverse effect of earlier changeset
186
186
187 Commit the backed out changes as a new changeset. The new
187 Commit the backed out changes as a new changeset. The new
188 changeset is a child of the backed out changeset.
188 changeset is a child of the backed out changeset.
189
189
190 If you back out a changeset other than the tip, a new head is
190 If you back out a changeset other than the tip, a new head is
191 created. This head is the parent of the working directory. If
191 created. This head is the parent of the working directory. If
192 you back out an old changeset, your working directory will appear
192 you back out an old changeset, your working directory will appear
193 old after the backout. You should merge the backout changeset
193 old after the backout. You should merge the backout changeset
194 with another head.
194 with another head.
195
195
196 The --merge option remembers the parent of the working directory
196 The --merge option remembers the parent of the working directory
197 before starting the backout, then merges the new head with that
197 before starting the backout, then merges the new head with that
198 changeset afterwards. This saves you from doing the merge by
198 changeset afterwards. This saves you from doing the merge by
199 hand. The result of this merge is not committed, as for a normal
199 hand. The result of this merge is not committed, as for a normal
200 merge.'''
200 merge.'''
201
201
202 bail_if_changed(repo)
202 bail_if_changed(repo)
203 op1, op2 = repo.dirstate.parents()
203 op1, op2 = repo.dirstate.parents()
204 if op2 != nullid:
204 if op2 != nullid:
205 raise util.Abort(_('outstanding uncommitted merge'))
205 raise util.Abort(_('outstanding uncommitted merge'))
206 node = repo.lookup(rev)
206 node = repo.lookup(rev)
207 p1, p2 = repo.changelog.parents(node)
207 p1, p2 = repo.changelog.parents(node)
208 if p1 == nullid:
208 if p1 == nullid:
209 raise util.Abort(_('cannot back out a change with no parents'))
209 raise util.Abort(_('cannot back out a change with no parents'))
210 if p2 != nullid:
210 if p2 != nullid:
211 if not opts['parent']:
211 if not opts['parent']:
212 raise util.Abort(_('cannot back out a merge changeset without '
212 raise util.Abort(_('cannot back out a merge changeset without '
213 '--parent'))
213 '--parent'))
214 p = repo.lookup(opts['parent'])
214 p = repo.lookup(opts['parent'])
215 if p not in (p1, p2):
215 if p not in (p1, p2):
216 raise util.Abort(_('%s is not a parent of %s') %
216 raise util.Abort(_('%s is not a parent of %s') %
217 (short(p), short(node)))
217 (short(p), short(node)))
218 parent = p
218 parent = p
219 else:
219 else:
220 if opts['parent']:
220 if opts['parent']:
221 raise util.Abort(_('cannot use --parent on non-merge changeset'))
221 raise util.Abort(_('cannot use --parent on non-merge changeset'))
222 parent = p1
222 parent = p1
223 hg.clean(repo, node, show_stats=False)
223 hg.clean(repo, node, show_stats=False)
224 revert_opts = opts.copy()
224 revert_opts = opts.copy()
225 revert_opts['date'] = None
225 revert_opts['date'] = None
226 revert_opts['all'] = True
226 revert_opts['all'] = True
227 revert_opts['rev'] = hex(parent)
227 revert_opts['rev'] = hex(parent)
228 revert(ui, repo, **revert_opts)
228 revert(ui, repo, **revert_opts)
229 commit_opts = opts.copy()
229 commit_opts = opts.copy()
230 commit_opts['addremove'] = False
230 commit_opts['addremove'] = False
231 if not commit_opts['message'] and not commit_opts['logfile']:
231 if not commit_opts['message'] and not commit_opts['logfile']:
232 commit_opts['message'] = _("Backed out changeset %s") % (hex(node))
232 commit_opts['message'] = _("Backed out changeset %s") % (hex(node))
233 commit_opts['force_editor'] = True
233 commit_opts['force_editor'] = True
234 commit(ui, repo, **commit_opts)
234 commit(ui, repo, **commit_opts)
235 def nice(node):
235 def nice(node):
236 return '%d:%s' % (repo.changelog.rev(node), short(node))
236 return '%d:%s' % (repo.changelog.rev(node), short(node))
237 ui.status(_('changeset %s backs out changeset %s\n') %
237 ui.status(_('changeset %s backs out changeset %s\n') %
238 (nice(repo.changelog.tip()), nice(node)))
238 (nice(repo.changelog.tip()), nice(node)))
239 if op1 != node:
239 if op1 != node:
240 if opts['merge']:
240 if opts['merge']:
241 ui.status(_('merging with changeset %s\n') % nice(op1))
241 ui.status(_('merging with changeset %s\n') % nice(op1))
242 n = _lookup(repo, hex(op1))
242 n = _lookup(repo, hex(op1))
243 hg.merge(repo, n)
243 hg.merge(repo, n)
244 else:
244 else:
245 ui.status(_('the backout changeset is a new head - '
245 ui.status(_('the backout changeset is a new head - '
246 'do not forget to merge\n'))
246 'do not forget to merge\n'))
247 ui.status(_('(use "backout --merge" '
247 ui.status(_('(use "backout --merge" '
248 'if you want to auto-merge)\n'))
248 'if you want to auto-merge)\n'))
249
249
250 def branch(ui, repo, label=None):
250 def branch(ui, repo, label=None):
251 """set or show the current branch name
251 """set or show the current branch name
252
252
253 With <name>, set the current branch name. Otherwise, show the
253 With <name>, set the current branch name. Otherwise, show the
254 current branch name.
254 current branch name.
255 """
255 """
256
256
257 if label is not None:
257 if label is not None:
258 repo.opener("branch", "w").write(label)
258 repo.opener("branch", "w").write(label)
259 else:
259 else:
260 b = repo.workingctx().branch()
260 b = repo.workingctx().branch()
261 if b:
261 if b:
262 ui.write("%s\n" % b)
262 ui.write("%s\n" % b)
263
263
264 def branches(ui, repo):
264 def branches(ui, repo):
265 """list repository named branches
265 """list repository named branches
266
266
267 List the repository's named branches.
267 List the repository's named branches.
268 """
268 """
269 b = repo.branchtags()
269 b = repo.branchtags()
270 l = [(-repo.changelog.rev(n), n, t) for t, n in b.items()]
270 l = [(-repo.changelog.rev(n), n, t) for t, n in b.items()]
271 l.sort()
271 l.sort()
272 for r, n, t in l:
272 for r, n, t in l:
273 hexfunc = ui.debugflag and hex or short
273 hexfunc = ui.debugflag and hex or short
274 if ui.quiet:
274 if ui.quiet:
275 ui.write("%s\n" % t)
275 ui.write("%s\n" % t)
276 else:
276 else:
277 t = util.localsub(t, 30)
277 t = util.localsub(t, 30)
278 t += " " * (30 - util.locallen(t))
278 t += " " * (30 - util.locallen(t))
279 ui.write("%s %s:%s\n" % (t, -r, hexfunc(n)))
279 ui.write("%s %s:%s\n" % (t, -r, hexfunc(n)))
280
280
281 def bundle(ui, repo, fname, dest=None, **opts):
281 def bundle(ui, repo, fname, dest=None, **opts):
282 """create a changegroup file
282 """create a changegroup file
283
283
284 Generate a compressed changegroup file collecting changesets not
284 Generate a compressed changegroup file collecting changesets not
285 found in the other repository.
285 found in the other repository.
286
286
287 If no destination repository is specified the destination is assumed
287 If no destination repository is specified the destination is assumed
288 to have all the nodes specified by one or more --base parameters.
288 to have all the nodes specified by one or more --base parameters.
289
289
290 The bundle file can then be transferred using conventional means and
290 The bundle file can then be transferred using conventional means and
291 applied to another repository with the unbundle or pull command.
291 applied to another repository with the unbundle or pull command.
292 This is useful when direct push and pull are not available or when
292 This is useful when direct push and pull are not available or when
293 exporting an entire repository is undesirable.
293 exporting an entire repository is undesirable.
294
294
295 Applying bundles preserves all changeset contents including
295 Applying bundles preserves all changeset contents including
296 permissions, copy/rename information, and revision history.
296 permissions, copy/rename information, and revision history.
297 """
297 """
298 revs = opts.get('rev') or None
298 revs = opts.get('rev') or None
299 if revs:
299 if revs:
300 revs = [repo.lookup(rev) for rev in revs]
300 revs = [repo.lookup(rev) for rev in revs]
301 base = opts.get('base')
301 base = opts.get('base')
302 if base:
302 if base:
303 if dest:
303 if dest:
304 raise util.Abort(_("--base is incompatible with specifiying "
304 raise util.Abort(_("--base is incompatible with specifiying "
305 "a destination"))
305 "a destination"))
306 base = [repo.lookup(rev) for rev in base]
306 base = [repo.lookup(rev) for rev in base]
307 # create the right base
307 # create the right base
308 # XXX: nodesbetween / changegroup* should be "fixed" instead
308 # XXX: nodesbetween / changegroup* should be "fixed" instead
309 o = []
309 o = []
310 has = {nullid: None}
310 has = {nullid: None}
311 for n in base:
311 for n in base:
312 has.update(repo.changelog.reachable(n))
312 has.update(repo.changelog.reachable(n))
313 if revs:
313 if revs:
314 visit = list(revs)
314 visit = list(revs)
315 else:
315 else:
316 visit = repo.changelog.heads()
316 visit = repo.changelog.heads()
317 seen = {}
317 seen = {}
318 while visit:
318 while visit:
319 n = visit.pop(0)
319 n = visit.pop(0)
320 parents = [p for p in repo.changelog.parents(n) if p not in has]
320 parents = [p for p in repo.changelog.parents(n) if p not in has]
321 if len(parents) == 0:
321 if len(parents) == 0:
322 o.insert(0, n)
322 o.insert(0, n)
323 else:
323 else:
324 for p in parents:
324 for p in parents:
325 if p not in seen:
325 if p not in seen:
326 seen[p] = 1
326 seen[p] = 1
327 visit.append(p)
327 visit.append(p)
328 else:
328 else:
329 setremoteconfig(ui, opts)
329 setremoteconfig(ui, opts)
330 dest = ui.expandpath(dest or 'default-push', dest or 'default')
330 dest = ui.expandpath(dest or 'default-push', dest or 'default')
331 other = hg.repository(ui, dest)
331 other = hg.repository(ui, dest)
332 o = repo.findoutgoing(other, force=opts['force'])
332 o = repo.findoutgoing(other, force=opts['force'])
333
333
334 if revs:
334 if revs:
335 cg = repo.changegroupsubset(o, revs, 'bundle')
335 cg = repo.changegroupsubset(o, revs, 'bundle')
336 else:
336 else:
337 cg = repo.changegroup(o, 'bundle')
337 cg = repo.changegroup(o, 'bundle')
338 changegroup.writebundle(cg, fname, "HG10BZ")
338 changegroup.writebundle(cg, fname, "HG10BZ")
339
339
340 def cat(ui, repo, file1, *pats, **opts):
340 def cat(ui, repo, file1, *pats, **opts):
341 """output the latest or given revisions of files
341 """output the latest or given revisions of files
342
342
343 Print the specified files as they were at the given revision.
343 Print the specified files as they were at the given revision.
344 If no revision is given then working dir parent is used, or tip
344 If no revision is given then working dir parent is used, or tip
345 if no revision is checked out.
345 if no revision is checked out.
346
346
347 Output may be to a file, in which case the name of the file is
347 Output may be to a file, in which case the name of the file is
348 given using a format string. The formatting rules are the same as
348 given using a format string. The formatting rules are the same as
349 for the export command, with the following additions:
349 for the export command, with the following additions:
350
350
351 %s basename of file being printed
351 %s basename of file being printed
352 %d dirname of file being printed, or '.' if in repo root
352 %d dirname of file being printed, or '.' if in repo root
353 %p root-relative path name of file being printed
353 %p root-relative path name of file being printed
354 """
354 """
355 ctx = repo.changectx(opts['rev'])
355 ctx = repo.changectx(opts['rev'])
356 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
356 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
357 ctx.node()):
357 ctx.node()):
358 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
358 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
359 fp.write(ctx.filectx(abs).data())
359 fp.write(ctx.filectx(abs).data())
360
360
361 def clone(ui, source, dest=None, **opts):
361 def clone(ui, source, dest=None, **opts):
362 """make a copy of an existing repository
362 """make a copy of an existing repository
363
363
364 Create a copy of an existing repository in a new directory.
364 Create a copy of an existing repository in a new directory.
365
365
366 If no destination directory name is specified, it defaults to the
366 If no destination directory name is specified, it defaults to the
367 basename of the source.
367 basename of the source.
368
368
369 The location of the source is added to the new repository's
369 The location of the source is added to the new repository's
370 .hg/hgrc file, as the default to be used for future pulls.
370 .hg/hgrc file, as the default to be used for future pulls.
371
371
372 For efficiency, hardlinks are used for cloning whenever the source
372 For efficiency, hardlinks are used for cloning whenever the source
373 and destination are on the same filesystem (note this applies only
373 and destination are on the same filesystem (note this applies only
374 to the repository data, not to the checked out files). Some
374 to the repository data, not to the checked out files). Some
375 filesystems, such as AFS, implement hardlinking incorrectly, but
375 filesystems, such as AFS, implement hardlinking incorrectly, but
376 do not report errors. In these cases, use the --pull option to
376 do not report errors. In these cases, use the --pull option to
377 avoid hardlinking.
377 avoid hardlinking.
378
378
379 You can safely clone repositories and checked out files using full
379 You can safely clone repositories and checked out files using full
380 hardlinks with
380 hardlinks with
381
381
382 $ cp -al REPO REPOCLONE
382 $ cp -al REPO REPOCLONE
383
383
384 which is the fastest way to clone. However, the operation is not
384 which is the fastest way to clone. However, the operation is not
385 atomic (making sure REPO is not modified during the operation is
385 atomic (making sure REPO is not modified during the operation is
386 up to you) and you have to make sure your editor breaks hardlinks
386 up to you) and you have to make sure your editor breaks hardlinks
387 (Emacs and most Linux Kernel tools do so).
387 (Emacs and most Linux Kernel tools do so).
388
388
389 If you use the -r option to clone up to a specific revision, no
389 If you use the -r option to clone up to a specific revision, no
390 subsequent revisions will be present in the cloned repository.
390 subsequent revisions will be present in the cloned repository.
391 This option implies --pull, even on local repositories.
391 This option implies --pull, even on local repositories.
392
392
393 See pull for valid source format details.
393 See pull for valid source format details.
394
394
395 It is possible to specify an ssh:// URL as the destination, but no
395 It is possible to specify an ssh:// URL as the destination, but no
396 .hg/hgrc and working directory will be created on the remote side.
396 .hg/hgrc and working directory will be created on the remote side.
397 Look at the help text for the pull command for important details
397 Look at the help text for the pull command for important details
398 about ssh:// URLs.
398 about ssh:// URLs.
399 """
399 """
400 setremoteconfig(ui, opts)
400 setremoteconfig(ui, opts)
401 hg.clone(ui, ui.expandpath(source), dest,
401 hg.clone(ui, ui.expandpath(source), dest,
402 pull=opts['pull'],
402 pull=opts['pull'],
403 stream=opts['uncompressed'],
403 stream=opts['uncompressed'],
404 rev=opts['rev'],
404 rev=opts['rev'],
405 update=not opts['noupdate'])
405 update=not opts['noupdate'])
406
406
407 def commit(ui, repo, *pats, **opts):
407 def commit(ui, repo, *pats, **opts):
408 """commit the specified files or all outstanding changes
408 """commit the specified files or all outstanding changes
409
409
410 Commit changes to the given files into the repository.
410 Commit changes to the given files into the repository.
411
411
412 If a list of files is omitted, all changes reported by "hg status"
412 If a list of files is omitted, all changes reported by "hg status"
413 will be committed.
413 will be committed.
414
414
415 If no commit message is specified, the editor configured in your hgrc
415 If no commit message is specified, the editor configured in your hgrc
416 or in the EDITOR environment variable is started to enter a message.
416 or in the EDITOR environment variable is started to enter a message.
417 """
417 """
418 message = logmessage(opts)
418 message = logmessage(opts)
419
419
420 if opts['addremove']:
420 if opts['addremove']:
421 cmdutil.addremove(repo, pats, opts)
421 cmdutil.addremove(repo, pats, opts)
422 fns, match, anypats = cmdutil.matchpats(repo, pats, opts)
422 fns, match, anypats = cmdutil.matchpats(repo, pats, opts)
423 if pats:
423 if pats:
424 status = repo.status(files=fns, match=match)
424 status = repo.status(files=fns, match=match)
425 modified, added, removed, deleted, unknown = status[:5]
425 modified, added, removed, deleted, unknown = status[:5]
426 files = modified + added + removed
426 files = modified + added + removed
427 slist = None
427 slist = None
428 for f in fns:
428 for f in fns:
429 if f not in files:
429 if f not in files:
430 rf = repo.wjoin(f)
430 rf = repo.wjoin(f)
431 if f in unknown:
431 if f in unknown:
432 raise util.Abort(_("file %s not tracked!") % rf)
432 raise util.Abort(_("file %s not tracked!") % rf)
433 try:
433 try:
434 mode = os.lstat(rf)[stat.ST_MODE]
434 mode = os.lstat(rf)[stat.ST_MODE]
435 except OSError:
435 except OSError:
436 raise util.Abort(_("file %s not found!") % rf)
436 raise util.Abort(_("file %s not found!") % rf)
437 if stat.S_ISDIR(mode):
437 if stat.S_ISDIR(mode):
438 name = f + '/'
438 name = f + '/'
439 if slist is None:
439 if slist is None:
440 slist = list(files)
440 slist = list(files)
441 slist.sort()
441 slist.sort()
442 i = bisect.bisect(slist, name)
442 i = bisect.bisect(slist, name)
443 if i >= len(slist) or not slist[i].startswith(name):
443 if i >= len(slist) or not slist[i].startswith(name):
444 raise util.Abort(_("no match under directory %s!")
444 raise util.Abort(_("no match under directory %s!")
445 % rf)
445 % rf)
446 elif not stat.S_ISREG(mode):
446 elif not stat.S_ISREG(mode):
447 raise util.Abort(_("can't commit %s: "
447 raise util.Abort(_("can't commit %s: "
448 "unsupported file type!") % rf)
448 "unsupported file type!") % rf)
449 else:
449 else:
450 files = []
450 files = []
451 try:
451 try:
452 repo.commit(files, message, opts['user'], opts['date'], match,
452 repo.commit(files, message, opts['user'], opts['date'], match,
453 force_editor=opts.get('force_editor'))
453 force_editor=opts.get('force_editor'))
454 except ValueError, inst:
454 except ValueError, inst:
455 raise util.Abort(str(inst))
455 raise util.Abort(str(inst))
456
456
457 def docopy(ui, repo, pats, opts, wlock):
457 def docopy(ui, repo, pats, opts, wlock):
458 # called with the repo lock held
458 # called with the repo lock held
459 #
459 #
460 # hgsep => pathname that uses "/" to separate directories
460 # hgsep => pathname that uses "/" to separate directories
461 # ossep => pathname that uses os.sep to separate directories
461 # ossep => pathname that uses os.sep to separate directories
462 cwd = repo.getcwd()
462 cwd = repo.getcwd()
463 errors = 0
463 errors = 0
464 copied = []
464 copied = []
465 targets = {}
465 targets = {}
466
466
467 # abs: hgsep
467 # abs: hgsep
468 # rel: ossep
468 # rel: ossep
469 # return: hgsep
469 # return: hgsep
470 def okaytocopy(abs, rel, exact):
470 def okaytocopy(abs, rel, exact):
471 reasons = {'?': _('is not managed'),
471 reasons = {'?': _('is not managed'),
472 'a': _('has been marked for add'),
472 'a': _('has been marked for add'),
473 'r': _('has been marked for remove')}
473 'r': _('has been marked for remove')}
474 state = repo.dirstate.state(abs)
474 state = repo.dirstate.state(abs)
475 reason = reasons.get(state)
475 reason = reasons.get(state)
476 if reason:
476 if reason:
477 if state == 'a':
477 if state == 'a':
478 origsrc = repo.dirstate.copied(abs)
478 origsrc = repo.dirstate.copied(abs)
479 if origsrc is not None:
479 if origsrc is not None:
480 return origsrc
480 return origsrc
481 if exact:
481 if exact:
482 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
482 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
483 else:
483 else:
484 return abs
484 return abs
485
485
486 # origsrc: hgsep
486 # origsrc: hgsep
487 # abssrc: hgsep
487 # abssrc: hgsep
488 # relsrc: ossep
488 # relsrc: ossep
489 # target: ossep
489 # target: ossep
490 def copy(origsrc, abssrc, relsrc, target, exact):
490 def copy(origsrc, abssrc, relsrc, target, exact):
491 abstarget = util.canonpath(repo.root, cwd, target)
491 abstarget = util.canonpath(repo.root, cwd, target)
492 reltarget = util.pathto(cwd, abstarget)
492 reltarget = util.pathto(cwd, abstarget)
493 prevsrc = targets.get(abstarget)
493 prevsrc = targets.get(abstarget)
494 if prevsrc is not None:
494 if prevsrc is not None:
495 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
495 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
496 (reltarget, util.localpath(abssrc),
496 (reltarget, util.localpath(abssrc),
497 util.localpath(prevsrc)))
497 util.localpath(prevsrc)))
498 return
498 return
499 if (not opts['after'] and os.path.exists(reltarget) or
499 if (not opts['after'] and os.path.exists(reltarget) or
500 opts['after'] and repo.dirstate.state(abstarget) not in '?r'):
500 opts['after'] and repo.dirstate.state(abstarget) not in '?r'):
501 if not opts['force']:
501 if not opts['force']:
502 ui.warn(_('%s: not overwriting - file exists\n') %
502 ui.warn(_('%s: not overwriting - file exists\n') %
503 reltarget)
503 reltarget)
504 return
504 return
505 if not opts['after'] and not opts.get('dry_run'):
505 if not opts['after'] and not opts.get('dry_run'):
506 os.unlink(reltarget)
506 os.unlink(reltarget)
507 if opts['after']:
507 if opts['after']:
508 if not os.path.exists(reltarget):
508 if not os.path.exists(reltarget):
509 return
509 return
510 else:
510 else:
511 targetdir = os.path.dirname(reltarget) or '.'
511 targetdir = os.path.dirname(reltarget) or '.'
512 if not os.path.isdir(targetdir) and not opts.get('dry_run'):
512 if not os.path.isdir(targetdir) and not opts.get('dry_run'):
513 os.makedirs(targetdir)
513 os.makedirs(targetdir)
514 try:
514 try:
515 restore = repo.dirstate.state(abstarget) == 'r'
515 restore = repo.dirstate.state(abstarget) == 'r'
516 if restore and not opts.get('dry_run'):
516 if restore and not opts.get('dry_run'):
517 repo.undelete([abstarget], wlock)
517 repo.undelete([abstarget], wlock)
518 try:
518 try:
519 if not opts.get('dry_run'):
519 if not opts.get('dry_run'):
520 util.copyfile(relsrc, reltarget)
520 util.copyfile(relsrc, reltarget)
521 restore = False
521 restore = False
522 finally:
522 finally:
523 if restore:
523 if restore:
524 repo.remove([abstarget], wlock)
524 repo.remove([abstarget], wlock)
525 except IOError, inst:
525 except IOError, inst:
526 if inst.errno == errno.ENOENT:
526 if inst.errno == errno.ENOENT:
527 ui.warn(_('%s: deleted in working copy\n') % relsrc)
527 ui.warn(_('%s: deleted in working copy\n') % relsrc)
528 else:
528 else:
529 ui.warn(_('%s: cannot copy - %s\n') %
529 ui.warn(_('%s: cannot copy - %s\n') %
530 (relsrc, inst.strerror))
530 (relsrc, inst.strerror))
531 errors += 1
531 errors += 1
532 return
532 return
533 if ui.verbose or not exact:
533 if ui.verbose or not exact:
534 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
534 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
535 targets[abstarget] = abssrc
535 targets[abstarget] = abssrc
536 if abstarget != origsrc and not opts.get('dry_run'):
536 if abstarget != origsrc and not opts.get('dry_run'):
537 repo.copy(origsrc, abstarget, wlock)
537 repo.copy(origsrc, abstarget, wlock)
538 copied.append((abssrc, relsrc, exact))
538 copied.append((abssrc, relsrc, exact))
539
539
540 # pat: ossep
540 # pat: ossep
541 # dest ossep
541 # dest ossep
542 # srcs: list of (hgsep, hgsep, ossep, bool)
542 # srcs: list of (hgsep, hgsep, ossep, bool)
543 # return: function that takes hgsep and returns ossep
543 # return: function that takes hgsep and returns ossep
544 def targetpathfn(pat, dest, srcs):
544 def targetpathfn(pat, dest, srcs):
545 if os.path.isdir(pat):
545 if os.path.isdir(pat):
546 abspfx = util.canonpath(repo.root, cwd, pat)
546 abspfx = util.canonpath(repo.root, cwd, pat)
547 abspfx = util.localpath(abspfx)
547 abspfx = util.localpath(abspfx)
548 if destdirexists:
548 if destdirexists:
549 striplen = len(os.path.split(abspfx)[0])
549 striplen = len(os.path.split(abspfx)[0])
550 else:
550 else:
551 striplen = len(abspfx)
551 striplen = len(abspfx)
552 if striplen:
552 if striplen:
553 striplen += len(os.sep)
553 striplen += len(os.sep)
554 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
554 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
555 elif destdirexists:
555 elif destdirexists:
556 res = lambda p: os.path.join(dest,
556 res = lambda p: os.path.join(dest,
557 os.path.basename(util.localpath(p)))
557 os.path.basename(util.localpath(p)))
558 else:
558 else:
559 res = lambda p: dest
559 res = lambda p: dest
560 return res
560 return res
561
561
562 # pat: ossep
562 # pat: ossep
563 # dest ossep
563 # dest ossep
564 # srcs: list of (hgsep, hgsep, ossep, bool)
564 # srcs: list of (hgsep, hgsep, ossep, bool)
565 # return: function that takes hgsep and returns ossep
565 # return: function that takes hgsep and returns ossep
566 def targetpathafterfn(pat, dest, srcs):
566 def targetpathafterfn(pat, dest, srcs):
567 if util.patkind(pat, None)[0]:
567 if util.patkind(pat, None)[0]:
568 # a mercurial pattern
568 # a mercurial pattern
569 res = lambda p: os.path.join(dest,
569 res = lambda p: os.path.join(dest,
570 os.path.basename(util.localpath(p)))
570 os.path.basename(util.localpath(p)))
571 else:
571 else:
572 abspfx = util.canonpath(repo.root, cwd, pat)
572 abspfx = util.canonpath(repo.root, cwd, pat)
573 if len(abspfx) < len(srcs[0][0]):
573 if len(abspfx) < len(srcs[0][0]):
574 # A directory. Either the target path contains the last
574 # A directory. Either the target path contains the last
575 # component of the source path or it does not.
575 # component of the source path or it does not.
576 def evalpath(striplen):
576 def evalpath(striplen):
577 score = 0
577 score = 0
578 for s in srcs:
578 for s in srcs:
579 t = os.path.join(dest, util.localpath(s[0])[striplen:])
579 t = os.path.join(dest, util.localpath(s[0])[striplen:])
580 if os.path.exists(t):
580 if os.path.exists(t):
581 score += 1
581 score += 1
582 return score
582 return score
583
583
584 abspfx = util.localpath(abspfx)
584 abspfx = util.localpath(abspfx)
585 striplen = len(abspfx)
585 striplen = len(abspfx)
586 if striplen:
586 if striplen:
587 striplen += len(os.sep)
587 striplen += len(os.sep)
588 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
588 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
589 score = evalpath(striplen)
589 score = evalpath(striplen)
590 striplen1 = len(os.path.split(abspfx)[0])
590 striplen1 = len(os.path.split(abspfx)[0])
591 if striplen1:
591 if striplen1:
592 striplen1 += len(os.sep)
592 striplen1 += len(os.sep)
593 if evalpath(striplen1) > score:
593 if evalpath(striplen1) > score:
594 striplen = striplen1
594 striplen = striplen1
595 res = lambda p: os.path.join(dest,
595 res = lambda p: os.path.join(dest,
596 util.localpath(p)[striplen:])
596 util.localpath(p)[striplen:])
597 else:
597 else:
598 # a file
598 # a file
599 if destdirexists:
599 if destdirexists:
600 res = lambda p: os.path.join(dest,
600 res = lambda p: os.path.join(dest,
601 os.path.basename(util.localpath(p)))
601 os.path.basename(util.localpath(p)))
602 else:
602 else:
603 res = lambda p: dest
603 res = lambda p: dest
604 return res
604 return res
605
605
606
606
607 pats = list(pats)
607 pats = list(pats)
608 if not pats:
608 if not pats:
609 raise util.Abort(_('no source or destination specified'))
609 raise util.Abort(_('no source or destination specified'))
610 if len(pats) == 1:
610 if len(pats) == 1:
611 raise util.Abort(_('no destination specified'))
611 raise util.Abort(_('no destination specified'))
612 dest = pats.pop()
612 dest = pats.pop()
613 destdirexists = os.path.isdir(dest)
613 destdirexists = os.path.isdir(dest)
614 if (len(pats) > 1 or util.patkind(pats[0], None)[0]) and not destdirexists:
614 if (len(pats) > 1 or util.patkind(pats[0], None)[0]) and not destdirexists:
615 raise util.Abort(_('with multiple sources, destination must be an '
615 raise util.Abort(_('with multiple sources, destination must be an '
616 'existing directory'))
616 'existing directory'))
617 if opts['after']:
617 if opts['after']:
618 tfn = targetpathafterfn
618 tfn = targetpathafterfn
619 else:
619 else:
620 tfn = targetpathfn
620 tfn = targetpathfn
621 copylist = []
621 copylist = []
622 for pat in pats:
622 for pat in pats:
623 srcs = []
623 srcs = []
624 for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts):
624 for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts):
625 origsrc = okaytocopy(abssrc, relsrc, exact)
625 origsrc = okaytocopy(abssrc, relsrc, exact)
626 if origsrc:
626 if origsrc:
627 srcs.append((origsrc, abssrc, relsrc, exact))
627 srcs.append((origsrc, abssrc, relsrc, exact))
628 if not srcs:
628 if not srcs:
629 continue
629 continue
630 copylist.append((tfn(pat, dest, srcs), srcs))
630 copylist.append((tfn(pat, dest, srcs), srcs))
631 if not copylist:
631 if not copylist:
632 raise util.Abort(_('no files to copy'))
632 raise util.Abort(_('no files to copy'))
633
633
634 for targetpath, srcs in copylist:
634 for targetpath, srcs in copylist:
635 for origsrc, abssrc, relsrc, exact in srcs:
635 for origsrc, abssrc, relsrc, exact in srcs:
636 copy(origsrc, abssrc, relsrc, targetpath(abssrc), exact)
636 copy(origsrc, abssrc, relsrc, targetpath(abssrc), exact)
637
637
638 if errors:
638 if errors:
639 ui.warn(_('(consider using --after)\n'))
639 ui.warn(_('(consider using --after)\n'))
640 return errors, copied
640 return errors, copied
641
641
642 def copy(ui, repo, *pats, **opts):
642 def copy(ui, repo, *pats, **opts):
643 """mark files as copied for the next commit
643 """mark files as copied for the next commit
644
644
645 Mark dest as having copies of source files. If dest is a
645 Mark dest as having copies of source files. If dest is a
646 directory, copies are put in that directory. If dest is a file,
646 directory, copies are put in that directory. If dest is a file,
647 there can only be one source.
647 there can only be one source.
648
648
649 By default, this command copies the contents of files as they
649 By default, this command copies the contents of files as they
650 stand in the working directory. If invoked with --after, the
650 stand in the working directory. If invoked with --after, the
651 operation is recorded, but no copying is performed.
651 operation is recorded, but no copying is performed.
652
652
653 This command takes effect in the next commit.
653 This command takes effect in the next commit.
654 """
654 """
655 wlock = repo.wlock(0)
655 wlock = repo.wlock(0)
656 errs, copied = docopy(ui, repo, pats, opts, wlock)
656 errs, copied = docopy(ui, repo, pats, opts, wlock)
657 return errs
657 return errs
658
658
659 def debugancestor(ui, index, rev1, rev2):
659 def debugancestor(ui, index, rev1, rev2):
660 """find the ancestor revision of two revisions in a given index"""
660 """find the ancestor revision of two revisions in a given index"""
661 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index, "", 0)
661 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index, "", 0)
662 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
662 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
663 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
663 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
664
664
665 def debugcomplete(ui, cmd='', **opts):
665 def debugcomplete(ui, cmd='', **opts):
666 """returns the completion list associated with the given command"""
666 """returns the completion list associated with the given command"""
667
667
668 if opts['options']:
668 if opts['options']:
669 options = []
669 options = []
670 otables = [globalopts]
670 otables = [globalopts]
671 if cmd:
671 if cmd:
672 aliases, entry = findcmd(ui, cmd)
672 aliases, entry = findcmd(ui, cmd)
673 otables.append(entry[1])
673 otables.append(entry[1])
674 for t in otables:
674 for t in otables:
675 for o in t:
675 for o in t:
676 if o[0]:
676 if o[0]:
677 options.append('-%s' % o[0])
677 options.append('-%s' % o[0])
678 options.append('--%s' % o[1])
678 options.append('--%s' % o[1])
679 ui.write("%s\n" % "\n".join(options))
679 ui.write("%s\n" % "\n".join(options))
680 return
680 return
681
681
682 clist = findpossible(ui, cmd).keys()
682 clist = findpossible(ui, cmd).keys()
683 clist.sort()
683 clist.sort()
684 ui.write("%s\n" % "\n".join(clist))
684 ui.write("%s\n" % "\n".join(clist))
685
685
686 def debugrebuildstate(ui, repo, rev=None):
686 def debugrebuildstate(ui, repo, rev=None):
687 """rebuild the dirstate as it would look like for the given revision"""
687 """rebuild the dirstate as it would look like for the given revision"""
688 if not rev:
688 if not rev:
689 rev = repo.changelog.tip()
689 rev = repo.changelog.tip()
690 else:
690 else:
691 rev = repo.lookup(rev)
691 rev = repo.lookup(rev)
692 change = repo.changelog.read(rev)
692 change = repo.changelog.read(rev)
693 n = change[0]
693 n = change[0]
694 files = repo.manifest.read(n)
694 files = repo.manifest.read(n)
695 wlock = repo.wlock()
695 wlock = repo.wlock()
696 repo.dirstate.rebuild(rev, files)
696 repo.dirstate.rebuild(rev, files)
697
697
698 def debugcheckstate(ui, repo):
698 def debugcheckstate(ui, repo):
699 """validate the correctness of the current dirstate"""
699 """validate the correctness of the current dirstate"""
700 parent1, parent2 = repo.dirstate.parents()
700 parent1, parent2 = repo.dirstate.parents()
701 repo.dirstate.read()
701 repo.dirstate.read()
702 dc = repo.dirstate.map
702 dc = repo.dirstate.map
703 keys = dc.keys()
703 keys = dc.keys()
704 keys.sort()
704 keys.sort()
705 m1n = repo.changelog.read(parent1)[0]
705 m1n = repo.changelog.read(parent1)[0]
706 m2n = repo.changelog.read(parent2)[0]
706 m2n = repo.changelog.read(parent2)[0]
707 m1 = repo.manifest.read(m1n)
707 m1 = repo.manifest.read(m1n)
708 m2 = repo.manifest.read(m2n)
708 m2 = repo.manifest.read(m2n)
709 errors = 0
709 errors = 0
710 for f in dc:
710 for f in dc:
711 state = repo.dirstate.state(f)
711 state = repo.dirstate.state(f)
712 if state in "nr" and f not in m1:
712 if state in "nr" and f not in m1:
713 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
713 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
714 errors += 1
714 errors += 1
715 if state in "a" and f in m1:
715 if state in "a" and f in m1:
716 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
716 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
717 errors += 1
717 errors += 1
718 if state in "m" and f not in m1 and f not in m2:
718 if state in "m" and f not in m1 and f not in m2:
719 ui.warn(_("%s in state %s, but not in either manifest\n") %
719 ui.warn(_("%s in state %s, but not in either manifest\n") %
720 (f, state))
720 (f, state))
721 errors += 1
721 errors += 1
722 for f in m1:
722 for f in m1:
723 state = repo.dirstate.state(f)
723 state = repo.dirstate.state(f)
724 if state not in "nrm":
724 if state not in "nrm":
725 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
725 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
726 errors += 1
726 errors += 1
727 if errors:
727 if errors:
728 error = _(".hg/dirstate inconsistent with current parent's manifest")
728 error = _(".hg/dirstate inconsistent with current parent's manifest")
729 raise util.Abort(error)
729 raise util.Abort(error)
730
730
731 def showconfig(ui, repo, *values, **opts):
731 def showconfig(ui, repo, *values, **opts):
732 """show combined config settings from all hgrc files
732 """show combined config settings from all hgrc files
733
733
734 With no args, print names and values of all config items.
734 With no args, print names and values of all config items.
735
735
736 With one arg of the form section.name, print just the value of
736 With one arg of the form section.name, print just the value of
737 that config item.
737 that config item.
738
738
739 With multiple args, print names and values of all config items
739 With multiple args, print names and values of all config items
740 with matching section names."""
740 with matching section names."""
741
741
742 untrusted = bool(opts.get('untrusted'))
742 untrusted = bool(opts.get('untrusted'))
743 if values:
743 if values:
744 if len([v for v in values if '.' in v]) > 1:
744 if len([v for v in values if '.' in v]) > 1:
745 raise util.Abort(_('only one config item permitted'))
745 raise util.Abort(_('only one config item permitted'))
746 for section, name, value in ui.walkconfig(untrusted=untrusted):
746 for section, name, value in ui.walkconfig(untrusted=untrusted):
747 sectname = section + '.' + name
747 sectname = section + '.' + name
748 if values:
748 if values:
749 for v in values:
749 for v in values:
750 if v == section:
750 if v == section:
751 ui.write('%s=%s\n' % (sectname, value))
751 ui.write('%s=%s\n' % (sectname, value))
752 elif v == sectname:
752 elif v == sectname:
753 ui.write(value, '\n')
753 ui.write(value, '\n')
754 else:
754 else:
755 ui.write('%s=%s\n' % (sectname, value))
755 ui.write('%s=%s\n' % (sectname, value))
756
756
757 def debugsetparents(ui, repo, rev1, rev2=None):
757 def debugsetparents(ui, repo, rev1, rev2=None):
758 """manually set the parents of the current working directory
758 """manually set the parents of the current working directory
759
759
760 This is useful for writing repository conversion tools, but should
760 This is useful for writing repository conversion tools, but should
761 be used with care.
761 be used with care.
762 """
762 """
763
763
764 if not rev2:
764 if not rev2:
765 rev2 = hex(nullid)
765 rev2 = hex(nullid)
766
766
767 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
767 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
768
768
769 def debugstate(ui, repo):
769 def debugstate(ui, repo):
770 """show the contents of the current dirstate"""
770 """show the contents of the current dirstate"""
771 repo.dirstate.read()
771 repo.dirstate.read()
772 dc = repo.dirstate.map
772 dc = repo.dirstate.map
773 keys = dc.keys()
773 keys = dc.keys()
774 keys.sort()
774 keys.sort()
775 for file_ in keys:
775 for file_ in keys:
776 ui.write("%c %3o %10d %s %s\n"
776 ui.write("%c %3o %10d %s %s\n"
777 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
777 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
778 time.strftime("%x %X",
778 time.strftime("%x %X",
779 time.localtime(dc[file_][3])), file_))
779 time.localtime(dc[file_][3])), file_))
780 for f in repo.dirstate.copies():
780 for f in repo.dirstate.copies():
781 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
781 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
782
782
783 def debugdata(ui, file_, rev):
783 def debugdata(ui, file_, rev):
784 """dump the contents of an data file revision"""
784 """dump the contents of an data file revision"""
785 r = revlog.revlog(util.opener(os.getcwd(), audit=False),
785 r = revlog.revlog(util.opener(os.getcwd(), audit=False),
786 file_[:-2] + ".i", file_, 0)
786 file_[:-2] + ".i", file_, 0)
787 try:
787 try:
788 ui.write(r.revision(r.lookup(rev)))
788 ui.write(r.revision(r.lookup(rev)))
789 except KeyError:
789 except KeyError:
790 raise util.Abort(_('invalid revision identifier %s') % rev)
790 raise util.Abort(_('invalid revision identifier %s') % rev)
791
791
792 def debugdate(ui, date, range=None, **opts):
792 def debugdate(ui, date, range=None, **opts):
793 """parse and display a date"""
793 """parse and display a date"""
794 if opts["extended"]:
794 if opts["extended"]:
795 d = util.parsedate(date, util.extendeddateformats)
795 d = util.parsedate(date, util.extendeddateformats)
796 else:
796 else:
797 d = util.parsedate(date)
797 d = util.parsedate(date)
798 ui.write("internal: %s %s\n" % d)
798 ui.write("internal: %s %s\n" % d)
799 ui.write("standard: %s\n" % util.datestr(d))
799 ui.write("standard: %s\n" % util.datestr(d))
800 if range:
800 if range:
801 m = util.matchdate(range)
801 m = util.matchdate(range)
802 ui.write("match: %s\n" % m(d[0]))
802 ui.write("match: %s\n" % m(d[0]))
803
803
804 def debugindex(ui, file_):
804 def debugindex(ui, file_):
805 """dump the contents of an index file"""
805 """dump the contents of an index file"""
806 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
806 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
807 ui.write(" rev offset length base linkrev" +
807 ui.write(" rev offset length base linkrev" +
808 " nodeid p1 p2\n")
808 " nodeid p1 p2\n")
809 for i in xrange(r.count()):
809 for i in xrange(r.count()):
810 node = r.node(i)
810 node = r.node(i)
811 pp = r.parents(node)
811 pp = r.parents(node)
812 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
812 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
813 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
813 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
814 short(node), short(pp[0]), short(pp[1])))
814 short(node), short(pp[0]), short(pp[1])))
815
815
816 def debugindexdot(ui, file_):
816 def debugindexdot(ui, file_):
817 """dump an index DAG as a .dot file"""
817 """dump an index DAG as a .dot file"""
818 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
818 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
819 ui.write("digraph G {\n")
819 ui.write("digraph G {\n")
820 for i in xrange(r.count()):
820 for i in xrange(r.count()):
821 node = r.node(i)
821 node = r.node(i)
822 pp = r.parents(node)
822 pp = r.parents(node)
823 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
823 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
824 if pp[1] != nullid:
824 if pp[1] != nullid:
825 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
825 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
826 ui.write("}\n")
826 ui.write("}\n")
827
827
828 def debugrename(ui, repo, file1, *pats, **opts):
828 def debugrename(ui, repo, file1, *pats, **opts):
829 """dump rename information"""
829 """dump rename information"""
830
830
831 ctx = repo.changectx(opts.get('rev', 'tip'))
831 ctx = repo.changectx(opts.get('rev', 'tip'))
832 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
832 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
833 ctx.node()):
833 ctx.node()):
834 m = ctx.filectx(abs).renamed()
834 m = ctx.filectx(abs).renamed()
835 if m:
835 if m:
836 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
836 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
837 else:
837 else:
838 ui.write(_("%s not renamed\n") % rel)
838 ui.write(_("%s not renamed\n") % rel)
839
839
840 def debugwalk(ui, repo, *pats, **opts):
840 def debugwalk(ui, repo, *pats, **opts):
841 """show how files match on given patterns"""
841 """show how files match on given patterns"""
842 items = list(cmdutil.walk(repo, pats, opts))
842 items = list(cmdutil.walk(repo, pats, opts))
843 if not items:
843 if not items:
844 return
844 return
845 fmt = '%%s %%-%ds %%-%ds %%s' % (
845 fmt = '%%s %%-%ds %%-%ds %%s' % (
846 max([len(abs) for (src, abs, rel, exact) in items]),
846 max([len(abs) for (src, abs, rel, exact) in items]),
847 max([len(rel) for (src, abs, rel, exact) in items]))
847 max([len(rel) for (src, abs, rel, exact) in items]))
848 for src, abs, rel, exact in items:
848 for src, abs, rel, exact in items:
849 line = fmt % (src, abs, rel, exact and 'exact' or '')
849 line = fmt % (src, abs, rel, exact and 'exact' or '')
850 ui.write("%s\n" % line.rstrip())
850 ui.write("%s\n" % line.rstrip())
851
851
852 def diff(ui, repo, *pats, **opts):
852 def diff(ui, repo, *pats, **opts):
853 """diff repository (or selected files)
853 """diff repository (or selected files)
854
854
855 Show differences between revisions for the specified files.
855 Show differences between revisions for the specified files.
856
856
857 Differences between files are shown using the unified diff format.
857 Differences between files are shown using the unified diff format.
858
858
859 NOTE: diff may generate unexpected results for merges, as it will
860 default to comparing against the working directory's first parent
861 changeset if no revisions are specified.
862
859 When two revision arguments are given, then changes are shown
863 When two revision arguments are given, then changes are shown
860 between those revisions. If only one revision is specified then
864 between those revisions. If only one revision is specified then
861 that revision is compared to the working directory, and, when no
865 that revision is compared to the working directory, and, when no
862 revisions are specified, the working directory files are compared
866 revisions are specified, the working directory files are compared
863 to its parent.
867 to its parent.
864
868
865 Without the -a option, diff will avoid generating diffs of files
869 Without the -a option, diff will avoid generating diffs of files
866 it detects as binary. With -a, diff will generate a diff anyway,
870 it detects as binary. With -a, diff will generate a diff anyway,
867 probably with undesirable results.
871 probably with undesirable results.
868 """
872 """
869 node1, node2 = cmdutil.revpair(repo, opts['rev'])
873 node1, node2 = cmdutil.revpair(repo, opts['rev'])
870
874
871 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
875 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
872
876
873 patch.diff(repo, node1, node2, fns, match=matchfn,
877 patch.diff(repo, node1, node2, fns, match=matchfn,
874 opts=patch.diffopts(ui, opts))
878 opts=patch.diffopts(ui, opts))
875
879
876 def export(ui, repo, *changesets, **opts):
880 def export(ui, repo, *changesets, **opts):
877 """dump the header and diffs for one or more changesets
881 """dump the header and diffs for one or more changesets
878
882
879 Print the changeset header and diffs for one or more revisions.
883 Print the changeset header and diffs for one or more revisions.
880
884
881 The information shown in the changeset header is: author,
885 The information shown in the changeset header is: author,
882 changeset hash, parent and commit comment.
886 changeset hash, parent(s) and commit comment.
887
888 NOTE: export may generate unexpected diff output for merge changesets,
889 as it will compare the merge changeset against its first parent only.
883
890
884 Output may be to a file, in which case the name of the file is
891 Output may be to a file, in which case the name of the file is
885 given using a format string. The formatting rules are as follows:
892 given using a format string. The formatting rules are as follows:
886
893
887 %% literal "%" character
894 %% literal "%" character
888 %H changeset hash (40 bytes of hexadecimal)
895 %H changeset hash (40 bytes of hexadecimal)
889 %N number of patches being generated
896 %N number of patches being generated
890 %R changeset revision number
897 %R changeset revision number
891 %b basename of the exporting repository
898 %b basename of the exporting repository
892 %h short-form changeset hash (12 bytes of hexadecimal)
899 %h short-form changeset hash (12 bytes of hexadecimal)
893 %n zero-padded sequence number, starting at 1
900 %n zero-padded sequence number, starting at 1
894 %r zero-padded changeset revision number
901 %r zero-padded changeset revision number
895
902
896 Without the -a option, export will avoid generating diffs of files
903 Without the -a option, export will avoid generating diffs of files
897 it detects as binary. With -a, export will generate a diff anyway,
904 it detects as binary. With -a, export will generate a diff anyway,
898 probably with undesirable results.
905 probably with undesirable results.
899
906
900 With the --switch-parent option, the diff will be against the second
907 With the --switch-parent option, the diff will be against the second
901 parent. It can be useful to review a merge.
908 parent. It can be useful to review a merge.
902 """
909 """
903 if not changesets:
910 if not changesets:
904 raise util.Abort(_("export requires at least one changeset"))
911 raise util.Abort(_("export requires at least one changeset"))
905 revs = cmdutil.revrange(repo, changesets)
912 revs = cmdutil.revrange(repo, changesets)
906 if len(revs) > 1:
913 if len(revs) > 1:
907 ui.note(_('exporting patches:\n'))
914 ui.note(_('exporting patches:\n'))
908 else:
915 else:
909 ui.note(_('exporting patch:\n'))
916 ui.note(_('exporting patch:\n'))
910 patch.export(repo, map(repo.lookup, revs), template=opts['output'],
917 patch.export(repo, map(repo.lookup, revs), template=opts['output'],
911 switch_parent=opts['switch_parent'],
918 switch_parent=opts['switch_parent'],
912 opts=patch.diffopts(ui, opts))
919 opts=patch.diffopts(ui, opts))
913
920
914 def grep(ui, repo, pattern, *pats, **opts):
921 def grep(ui, repo, pattern, *pats, **opts):
915 """search for a pattern in specified files and revisions
922 """search for a pattern in specified files and revisions
916
923
917 Search revisions of files for a regular expression.
924 Search revisions of files for a regular expression.
918
925
919 This command behaves differently than Unix grep. It only accepts
926 This command behaves differently than Unix grep. It only accepts
920 Python/Perl regexps. It searches repository history, not the
927 Python/Perl regexps. It searches repository history, not the
921 working directory. It always prints the revision number in which
928 working directory. It always prints the revision number in which
922 a match appears.
929 a match appears.
923
930
924 By default, grep only prints output for the first revision of a
931 By default, grep only prints output for the first revision of a
925 file in which it finds a match. To get it to print every revision
932 file in which it finds a match. To get it to print every revision
926 that contains a change in match status ("-" for a match that
933 that contains a change in match status ("-" for a match that
927 becomes a non-match, or "+" for a non-match that becomes a match),
934 becomes a non-match, or "+" for a non-match that becomes a match),
928 use the --all flag.
935 use the --all flag.
929 """
936 """
930 reflags = 0
937 reflags = 0
931 if opts['ignore_case']:
938 if opts['ignore_case']:
932 reflags |= re.I
939 reflags |= re.I
933 regexp = re.compile(pattern, reflags)
940 regexp = re.compile(pattern, reflags)
934 sep, eol = ':', '\n'
941 sep, eol = ':', '\n'
935 if opts['print0']:
942 if opts['print0']:
936 sep = eol = '\0'
943 sep = eol = '\0'
937
944
938 fcache = {}
945 fcache = {}
939 def getfile(fn):
946 def getfile(fn):
940 if fn not in fcache:
947 if fn not in fcache:
941 fcache[fn] = repo.file(fn)
948 fcache[fn] = repo.file(fn)
942 return fcache[fn]
949 return fcache[fn]
943
950
944 def matchlines(body):
951 def matchlines(body):
945 begin = 0
952 begin = 0
946 linenum = 0
953 linenum = 0
947 while True:
954 while True:
948 match = regexp.search(body, begin)
955 match = regexp.search(body, begin)
949 if not match:
956 if not match:
950 break
957 break
951 mstart, mend = match.span()
958 mstart, mend = match.span()
952 linenum += body.count('\n', begin, mstart) + 1
959 linenum += body.count('\n', begin, mstart) + 1
953 lstart = body.rfind('\n', begin, mstart) + 1 or begin
960 lstart = body.rfind('\n', begin, mstart) + 1 or begin
954 lend = body.find('\n', mend)
961 lend = body.find('\n', mend)
955 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
962 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
956 begin = lend + 1
963 begin = lend + 1
957
964
958 class linestate(object):
965 class linestate(object):
959 def __init__(self, line, linenum, colstart, colend):
966 def __init__(self, line, linenum, colstart, colend):
960 self.line = line
967 self.line = line
961 self.linenum = linenum
968 self.linenum = linenum
962 self.colstart = colstart
969 self.colstart = colstart
963 self.colend = colend
970 self.colend = colend
964
971
965 def __eq__(self, other):
972 def __eq__(self, other):
966 return self.line == other.line
973 return self.line == other.line
967
974
968 matches = {}
975 matches = {}
969 copies = {}
976 copies = {}
970 def grepbody(fn, rev, body):
977 def grepbody(fn, rev, body):
971 matches[rev].setdefault(fn, [])
978 matches[rev].setdefault(fn, [])
972 m = matches[rev][fn]
979 m = matches[rev][fn]
973 for lnum, cstart, cend, line in matchlines(body):
980 for lnum, cstart, cend, line in matchlines(body):
974 s = linestate(line, lnum, cstart, cend)
981 s = linestate(line, lnum, cstart, cend)
975 m.append(s)
982 m.append(s)
976
983
977 def difflinestates(a, b):
984 def difflinestates(a, b):
978 sm = difflib.SequenceMatcher(None, a, b)
985 sm = difflib.SequenceMatcher(None, a, b)
979 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
986 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
980 if tag == 'insert':
987 if tag == 'insert':
981 for i in xrange(blo, bhi):
988 for i in xrange(blo, bhi):
982 yield ('+', b[i])
989 yield ('+', b[i])
983 elif tag == 'delete':
990 elif tag == 'delete':
984 for i in xrange(alo, ahi):
991 for i in xrange(alo, ahi):
985 yield ('-', a[i])
992 yield ('-', a[i])
986 elif tag == 'replace':
993 elif tag == 'replace':
987 for i in xrange(alo, ahi):
994 for i in xrange(alo, ahi):
988 yield ('-', a[i])
995 yield ('-', a[i])
989 for i in xrange(blo, bhi):
996 for i in xrange(blo, bhi):
990 yield ('+', b[i])
997 yield ('+', b[i])
991
998
992 prev = {}
999 prev = {}
993 def display(fn, rev, states, prevstates):
1000 def display(fn, rev, states, prevstates):
994 counts = {'-': 0, '+': 0}
1001 counts = {'-': 0, '+': 0}
995 filerevmatches = {}
1002 filerevmatches = {}
996 if incrementing or not opts['all']:
1003 if incrementing or not opts['all']:
997 a, b, r = prevstates, states, rev
1004 a, b, r = prevstates, states, rev
998 else:
1005 else:
999 a, b, r = states, prevstates, prev.get(fn, -1)
1006 a, b, r = states, prevstates, prev.get(fn, -1)
1000 for change, l in difflinestates(a, b):
1007 for change, l in difflinestates(a, b):
1001 cols = [fn, str(r)]
1008 cols = [fn, str(r)]
1002 if opts['line_number']:
1009 if opts['line_number']:
1003 cols.append(str(l.linenum))
1010 cols.append(str(l.linenum))
1004 if opts['all']:
1011 if opts['all']:
1005 cols.append(change)
1012 cols.append(change)
1006 if opts['user']:
1013 if opts['user']:
1007 cols.append(ui.shortuser(get(r)[1]))
1014 cols.append(ui.shortuser(get(r)[1]))
1008 if opts['files_with_matches']:
1015 if opts['files_with_matches']:
1009 c = (fn, r)
1016 c = (fn, r)
1010 if c in filerevmatches:
1017 if c in filerevmatches:
1011 continue
1018 continue
1012 filerevmatches[c] = 1
1019 filerevmatches[c] = 1
1013 else:
1020 else:
1014 cols.append(l.line)
1021 cols.append(l.line)
1015 ui.write(sep.join(cols), eol)
1022 ui.write(sep.join(cols), eol)
1016 counts[change] += 1
1023 counts[change] += 1
1017 return counts['+'], counts['-']
1024 return counts['+'], counts['-']
1018
1025
1019 fstate = {}
1026 fstate = {}
1020 skip = {}
1027 skip = {}
1021 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1028 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1022 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1029 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1023 count = 0
1030 count = 0
1024 incrementing = False
1031 incrementing = False
1025 follow = opts.get('follow')
1032 follow = opts.get('follow')
1026 for st, rev, fns in changeiter:
1033 for st, rev, fns in changeiter:
1027 if st == 'window':
1034 if st == 'window':
1028 incrementing = rev
1035 incrementing = rev
1029 matches.clear()
1036 matches.clear()
1030 elif st == 'add':
1037 elif st == 'add':
1031 mf = repo.changectx(rev).manifest()
1038 mf = repo.changectx(rev).manifest()
1032 matches[rev] = {}
1039 matches[rev] = {}
1033 for fn in fns:
1040 for fn in fns:
1034 if fn in skip:
1041 if fn in skip:
1035 continue
1042 continue
1036 fstate.setdefault(fn, {})
1043 fstate.setdefault(fn, {})
1037 try:
1044 try:
1038 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1045 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1039 if follow:
1046 if follow:
1040 copied = getfile(fn).renamed(mf[fn])
1047 copied = getfile(fn).renamed(mf[fn])
1041 if copied:
1048 if copied:
1042 copies.setdefault(rev, {})[fn] = copied[0]
1049 copies.setdefault(rev, {})[fn] = copied[0]
1043 except KeyError:
1050 except KeyError:
1044 pass
1051 pass
1045 elif st == 'iter':
1052 elif st == 'iter':
1046 states = matches[rev].items()
1053 states = matches[rev].items()
1047 states.sort()
1054 states.sort()
1048 for fn, m in states:
1055 for fn, m in states:
1049 copy = copies.get(rev, {}).get(fn)
1056 copy = copies.get(rev, {}).get(fn)
1050 if fn in skip:
1057 if fn in skip:
1051 if copy:
1058 if copy:
1052 skip[copy] = True
1059 skip[copy] = True
1053 continue
1060 continue
1054 if incrementing or not opts['all'] or fstate[fn]:
1061 if incrementing or not opts['all'] or fstate[fn]:
1055 pos, neg = display(fn, rev, m, fstate[fn])
1062 pos, neg = display(fn, rev, m, fstate[fn])
1056 count += pos + neg
1063 count += pos + neg
1057 if pos and not opts['all']:
1064 if pos and not opts['all']:
1058 skip[fn] = True
1065 skip[fn] = True
1059 if copy:
1066 if copy:
1060 skip[copy] = True
1067 skip[copy] = True
1061 fstate[fn] = m
1068 fstate[fn] = m
1062 if copy:
1069 if copy:
1063 fstate[copy] = m
1070 fstate[copy] = m
1064 prev[fn] = rev
1071 prev[fn] = rev
1065
1072
1066 if not incrementing:
1073 if not incrementing:
1067 fstate = fstate.items()
1074 fstate = fstate.items()
1068 fstate.sort()
1075 fstate.sort()
1069 for fn, state in fstate:
1076 for fn, state in fstate:
1070 if fn in skip:
1077 if fn in skip:
1071 continue
1078 continue
1072 if fn not in copies.get(prev[fn], {}):
1079 if fn not in copies.get(prev[fn], {}):
1073 display(fn, rev, {}, state)
1080 display(fn, rev, {}, state)
1074 return (count == 0 and 1) or 0
1081 return (count == 0 and 1) or 0
1075
1082
1076 def heads(ui, repo, **opts):
1083 def heads(ui, repo, **opts):
1077 """show current repository heads
1084 """show current repository heads
1078
1085
1079 Show all repository head changesets.
1086 Show all repository head changesets.
1080
1087
1081 Repository "heads" are changesets that don't have children
1088 Repository "heads" are changesets that don't have children
1082 changesets. They are where development generally takes place and
1089 changesets. They are where development generally takes place and
1083 are the usual targets for update and merge operations.
1090 are the usual targets for update and merge operations.
1084 """
1091 """
1085 if opts['rev']:
1092 if opts['rev']:
1086 heads = repo.heads(repo.lookup(opts['rev']))
1093 heads = repo.heads(repo.lookup(opts['rev']))
1087 else:
1094 else:
1088 heads = repo.heads()
1095 heads = repo.heads()
1089 displayer = cmdutil.show_changeset(ui, repo, opts)
1096 displayer = cmdutil.show_changeset(ui, repo, opts)
1090 for n in heads:
1097 for n in heads:
1091 displayer.show(changenode=n)
1098 displayer.show(changenode=n)
1092
1099
1093 def help_(ui, name=None, with_version=False):
1100 def help_(ui, name=None, with_version=False):
1094 """show help for a command, extension, or list of commands
1101 """show help for a command, extension, or list of commands
1095
1102
1096 With no arguments, print a list of commands and short help.
1103 With no arguments, print a list of commands and short help.
1097
1104
1098 Given a command name, print help for that command.
1105 Given a command name, print help for that command.
1099
1106
1100 Given an extension name, print help for that extension, and the
1107 Given an extension name, print help for that extension, and the
1101 commands it provides."""
1108 commands it provides."""
1102 option_lists = []
1109 option_lists = []
1103
1110
1104 def helpcmd(name):
1111 def helpcmd(name):
1105 if with_version:
1112 if with_version:
1106 version_(ui)
1113 version_(ui)
1107 ui.write('\n')
1114 ui.write('\n')
1108 aliases, i = findcmd(ui, name)
1115 aliases, i = findcmd(ui, name)
1109 # synopsis
1116 # synopsis
1110 ui.write("%s\n\n" % i[2])
1117 ui.write("%s\n\n" % i[2])
1111
1118
1112 # description
1119 # description
1113 doc = i[0].__doc__
1120 doc = i[0].__doc__
1114 if not doc:
1121 if not doc:
1115 doc = _("(No help text available)")
1122 doc = _("(No help text available)")
1116 if ui.quiet:
1123 if ui.quiet:
1117 doc = doc.splitlines(0)[0]
1124 doc = doc.splitlines(0)[0]
1118 ui.write("%s\n" % doc.rstrip())
1125 ui.write("%s\n" % doc.rstrip())
1119
1126
1120 if not ui.quiet:
1127 if not ui.quiet:
1121 # aliases
1128 # aliases
1122 if len(aliases) > 1:
1129 if len(aliases) > 1:
1123 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1130 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1124
1131
1125 # options
1132 # options
1126 if i[1]:
1133 if i[1]:
1127 option_lists.append(("options", i[1]))
1134 option_lists.append(("options", i[1]))
1128
1135
1129 def helplist(select=None):
1136 def helplist(select=None):
1130 h = {}
1137 h = {}
1131 cmds = {}
1138 cmds = {}
1132 for c, e in table.items():
1139 for c, e in table.items():
1133 f = c.split("|", 1)[0]
1140 f = c.split("|", 1)[0]
1134 if select and not select(f):
1141 if select and not select(f):
1135 continue
1142 continue
1136 if name == "shortlist" and not f.startswith("^"):
1143 if name == "shortlist" and not f.startswith("^"):
1137 continue
1144 continue
1138 f = f.lstrip("^")
1145 f = f.lstrip("^")
1139 if not ui.debugflag and f.startswith("debug"):
1146 if not ui.debugflag and f.startswith("debug"):
1140 continue
1147 continue
1141 doc = e[0].__doc__
1148 doc = e[0].__doc__
1142 if not doc:
1149 if not doc:
1143 doc = _("(No help text available)")
1150 doc = _("(No help text available)")
1144 h[f] = doc.splitlines(0)[0].rstrip()
1151 h[f] = doc.splitlines(0)[0].rstrip()
1145 cmds[f] = c.lstrip("^")
1152 cmds[f] = c.lstrip("^")
1146
1153
1147 fns = h.keys()
1154 fns = h.keys()
1148 fns.sort()
1155 fns.sort()
1149 m = max(map(len, fns))
1156 m = max(map(len, fns))
1150 for f in fns:
1157 for f in fns:
1151 if ui.verbose:
1158 if ui.verbose:
1152 commands = cmds[f].replace("|",", ")
1159 commands = cmds[f].replace("|",", ")
1153 ui.write(" %s:\n %s\n"%(commands, h[f]))
1160 ui.write(" %s:\n %s\n"%(commands, h[f]))
1154 else:
1161 else:
1155 ui.write(' %-*s %s\n' % (m, f, h[f]))
1162 ui.write(' %-*s %s\n' % (m, f, h[f]))
1156
1163
1157 def helptopic(name):
1164 def helptopic(name):
1158 v = None
1165 v = None
1159 for i in help.helptable:
1166 for i in help.helptable:
1160 l = i.split('|')
1167 l = i.split('|')
1161 if name in l:
1168 if name in l:
1162 v = i
1169 v = i
1163 header = l[-1]
1170 header = l[-1]
1164 if not v:
1171 if not v:
1165 raise UnknownCommand(name)
1172 raise UnknownCommand(name)
1166
1173
1167 # description
1174 # description
1168 doc = help.helptable[v]
1175 doc = help.helptable[v]
1169 if not doc:
1176 if not doc:
1170 doc = _("(No help text available)")
1177 doc = _("(No help text available)")
1171 if callable(doc):
1178 if callable(doc):
1172 doc = doc()
1179 doc = doc()
1173
1180
1174 ui.write("%s\n" % header)
1181 ui.write("%s\n" % header)
1175 ui.write("%s\n" % doc.rstrip())
1182 ui.write("%s\n" % doc.rstrip())
1176
1183
1177 def helpext(name):
1184 def helpext(name):
1178 try:
1185 try:
1179 mod = findext(name)
1186 mod = findext(name)
1180 except KeyError:
1187 except KeyError:
1181 raise UnknownCommand(name)
1188 raise UnknownCommand(name)
1182
1189
1183 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1190 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1184 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1191 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1185 for d in doc[1:]:
1192 for d in doc[1:]:
1186 ui.write(d, '\n')
1193 ui.write(d, '\n')
1187
1194
1188 ui.status('\n')
1195 ui.status('\n')
1189 if ui.verbose:
1196 if ui.verbose:
1190 ui.status(_('list of commands:\n\n'))
1197 ui.status(_('list of commands:\n\n'))
1191 else:
1198 else:
1192 ui.status(_('list of commands (use "hg help -v %s" '
1199 ui.status(_('list of commands (use "hg help -v %s" '
1193 'to show aliases and global options):\n\n') % name)
1200 'to show aliases and global options):\n\n') % name)
1194
1201
1195 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in mod.cmdtable])
1202 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in mod.cmdtable])
1196 helplist(modcmds.has_key)
1203 helplist(modcmds.has_key)
1197
1204
1198 if name and name != 'shortlist':
1205 if name and name != 'shortlist':
1199 i = None
1206 i = None
1200 for f in (helpcmd, helptopic, helpext):
1207 for f in (helpcmd, helptopic, helpext):
1201 try:
1208 try:
1202 f(name)
1209 f(name)
1203 i = None
1210 i = None
1204 break
1211 break
1205 except UnknownCommand, inst:
1212 except UnknownCommand, inst:
1206 i = inst
1213 i = inst
1207 if i:
1214 if i:
1208 raise i
1215 raise i
1209
1216
1210 else:
1217 else:
1211 # program name
1218 # program name
1212 if ui.verbose or with_version:
1219 if ui.verbose or with_version:
1213 version_(ui)
1220 version_(ui)
1214 else:
1221 else:
1215 ui.status(_("Mercurial Distributed SCM\n"))
1222 ui.status(_("Mercurial Distributed SCM\n"))
1216 ui.status('\n')
1223 ui.status('\n')
1217
1224
1218 # list of commands
1225 # list of commands
1219 if name == "shortlist":
1226 if name == "shortlist":
1220 ui.status(_('basic commands (use "hg help" '
1227 ui.status(_('basic commands (use "hg help" '
1221 'for the full list or option "-v" for details):\n\n'))
1228 'for the full list or option "-v" for details):\n\n'))
1222 elif ui.verbose:
1229 elif ui.verbose:
1223 ui.status(_('list of commands:\n\n'))
1230 ui.status(_('list of commands:\n\n'))
1224 else:
1231 else:
1225 ui.status(_('list of commands (use "hg help -v" '
1232 ui.status(_('list of commands (use "hg help -v" '
1226 'to show aliases and global options):\n\n'))
1233 'to show aliases and global options):\n\n'))
1227
1234
1228 helplist()
1235 helplist()
1229
1236
1230 # global options
1237 # global options
1231 if ui.verbose:
1238 if ui.verbose:
1232 option_lists.append(("global options", globalopts))
1239 option_lists.append(("global options", globalopts))
1233
1240
1234 # list all option lists
1241 # list all option lists
1235 opt_output = []
1242 opt_output = []
1236 for title, options in option_lists:
1243 for title, options in option_lists:
1237 opt_output.append(("\n%s:\n" % title, None))
1244 opt_output.append(("\n%s:\n" % title, None))
1238 for shortopt, longopt, default, desc in options:
1245 for shortopt, longopt, default, desc in options:
1239 if "DEPRECATED" in desc and not ui.verbose: continue
1246 if "DEPRECATED" in desc and not ui.verbose: continue
1240 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1247 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1241 longopt and " --%s" % longopt),
1248 longopt and " --%s" % longopt),
1242 "%s%s" % (desc,
1249 "%s%s" % (desc,
1243 default
1250 default
1244 and _(" (default: %s)") % default
1251 and _(" (default: %s)") % default
1245 or "")))
1252 or "")))
1246
1253
1247 if opt_output:
1254 if opt_output:
1248 opts_len = max([len(line[0]) for line in opt_output if line[1]])
1255 opts_len = max([len(line[0]) for line in opt_output if line[1]])
1249 for first, second in opt_output:
1256 for first, second in opt_output:
1250 if second:
1257 if second:
1251 ui.write(" %-*s %s\n" % (opts_len, first, second))
1258 ui.write(" %-*s %s\n" % (opts_len, first, second))
1252 else:
1259 else:
1253 ui.write("%s\n" % first)
1260 ui.write("%s\n" % first)
1254
1261
1255 def identify(ui, repo):
1262 def identify(ui, repo):
1256 """print information about the working copy
1263 """print information about the working copy
1257
1264
1258 Print a short summary of the current state of the repo.
1265 Print a short summary of the current state of the repo.
1259
1266
1260 This summary identifies the repository state using one or two parent
1267 This summary identifies the repository state using one or two parent
1261 hash identifiers, followed by a "+" if there are uncommitted changes
1268 hash identifiers, followed by a "+" if there are uncommitted changes
1262 in the working directory, followed by a list of tags for this revision.
1269 in the working directory, followed by a list of tags for this revision.
1263 """
1270 """
1264 parents = [p for p in repo.dirstate.parents() if p != nullid]
1271 parents = [p for p in repo.dirstate.parents() if p != nullid]
1265 if not parents:
1272 if not parents:
1266 ui.write(_("unknown\n"))
1273 ui.write(_("unknown\n"))
1267 return
1274 return
1268
1275
1269 hexfunc = ui.debugflag and hex or short
1276 hexfunc = ui.debugflag and hex or short
1270 modified, added, removed, deleted = repo.status()[:4]
1277 modified, added, removed, deleted = repo.status()[:4]
1271 output = ["%s%s" %
1278 output = ["%s%s" %
1272 ('+'.join([hexfunc(parent) for parent in parents]),
1279 ('+'.join([hexfunc(parent) for parent in parents]),
1273 (modified or added or removed or deleted) and "+" or "")]
1280 (modified or added or removed or deleted) and "+" or "")]
1274
1281
1275 if not ui.quiet:
1282 if not ui.quiet:
1276
1283
1277 branch = repo.workingctx().branch()
1284 branch = repo.workingctx().branch()
1278 if branch:
1285 if branch:
1279 output.append("(%s)" % branch)
1286 output.append("(%s)" % branch)
1280
1287
1281 # multiple tags for a single parent separated by '/'
1288 # multiple tags for a single parent separated by '/'
1282 parenttags = ['/'.join(tags)
1289 parenttags = ['/'.join(tags)
1283 for tags in map(repo.nodetags, parents) if tags]
1290 for tags in map(repo.nodetags, parents) if tags]
1284 # tags for multiple parents separated by ' + '
1291 # tags for multiple parents separated by ' + '
1285 if parenttags:
1292 if parenttags:
1286 output.append(' + '.join(parenttags))
1293 output.append(' + '.join(parenttags))
1287
1294
1288 ui.write("%s\n" % ' '.join(output))
1295 ui.write("%s\n" % ' '.join(output))
1289
1296
1290 def import_(ui, repo, patch1, *patches, **opts):
1297 def import_(ui, repo, patch1, *patches, **opts):
1291 """import an ordered set of patches
1298 """import an ordered set of patches
1292
1299
1293 Import a list of patches and commit them individually.
1300 Import a list of patches and commit them individually.
1294
1301
1295 If there are outstanding changes in the working directory, import
1302 If there are outstanding changes in the working directory, import
1296 will abort unless given the -f flag.
1303 will abort unless given the -f flag.
1297
1304
1298 You can import a patch straight from a mail message. Even patches
1305 You can import a patch straight from a mail message. Even patches
1299 as attachments work (body part must be type text/plain or
1306 as attachments work (body part must be type text/plain or
1300 text/x-patch to be used). From and Subject headers of email
1307 text/x-patch to be used). From and Subject headers of email
1301 message are used as default committer and commit message. All
1308 message are used as default committer and commit message. All
1302 text/plain body parts before first diff are added to commit
1309 text/plain body parts before first diff are added to commit
1303 message.
1310 message.
1304
1311
1305 If imported patch was generated by hg export, user and description
1312 If imported patch was generated by hg export, user and description
1306 from patch override values from message headers and body. Values
1313 from patch override values from message headers and body. Values
1307 given on command line with -m and -u override these.
1314 given on command line with -m and -u override these.
1308
1315
1309 To read a patch from standard input, use patch name "-".
1316 To read a patch from standard input, use patch name "-".
1310 """
1317 """
1311 patches = (patch1,) + patches
1318 patches = (patch1,) + patches
1312
1319
1313 if not opts['force']:
1320 if not opts['force']:
1314 bail_if_changed(repo)
1321 bail_if_changed(repo)
1315
1322
1316 d = opts["base"]
1323 d = opts["base"]
1317 strip = opts["strip"]
1324 strip = opts["strip"]
1318
1325
1319 wlock = repo.wlock()
1326 wlock = repo.wlock()
1320 lock = repo.lock()
1327 lock = repo.lock()
1321
1328
1322 for p in patches:
1329 for p in patches:
1323 pf = os.path.join(d, p)
1330 pf = os.path.join(d, p)
1324
1331
1325 if pf == '-':
1332 if pf == '-':
1326 ui.status(_("applying patch from stdin\n"))
1333 ui.status(_("applying patch from stdin\n"))
1327 tmpname, message, user, date = patch.extract(ui, sys.stdin)
1334 tmpname, message, user, date = patch.extract(ui, sys.stdin)
1328 else:
1335 else:
1329 ui.status(_("applying %s\n") % p)
1336 ui.status(_("applying %s\n") % p)
1330 tmpname, message, user, date = patch.extract(ui, file(pf))
1337 tmpname, message, user, date = patch.extract(ui, file(pf))
1331
1338
1332 if tmpname is None:
1339 if tmpname is None:
1333 raise util.Abort(_('no diffs found'))
1340 raise util.Abort(_('no diffs found'))
1334
1341
1335 try:
1342 try:
1336 if opts['message']:
1343 if opts['message']:
1337 # pickup the cmdline msg
1344 # pickup the cmdline msg
1338 message = opts['message']
1345 message = opts['message']
1339 elif message:
1346 elif message:
1340 # pickup the patch msg
1347 # pickup the patch msg
1341 message = message.strip()
1348 message = message.strip()
1342 else:
1349 else:
1343 # launch the editor
1350 # launch the editor
1344 message = None
1351 message = None
1345 ui.debug(_('message:\n%s\n') % message)
1352 ui.debug(_('message:\n%s\n') % message)
1346
1353
1347 files = {}
1354 files = {}
1348 try:
1355 try:
1349 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1356 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1350 files=files)
1357 files=files)
1351 finally:
1358 finally:
1352 files = patch.updatedir(ui, repo, files, wlock=wlock)
1359 files = patch.updatedir(ui, repo, files, wlock=wlock)
1353 repo.commit(files, message, user, date, wlock=wlock, lock=lock)
1360 repo.commit(files, message, user, date, wlock=wlock, lock=lock)
1354 finally:
1361 finally:
1355 os.unlink(tmpname)
1362 os.unlink(tmpname)
1356
1363
1357 def incoming(ui, repo, source="default", **opts):
1364 def incoming(ui, repo, source="default", **opts):
1358 """show new changesets found in source
1365 """show new changesets found in source
1359
1366
1360 Show new changesets found in the specified path/URL or the default
1367 Show new changesets found in the specified path/URL or the default
1361 pull location. These are the changesets that would be pulled if a pull
1368 pull location. These are the changesets that would be pulled if a pull
1362 was requested.
1369 was requested.
1363
1370
1364 For remote repository, using --bundle avoids downloading the changesets
1371 For remote repository, using --bundle avoids downloading the changesets
1365 twice if the incoming is followed by a pull.
1372 twice if the incoming is followed by a pull.
1366
1373
1367 See pull for valid source format details.
1374 See pull for valid source format details.
1368 """
1375 """
1369 source = ui.expandpath(source)
1376 source = ui.expandpath(source)
1370 setremoteconfig(ui, opts)
1377 setremoteconfig(ui, opts)
1371
1378
1372 other = hg.repository(ui, source)
1379 other = hg.repository(ui, source)
1373 incoming = repo.findincoming(other, force=opts["force"])
1380 incoming = repo.findincoming(other, force=opts["force"])
1374 if not incoming:
1381 if not incoming:
1375 ui.status(_("no changes found\n"))
1382 ui.status(_("no changes found\n"))
1376 return
1383 return
1377
1384
1378 cleanup = None
1385 cleanup = None
1379 try:
1386 try:
1380 fname = opts["bundle"]
1387 fname = opts["bundle"]
1381 if fname or not other.local():
1388 if fname or not other.local():
1382 # create a bundle (uncompressed if other repo is not local)
1389 # create a bundle (uncompressed if other repo is not local)
1383 cg = other.changegroup(incoming, "incoming")
1390 cg = other.changegroup(incoming, "incoming")
1384 bundletype = other.local() and "HG10BZ" or "HG10UN"
1391 bundletype = other.local() and "HG10BZ" or "HG10UN"
1385 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1392 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1386 # keep written bundle?
1393 # keep written bundle?
1387 if opts["bundle"]:
1394 if opts["bundle"]:
1388 cleanup = None
1395 cleanup = None
1389 if not other.local():
1396 if not other.local():
1390 # use the created uncompressed bundlerepo
1397 # use the created uncompressed bundlerepo
1391 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1398 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1392
1399
1393 revs = None
1400 revs = None
1394 if opts['rev']:
1401 if opts['rev']:
1395 revs = [other.lookup(rev) for rev in opts['rev']]
1402 revs = [other.lookup(rev) for rev in opts['rev']]
1396 o = other.changelog.nodesbetween(incoming, revs)[0]
1403 o = other.changelog.nodesbetween(incoming, revs)[0]
1397 if opts['newest_first']:
1404 if opts['newest_first']:
1398 o.reverse()
1405 o.reverse()
1399 displayer = cmdutil.show_changeset(ui, other, opts)
1406 displayer = cmdutil.show_changeset(ui, other, opts)
1400 for n in o:
1407 for n in o:
1401 parents = [p for p in other.changelog.parents(n) if p != nullid]
1408 parents = [p for p in other.changelog.parents(n) if p != nullid]
1402 if opts['no_merges'] and len(parents) == 2:
1409 if opts['no_merges'] and len(parents) == 2:
1403 continue
1410 continue
1404 displayer.show(changenode=n)
1411 displayer.show(changenode=n)
1405 finally:
1412 finally:
1406 if hasattr(other, 'close'):
1413 if hasattr(other, 'close'):
1407 other.close()
1414 other.close()
1408 if cleanup:
1415 if cleanup:
1409 os.unlink(cleanup)
1416 os.unlink(cleanup)
1410
1417
1411 def init(ui, dest=".", **opts):
1418 def init(ui, dest=".", **opts):
1412 """create a new repository in the given directory
1419 """create a new repository in the given directory
1413
1420
1414 Initialize a new repository in the given directory. If the given
1421 Initialize a new repository in the given directory. If the given
1415 directory does not exist, it is created.
1422 directory does not exist, it is created.
1416
1423
1417 If no directory is given, the current directory is used.
1424 If no directory is given, the current directory is used.
1418
1425
1419 It is possible to specify an ssh:// URL as the destination.
1426 It is possible to specify an ssh:// URL as the destination.
1420 Look at the help text for the pull command for important details
1427 Look at the help text for the pull command for important details
1421 about ssh:// URLs.
1428 about ssh:// URLs.
1422 """
1429 """
1423 setremoteconfig(ui, opts)
1430 setremoteconfig(ui, opts)
1424 hg.repository(ui, dest, create=1)
1431 hg.repository(ui, dest, create=1)
1425
1432
1426 def locate(ui, repo, *pats, **opts):
1433 def locate(ui, repo, *pats, **opts):
1427 """locate files matching specific patterns
1434 """locate files matching specific patterns
1428
1435
1429 Print all files under Mercurial control whose names match the
1436 Print all files under Mercurial control whose names match the
1430 given patterns.
1437 given patterns.
1431
1438
1432 This command searches the current directory and its
1439 This command searches the current directory and its
1433 subdirectories. To search an entire repository, move to the root
1440 subdirectories. To search an entire repository, move to the root
1434 of the repository.
1441 of the repository.
1435
1442
1436 If no patterns are given to match, this command prints all file
1443 If no patterns are given to match, this command prints all file
1437 names.
1444 names.
1438
1445
1439 If you want to feed the output of this command into the "xargs"
1446 If you want to feed the output of this command into the "xargs"
1440 command, use the "-0" option to both this command and "xargs".
1447 command, use the "-0" option to both this command and "xargs".
1441 This will avoid the problem of "xargs" treating single filenames
1448 This will avoid the problem of "xargs" treating single filenames
1442 that contain white space as multiple filenames.
1449 that contain white space as multiple filenames.
1443 """
1450 """
1444 end = opts['print0'] and '\0' or '\n'
1451 end = opts['print0'] and '\0' or '\n'
1445 rev = opts['rev']
1452 rev = opts['rev']
1446 if rev:
1453 if rev:
1447 node = repo.lookup(rev)
1454 node = repo.lookup(rev)
1448 else:
1455 else:
1449 node = None
1456 node = None
1450
1457
1451 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1458 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1452 head='(?:.*/|)'):
1459 head='(?:.*/|)'):
1453 if not node and repo.dirstate.state(abs) == '?':
1460 if not node and repo.dirstate.state(abs) == '?':
1454 continue
1461 continue
1455 if opts['fullpath']:
1462 if opts['fullpath']:
1456 ui.write(os.path.join(repo.root, abs), end)
1463 ui.write(os.path.join(repo.root, abs), end)
1457 else:
1464 else:
1458 ui.write(((pats and rel) or abs), end)
1465 ui.write(((pats and rel) or abs), end)
1459
1466
1460 def log(ui, repo, *pats, **opts):
1467 def log(ui, repo, *pats, **opts):
1461 """show revision history of entire repository or files
1468 """show revision history of entire repository or files
1462
1469
1463 Print the revision history of the specified files or the entire
1470 Print the revision history of the specified files or the entire
1464 project.
1471 project.
1465
1472
1466 File history is shown without following rename or copy history of
1473 File history is shown without following rename or copy history of
1467 files. Use -f/--follow with a file name to follow history across
1474 files. Use -f/--follow with a file name to follow history across
1468 renames and copies. --follow without a file name will only show
1475 renames and copies. --follow without a file name will only show
1469 ancestors or descendants of the starting revision. --follow-first
1476 ancestors or descendants of the starting revision. --follow-first
1470 only follows the first parent of merge revisions.
1477 only follows the first parent of merge revisions.
1471
1478
1472 If no revision range is specified, the default is tip:0 unless
1479 If no revision range is specified, the default is tip:0 unless
1473 --follow is set, in which case the working directory parent is
1480 --follow is set, in which case the working directory parent is
1474 used as the starting revision.
1481 used as the starting revision.
1475
1482
1476 By default this command outputs: changeset id and hash, tags,
1483 By default this command outputs: changeset id and hash, tags,
1477 non-trivial parents, user, date and time, and a summary for each
1484 non-trivial parents, user, date and time, and a summary for each
1478 commit. When the -v/--verbose switch is used, the list of changed
1485 commit. When the -v/--verbose switch is used, the list of changed
1479 files and full commit message is shown.
1486 files and full commit message is shown.
1487
1488 NOTE: log -p may generate unexpected diff output for merge
1489 changesets, as it will compare the merge changeset against its
1490 first parent only. Also, the files: list will only reflect files
1491 that are different from BOTH parents.
1492
1480 """
1493 """
1481
1494
1482 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1495 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1483 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1496 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1484
1497
1485 if opts['limit']:
1498 if opts['limit']:
1486 try:
1499 try:
1487 limit = int(opts['limit'])
1500 limit = int(opts['limit'])
1488 except ValueError:
1501 except ValueError:
1489 raise util.Abort(_('limit must be a positive integer'))
1502 raise util.Abort(_('limit must be a positive integer'))
1490 if limit <= 0: raise util.Abort(_('limit must be positive'))
1503 if limit <= 0: raise util.Abort(_('limit must be positive'))
1491 else:
1504 else:
1492 limit = sys.maxint
1505 limit = sys.maxint
1493 count = 0
1506 count = 0
1494
1507
1495 if opts['copies'] and opts['rev']:
1508 if opts['copies'] and opts['rev']:
1496 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1509 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1497 else:
1510 else:
1498 endrev = repo.changelog.count()
1511 endrev = repo.changelog.count()
1499 rcache = {}
1512 rcache = {}
1500 ncache = {}
1513 ncache = {}
1501 dcache = []
1514 dcache = []
1502 def getrenamed(fn, rev, man):
1515 def getrenamed(fn, rev, man):
1503 '''looks up all renames for a file (up to endrev) the first
1516 '''looks up all renames for a file (up to endrev) the first
1504 time the file is given. It indexes on the changerev and only
1517 time the file is given. It indexes on the changerev and only
1505 parses the manifest if linkrev != changerev.
1518 parses the manifest if linkrev != changerev.
1506 Returns rename info for fn at changerev rev.'''
1519 Returns rename info for fn at changerev rev.'''
1507 if fn not in rcache:
1520 if fn not in rcache:
1508 rcache[fn] = {}
1521 rcache[fn] = {}
1509 ncache[fn] = {}
1522 ncache[fn] = {}
1510 fl = repo.file(fn)
1523 fl = repo.file(fn)
1511 for i in xrange(fl.count()):
1524 for i in xrange(fl.count()):
1512 node = fl.node(i)
1525 node = fl.node(i)
1513 lr = fl.linkrev(node)
1526 lr = fl.linkrev(node)
1514 renamed = fl.renamed(node)
1527 renamed = fl.renamed(node)
1515 rcache[fn][lr] = renamed
1528 rcache[fn][lr] = renamed
1516 if renamed:
1529 if renamed:
1517 ncache[fn][node] = renamed
1530 ncache[fn][node] = renamed
1518 if lr >= endrev:
1531 if lr >= endrev:
1519 break
1532 break
1520 if rev in rcache[fn]:
1533 if rev in rcache[fn]:
1521 return rcache[fn][rev]
1534 return rcache[fn][rev]
1522 mr = repo.manifest.rev(man)
1535 mr = repo.manifest.rev(man)
1523 if repo.manifest.parentrevs(mr) != (mr - 1, nullrev):
1536 if repo.manifest.parentrevs(mr) != (mr - 1, nullrev):
1524 return ncache[fn].get(repo.manifest.find(man, fn)[0])
1537 return ncache[fn].get(repo.manifest.find(man, fn)[0])
1525 if not dcache or dcache[0] != man:
1538 if not dcache or dcache[0] != man:
1526 dcache[:] = [man, repo.manifest.readdelta(man)]
1539 dcache[:] = [man, repo.manifest.readdelta(man)]
1527 if fn in dcache[1]:
1540 if fn in dcache[1]:
1528 return ncache[fn].get(dcache[1][fn])
1541 return ncache[fn].get(dcache[1][fn])
1529 return None
1542 return None
1530
1543
1531 df = False
1544 df = False
1532 if opts["date"]:
1545 if opts["date"]:
1533 df = util.matchdate(opts["date"])
1546 df = util.matchdate(opts["date"])
1534
1547
1535
1548
1536 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
1549 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
1537 for st, rev, fns in changeiter:
1550 for st, rev, fns in changeiter:
1538 if st == 'add':
1551 if st == 'add':
1539 changenode = repo.changelog.node(rev)
1552 changenode = repo.changelog.node(rev)
1540 parents = [p for p in repo.changelog.parentrevs(rev)
1553 parents = [p for p in repo.changelog.parentrevs(rev)
1541 if p != nullrev]
1554 if p != nullrev]
1542 if opts['no_merges'] and len(parents) == 2:
1555 if opts['no_merges'] and len(parents) == 2:
1543 continue
1556 continue
1544 if opts['only_merges'] and len(parents) != 2:
1557 if opts['only_merges'] and len(parents) != 2:
1545 continue
1558 continue
1546
1559
1547 if df:
1560 if df:
1548 changes = get(rev)
1561 changes = get(rev)
1549 if not df(changes[2][0]):
1562 if not df(changes[2][0]):
1550 continue
1563 continue
1551
1564
1552 if opts['keyword']:
1565 if opts['keyword']:
1553 changes = get(rev)
1566 changes = get(rev)
1554 miss = 0
1567 miss = 0
1555 for k in [kw.lower() for kw in opts['keyword']]:
1568 for k in [kw.lower() for kw in opts['keyword']]:
1556 if not (k in changes[1].lower() or
1569 if not (k in changes[1].lower() or
1557 k in changes[4].lower() or
1570 k in changes[4].lower() or
1558 k in " ".join(changes[3][:20]).lower()):
1571 k in " ".join(changes[3][:20]).lower()):
1559 miss = 1
1572 miss = 1
1560 break
1573 break
1561 if miss:
1574 if miss:
1562 continue
1575 continue
1563
1576
1564 copies = []
1577 copies = []
1565 if opts.get('copies') and rev:
1578 if opts.get('copies') and rev:
1566 mf = get(rev)[0]
1579 mf = get(rev)[0]
1567 for fn in get(rev)[3]:
1580 for fn in get(rev)[3]:
1568 rename = getrenamed(fn, rev, mf)
1581 rename = getrenamed(fn, rev, mf)
1569 if rename:
1582 if rename:
1570 copies.append((fn, rename[0]))
1583 copies.append((fn, rename[0]))
1571 displayer.show(rev, changenode, copies=copies)
1584 displayer.show(rev, changenode, copies=copies)
1572 elif st == 'iter':
1585 elif st == 'iter':
1573 if count == limit: break
1586 if count == limit: break
1574 if displayer.flush(rev):
1587 if displayer.flush(rev):
1575 count += 1
1588 count += 1
1576
1589
1577 def manifest(ui, repo, rev=None):
1590 def manifest(ui, repo, rev=None):
1578 """output the latest or given revision of the project manifest
1591 """output the latest or given revision of the project manifest
1579
1592
1580 Print a list of version controlled files for the given revision.
1593 Print a list of version controlled files for the given revision.
1581
1594
1582 The manifest is the list of files being version controlled. If no revision
1595 The manifest is the list of files being version controlled. If no revision
1583 is given then the first parent of the working directory is used.
1596 is given then the first parent of the working directory is used.
1584
1597
1585 With -v flag, print file permissions. With --debug flag, print
1598 With -v flag, print file permissions. With --debug flag, print
1586 file revision hashes.
1599 file revision hashes.
1587 """
1600 """
1588
1601
1589 m = repo.changectx(rev).manifest()
1602 m = repo.changectx(rev).manifest()
1590 files = m.keys()
1603 files = m.keys()
1591 files.sort()
1604 files.sort()
1592
1605
1593 for f in files:
1606 for f in files:
1594 if ui.debugflag:
1607 if ui.debugflag:
1595 ui.write("%40s " % hex(m[f]))
1608 ui.write("%40s " % hex(m[f]))
1596 if ui.verbose:
1609 if ui.verbose:
1597 ui.write("%3s " % (m.execf(f) and "755" or "644"))
1610 ui.write("%3s " % (m.execf(f) and "755" or "644"))
1598 ui.write("%s\n" % f)
1611 ui.write("%s\n" % f)
1599
1612
1600 def merge(ui, repo, node=None, force=None, branch=None):
1613 def merge(ui, repo, node=None, force=None, branch=None):
1601 """Merge working directory with another revision
1614 """Merge working directory with another revision
1602
1615
1603 Merge the contents of the current working directory and the
1616 Merge the contents of the current working directory and the
1604 requested revision. Files that changed between either parent are
1617 requested revision. Files that changed between either parent are
1605 marked as changed for the next commit and a commit must be
1618 marked as changed for the next commit and a commit must be
1606 performed before any further updates are allowed.
1619 performed before any further updates are allowed.
1607
1620
1608 If no revision is specified, the working directory's parent is a
1621 If no revision is specified, the working directory's parent is a
1609 head revision, and the repository contains exactly one other head,
1622 head revision, and the repository contains exactly one other head,
1610 the other head is merged with by default. Otherwise, an explicit
1623 the other head is merged with by default. Otherwise, an explicit
1611 revision to merge with must be provided.
1624 revision to merge with must be provided.
1612 """
1625 """
1613
1626
1614 if node or branch:
1627 if node or branch:
1615 node = _lookup(repo, node, branch)
1628 node = _lookup(repo, node, branch)
1616 else:
1629 else:
1617 heads = repo.heads()
1630 heads = repo.heads()
1618 if len(heads) > 2:
1631 if len(heads) > 2:
1619 raise util.Abort(_('repo has %d heads - '
1632 raise util.Abort(_('repo has %d heads - '
1620 'please merge with an explicit rev') %
1633 'please merge with an explicit rev') %
1621 len(heads))
1634 len(heads))
1622 if len(heads) == 1:
1635 if len(heads) == 1:
1623 raise util.Abort(_('there is nothing to merge - '
1636 raise util.Abort(_('there is nothing to merge - '
1624 'use "hg update" instead'))
1637 'use "hg update" instead'))
1625 parent = repo.dirstate.parents()[0]
1638 parent = repo.dirstate.parents()[0]
1626 if parent not in heads:
1639 if parent not in heads:
1627 raise util.Abort(_('working dir not at a head rev - '
1640 raise util.Abort(_('working dir not at a head rev - '
1628 'use "hg update" or merge with an explicit rev'))
1641 'use "hg update" or merge with an explicit rev'))
1629 node = parent == heads[0] and heads[-1] or heads[0]
1642 node = parent == heads[0] and heads[-1] or heads[0]
1630 return hg.merge(repo, node, force=force)
1643 return hg.merge(repo, node, force=force)
1631
1644
1632 def outgoing(ui, repo, dest=None, **opts):
1645 def outgoing(ui, repo, dest=None, **opts):
1633 """show changesets not found in destination
1646 """show changesets not found in destination
1634
1647
1635 Show changesets not found in the specified destination repository or
1648 Show changesets not found in the specified destination repository or
1636 the default push location. These are the changesets that would be pushed
1649 the default push location. These are the changesets that would be pushed
1637 if a push was requested.
1650 if a push was requested.
1638
1651
1639 See pull for valid destination format details.
1652 See pull for valid destination format details.
1640 """
1653 """
1641 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1654 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1642 setremoteconfig(ui, opts)
1655 setremoteconfig(ui, opts)
1643 revs = None
1656 revs = None
1644 if opts['rev']:
1657 if opts['rev']:
1645 revs = [repo.lookup(rev) for rev in opts['rev']]
1658 revs = [repo.lookup(rev) for rev in opts['rev']]
1646
1659
1647 other = hg.repository(ui, dest)
1660 other = hg.repository(ui, dest)
1648 o = repo.findoutgoing(other, force=opts['force'])
1661 o = repo.findoutgoing(other, force=opts['force'])
1649 if not o:
1662 if not o:
1650 ui.status(_("no changes found\n"))
1663 ui.status(_("no changes found\n"))
1651 return
1664 return
1652 o = repo.changelog.nodesbetween(o, revs)[0]
1665 o = repo.changelog.nodesbetween(o, revs)[0]
1653 if opts['newest_first']:
1666 if opts['newest_first']:
1654 o.reverse()
1667 o.reverse()
1655 displayer = cmdutil.show_changeset(ui, repo, opts)
1668 displayer = cmdutil.show_changeset(ui, repo, opts)
1656 for n in o:
1669 for n in o:
1657 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1670 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1658 if opts['no_merges'] and len(parents) == 2:
1671 if opts['no_merges'] and len(parents) == 2:
1659 continue
1672 continue
1660 displayer.show(changenode=n)
1673 displayer.show(changenode=n)
1661
1674
1662 def parents(ui, repo, file_=None, **opts):
1675 def parents(ui, repo, file_=None, **opts):
1663 """show the parents of the working dir or revision
1676 """show the parents of the working dir or revision
1664
1677
1665 Print the working directory's parent revisions.
1678 Print the working directory's parent revisions.
1666 """
1679 """
1667 rev = opts.get('rev')
1680 rev = opts.get('rev')
1668 if rev:
1681 if rev:
1669 if file_:
1682 if file_:
1670 ctx = repo.filectx(file_, changeid=rev)
1683 ctx = repo.filectx(file_, changeid=rev)
1671 else:
1684 else:
1672 ctx = repo.changectx(rev)
1685 ctx = repo.changectx(rev)
1673 p = [cp.node() for cp in ctx.parents()]
1686 p = [cp.node() for cp in ctx.parents()]
1674 else:
1687 else:
1675 p = repo.dirstate.parents()
1688 p = repo.dirstate.parents()
1676
1689
1677 displayer = cmdutil.show_changeset(ui, repo, opts)
1690 displayer = cmdutil.show_changeset(ui, repo, opts)
1678 for n in p:
1691 for n in p:
1679 if n != nullid:
1692 if n != nullid:
1680 displayer.show(changenode=n)
1693 displayer.show(changenode=n)
1681
1694
1682 def paths(ui, repo, search=None):
1695 def paths(ui, repo, search=None):
1683 """show definition of symbolic path names
1696 """show definition of symbolic path names
1684
1697
1685 Show definition of symbolic path name NAME. If no name is given, show
1698 Show definition of symbolic path name NAME. If no name is given, show
1686 definition of available names.
1699 definition of available names.
1687
1700
1688 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1701 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1689 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1702 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1690 """
1703 """
1691 if search:
1704 if search:
1692 for name, path in ui.configitems("paths"):
1705 for name, path in ui.configitems("paths"):
1693 if name == search:
1706 if name == search:
1694 ui.write("%s\n" % path)
1707 ui.write("%s\n" % path)
1695 return
1708 return
1696 ui.warn(_("not found!\n"))
1709 ui.warn(_("not found!\n"))
1697 return 1
1710 return 1
1698 else:
1711 else:
1699 for name, path in ui.configitems("paths"):
1712 for name, path in ui.configitems("paths"):
1700 ui.write("%s = %s\n" % (name, path))
1713 ui.write("%s = %s\n" % (name, path))
1701
1714
1702 def postincoming(ui, repo, modheads, optupdate):
1715 def postincoming(ui, repo, modheads, optupdate):
1703 if modheads == 0:
1716 if modheads == 0:
1704 return
1717 return
1705 if optupdate:
1718 if optupdate:
1706 if modheads == 1:
1719 if modheads == 1:
1707 return hg.update(repo, repo.changelog.tip()) # update
1720 return hg.update(repo, repo.changelog.tip()) # update
1708 else:
1721 else:
1709 ui.status(_("not updating, since new heads added\n"))
1722 ui.status(_("not updating, since new heads added\n"))
1710 if modheads > 1:
1723 if modheads > 1:
1711 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1724 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1712 else:
1725 else:
1713 ui.status(_("(run 'hg update' to get a working copy)\n"))
1726 ui.status(_("(run 'hg update' to get a working copy)\n"))
1714
1727
1715 def pull(ui, repo, source="default", **opts):
1728 def pull(ui, repo, source="default", **opts):
1716 """pull changes from the specified source
1729 """pull changes from the specified source
1717
1730
1718 Pull changes from a remote repository to a local one.
1731 Pull changes from a remote repository to a local one.
1719
1732
1720 This finds all changes from the repository at the specified path
1733 This finds all changes from the repository at the specified path
1721 or URL and adds them to the local repository. By default, this
1734 or URL and adds them to the local repository. By default, this
1722 does not update the copy of the project in the working directory.
1735 does not update the copy of the project in the working directory.
1723
1736
1724 Valid URLs are of the form:
1737 Valid URLs are of the form:
1725
1738
1726 local/filesystem/path (or file://local/filesystem/path)
1739 local/filesystem/path (or file://local/filesystem/path)
1727 http://[user@]host[:port]/[path]
1740 http://[user@]host[:port]/[path]
1728 https://[user@]host[:port]/[path]
1741 https://[user@]host[:port]/[path]
1729 ssh://[user@]host[:port]/[path]
1742 ssh://[user@]host[:port]/[path]
1730 static-http://host[:port]/[path]
1743 static-http://host[:port]/[path]
1731
1744
1732 Paths in the local filesystem can either point to Mercurial
1745 Paths in the local filesystem can either point to Mercurial
1733 repositories or to bundle files (as created by 'hg bundle' or
1746 repositories or to bundle files (as created by 'hg bundle' or
1734 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1747 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1735 allows access to a Mercurial repository where you simply use a web
1748 allows access to a Mercurial repository where you simply use a web
1736 server to publish the .hg directory as static content.
1749 server to publish the .hg directory as static content.
1737
1750
1738 Some notes about using SSH with Mercurial:
1751 Some notes about using SSH with Mercurial:
1739 - SSH requires an accessible shell account on the destination machine
1752 - SSH requires an accessible shell account on the destination machine
1740 and a copy of hg in the remote path or specified with as remotecmd.
1753 and a copy of hg in the remote path or specified with as remotecmd.
1741 - path is relative to the remote user's home directory by default.
1754 - path is relative to the remote user's home directory by default.
1742 Use an extra slash at the start of a path to specify an absolute path:
1755 Use an extra slash at the start of a path to specify an absolute path:
1743 ssh://example.com//tmp/repository
1756 ssh://example.com//tmp/repository
1744 - Mercurial doesn't use its own compression via SSH; the right thing
1757 - Mercurial doesn't use its own compression via SSH; the right thing
1745 to do is to configure it in your ~/.ssh/config, e.g.:
1758 to do is to configure it in your ~/.ssh/config, e.g.:
1746 Host *.mylocalnetwork.example.com
1759 Host *.mylocalnetwork.example.com
1747 Compression no
1760 Compression no
1748 Host *
1761 Host *
1749 Compression yes
1762 Compression yes
1750 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1763 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1751 with the --ssh command line option.
1764 with the --ssh command line option.
1752 """
1765 """
1753 source = ui.expandpath(source)
1766 source = ui.expandpath(source)
1754 setremoteconfig(ui, opts)
1767 setremoteconfig(ui, opts)
1755
1768
1756 other = hg.repository(ui, source)
1769 other = hg.repository(ui, source)
1757 ui.status(_('pulling from %s\n') % (source))
1770 ui.status(_('pulling from %s\n') % (source))
1758 revs = None
1771 revs = None
1759 if opts['rev']:
1772 if opts['rev']:
1760 if 'lookup' in other.capabilities:
1773 if 'lookup' in other.capabilities:
1761 revs = [other.lookup(rev) for rev in opts['rev']]
1774 revs = [other.lookup(rev) for rev in opts['rev']]
1762 else:
1775 else:
1763 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.")
1776 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.")
1764 raise util.Abort(error)
1777 raise util.Abort(error)
1765 modheads = repo.pull(other, heads=revs, force=opts['force'])
1778 modheads = repo.pull(other, heads=revs, force=opts['force'])
1766 return postincoming(ui, repo, modheads, opts['update'])
1779 return postincoming(ui, repo, modheads, opts['update'])
1767
1780
1768 def push(ui, repo, dest=None, **opts):
1781 def push(ui, repo, dest=None, **opts):
1769 """push changes to the specified destination
1782 """push changes to the specified destination
1770
1783
1771 Push changes from the local repository to the given destination.
1784 Push changes from the local repository to the given destination.
1772
1785
1773 This is the symmetrical operation for pull. It helps to move
1786 This is the symmetrical operation for pull. It helps to move
1774 changes from the current repository to a different one. If the
1787 changes from the current repository to a different one. If the
1775 destination is local this is identical to a pull in that directory
1788 destination is local this is identical to a pull in that directory
1776 from the current one.
1789 from the current one.
1777
1790
1778 By default, push will refuse to run if it detects the result would
1791 By default, push will refuse to run if it detects the result would
1779 increase the number of remote heads. This generally indicates the
1792 increase the number of remote heads. This generally indicates the
1780 the client has forgotten to sync and merge before pushing.
1793 the client has forgotten to sync and merge before pushing.
1781
1794
1782 Valid URLs are of the form:
1795 Valid URLs are of the form:
1783
1796
1784 local/filesystem/path (or file://local/filesystem/path)
1797 local/filesystem/path (or file://local/filesystem/path)
1785 ssh://[user@]host[:port]/[path]
1798 ssh://[user@]host[:port]/[path]
1786 http://[user@]host[:port]/[path]
1799 http://[user@]host[:port]/[path]
1787 https://[user@]host[:port]/[path]
1800 https://[user@]host[:port]/[path]
1788
1801
1789 Look at the help text for the pull command for important details
1802 Look at the help text for the pull command for important details
1790 about ssh:// URLs.
1803 about ssh:// URLs.
1791
1804
1792 Pushing to http:// and https:// URLs is only possible, if this
1805 Pushing to http:// and https:// URLs is only possible, if this
1793 feature is explicitly enabled on the remote Mercurial server.
1806 feature is explicitly enabled on the remote Mercurial server.
1794 """
1807 """
1795 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1808 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1796 setremoteconfig(ui, opts)
1809 setremoteconfig(ui, opts)
1797
1810
1798 other = hg.repository(ui, dest)
1811 other = hg.repository(ui, dest)
1799 ui.status('pushing to %s\n' % (dest))
1812 ui.status('pushing to %s\n' % (dest))
1800 revs = None
1813 revs = None
1801 if opts['rev']:
1814 if opts['rev']:
1802 revs = [repo.lookup(rev) for rev in opts['rev']]
1815 revs = [repo.lookup(rev) for rev in opts['rev']]
1803 r = repo.push(other, opts['force'], revs=revs)
1816 r = repo.push(other, opts['force'], revs=revs)
1804 return r == 0
1817 return r == 0
1805
1818
1806 def rawcommit(ui, repo, *pats, **opts):
1819 def rawcommit(ui, repo, *pats, **opts):
1807 """raw commit interface (DEPRECATED)
1820 """raw commit interface (DEPRECATED)
1808
1821
1809 (DEPRECATED)
1822 (DEPRECATED)
1810 Lowlevel commit, for use in helper scripts.
1823 Lowlevel commit, for use in helper scripts.
1811
1824
1812 This command is not intended to be used by normal users, as it is
1825 This command is not intended to be used by normal users, as it is
1813 primarily useful for importing from other SCMs.
1826 primarily useful for importing from other SCMs.
1814
1827
1815 This command is now deprecated and will be removed in a future
1828 This command is now deprecated and will be removed in a future
1816 release, please use debugsetparents and commit instead.
1829 release, please use debugsetparents and commit instead.
1817 """
1830 """
1818
1831
1819 ui.warn(_("(the rawcommit command is deprecated)\n"))
1832 ui.warn(_("(the rawcommit command is deprecated)\n"))
1820
1833
1821 message = logmessage(opts)
1834 message = logmessage(opts)
1822
1835
1823 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
1836 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
1824 if opts['files']:
1837 if opts['files']:
1825 files += open(opts['files']).read().splitlines()
1838 files += open(opts['files']).read().splitlines()
1826
1839
1827 parents = [repo.lookup(p) for p in opts['parent']]
1840 parents = [repo.lookup(p) for p in opts['parent']]
1828
1841
1829 try:
1842 try:
1830 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
1843 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
1831 except ValueError, inst:
1844 except ValueError, inst:
1832 raise util.Abort(str(inst))
1845 raise util.Abort(str(inst))
1833
1846
1834 def recover(ui, repo):
1847 def recover(ui, repo):
1835 """roll back an interrupted transaction
1848 """roll back an interrupted transaction
1836
1849
1837 Recover from an interrupted commit or pull.
1850 Recover from an interrupted commit or pull.
1838
1851
1839 This command tries to fix the repository status after an interrupted
1852 This command tries to fix the repository status after an interrupted
1840 operation. It should only be necessary when Mercurial suggests it.
1853 operation. It should only be necessary when Mercurial suggests it.
1841 """
1854 """
1842 if repo.recover():
1855 if repo.recover():
1843 return hg.verify(repo)
1856 return hg.verify(repo)
1844 return 1
1857 return 1
1845
1858
1846 def remove(ui, repo, *pats, **opts):
1859 def remove(ui, repo, *pats, **opts):
1847 """remove the specified files on the next commit
1860 """remove the specified files on the next commit
1848
1861
1849 Schedule the indicated files for removal from the repository.
1862 Schedule the indicated files for removal from the repository.
1850
1863
1851 This command schedules the files to be removed at the next commit.
1864 This command schedules the files to be removed at the next commit.
1852 This only removes files from the current branch, not from the
1865 This only removes files from the current branch, not from the
1853 entire project history. If the files still exist in the working
1866 entire project history. If the files still exist in the working
1854 directory, they will be deleted from it. If invoked with --after,
1867 directory, they will be deleted from it. If invoked with --after,
1855 files that have been manually deleted are marked as removed.
1868 files that have been manually deleted are marked as removed.
1856
1869
1857 Modified files and added files are not removed by default. To
1870 Modified files and added files are not removed by default. To
1858 remove them, use the -f/--force option.
1871 remove them, use the -f/--force option.
1859 """
1872 """
1860 names = []
1873 names = []
1861 if not opts['after'] and not pats:
1874 if not opts['after'] and not pats:
1862 raise util.Abort(_('no files specified'))
1875 raise util.Abort(_('no files specified'))
1863 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
1876 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
1864 exact = dict.fromkeys(files)
1877 exact = dict.fromkeys(files)
1865 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
1878 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
1866 modified, added, removed, deleted, unknown = mardu
1879 modified, added, removed, deleted, unknown = mardu
1867 remove, forget = [], []
1880 remove, forget = [], []
1868 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
1881 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
1869 reason = None
1882 reason = None
1870 if abs not in deleted and opts['after']:
1883 if abs not in deleted and opts['after']:
1871 reason = _('is still present')
1884 reason = _('is still present')
1872 elif abs in modified and not opts['force']:
1885 elif abs in modified and not opts['force']:
1873 reason = _('is modified (use -f to force removal)')
1886 reason = _('is modified (use -f to force removal)')
1874 elif abs in added:
1887 elif abs in added:
1875 if opts['force']:
1888 if opts['force']:
1876 forget.append(abs)
1889 forget.append(abs)
1877 continue
1890 continue
1878 reason = _('has been marked for add (use -f to force removal)')
1891 reason = _('has been marked for add (use -f to force removal)')
1879 elif abs in unknown:
1892 elif abs in unknown:
1880 reason = _('is not managed')
1893 reason = _('is not managed')
1881 elif abs in removed:
1894 elif abs in removed:
1882 continue
1895 continue
1883 if reason:
1896 if reason:
1884 if exact:
1897 if exact:
1885 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
1898 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
1886 else:
1899 else:
1887 if ui.verbose or not exact:
1900 if ui.verbose or not exact:
1888 ui.status(_('removing %s\n') % rel)
1901 ui.status(_('removing %s\n') % rel)
1889 remove.append(abs)
1902 remove.append(abs)
1890 repo.forget(forget)
1903 repo.forget(forget)
1891 repo.remove(remove, unlink=not opts['after'])
1904 repo.remove(remove, unlink=not opts['after'])
1892
1905
1893 def rename(ui, repo, *pats, **opts):
1906 def rename(ui, repo, *pats, **opts):
1894 """rename files; equivalent of copy + remove
1907 """rename files; equivalent of copy + remove
1895
1908
1896 Mark dest as copies of sources; mark sources for deletion. If
1909 Mark dest as copies of sources; mark sources for deletion. If
1897 dest is a directory, copies are put in that directory. If dest is
1910 dest is a directory, copies are put in that directory. If dest is
1898 a file, there can only be one source.
1911 a file, there can only be one source.
1899
1912
1900 By default, this command copies the contents of files as they
1913 By default, this command copies the contents of files as they
1901 stand in the working directory. If invoked with --after, the
1914 stand in the working directory. If invoked with --after, the
1902 operation is recorded, but no copying is performed.
1915 operation is recorded, but no copying is performed.
1903
1916
1904 This command takes effect in the next commit.
1917 This command takes effect in the next commit.
1905 """
1918 """
1906 wlock = repo.wlock(0)
1919 wlock = repo.wlock(0)
1907 errs, copied = docopy(ui, repo, pats, opts, wlock)
1920 errs, copied = docopy(ui, repo, pats, opts, wlock)
1908 names = []
1921 names = []
1909 for abs, rel, exact in copied:
1922 for abs, rel, exact in copied:
1910 if ui.verbose or not exact:
1923 if ui.verbose or not exact:
1911 ui.status(_('removing %s\n') % rel)
1924 ui.status(_('removing %s\n') % rel)
1912 names.append(abs)
1925 names.append(abs)
1913 if not opts.get('dry_run'):
1926 if not opts.get('dry_run'):
1914 repo.remove(names, True, wlock)
1927 repo.remove(names, True, wlock)
1915 return errs
1928 return errs
1916
1929
1917 def revert(ui, repo, *pats, **opts):
1930 def revert(ui, repo, *pats, **opts):
1918 """revert files or dirs to their states as of some revision
1931 """revert files or dirs to their states as of some revision
1919
1932
1920 With no revision specified, revert the named files or directories
1933 With no revision specified, revert the named files or directories
1921 to the contents they had in the parent of the working directory.
1934 to the contents they had in the parent of the working directory.
1922 This restores the contents of the affected files to an unmodified
1935 This restores the contents of the affected files to an unmodified
1923 state. If the working directory has two parents, you must
1936 state. If the working directory has two parents, you must
1924 explicitly specify the revision to revert to.
1937 explicitly specify the revision to revert to.
1925
1938
1926 Modified files are saved with a .orig suffix before reverting.
1939 Modified files are saved with a .orig suffix before reverting.
1927 To disable these backups, use --no-backup.
1940 To disable these backups, use --no-backup.
1928
1941
1929 Using the -r option, revert the given files or directories to their
1942 Using the -r option, revert the given files or directories to their
1930 contents as of a specific revision. This can be helpful to "roll
1943 contents as of a specific revision. This can be helpful to "roll
1931 back" some or all of a change that should not have been committed.
1944 back" some or all of a change that should not have been committed.
1932
1945
1933 Revert modifies the working directory. It does not commit any
1946 Revert modifies the working directory. It does not commit any
1934 changes, or change the parent of the working directory. If you
1947 changes, or change the parent of the working directory. If you
1935 revert to a revision other than the parent of the working
1948 revert to a revision other than the parent of the working
1936 directory, the reverted files will thus appear modified
1949 directory, the reverted files will thus appear modified
1937 afterwards.
1950 afterwards.
1938
1951
1939 If a file has been deleted, it is recreated. If the executable
1952 If a file has been deleted, it is recreated. If the executable
1940 mode of a file was changed, it is reset.
1953 mode of a file was changed, it is reset.
1941
1954
1942 If names are given, all files matching the names are reverted.
1955 If names are given, all files matching the names are reverted.
1943
1956
1944 If no arguments are given, no files are reverted.
1957 If no arguments are given, no files are reverted.
1945 """
1958 """
1946
1959
1947 if opts["date"]:
1960 if opts["date"]:
1948 if opts["rev"]:
1961 if opts["rev"]:
1949 raise util.Abort(_("you can't specify a revision and a date"))
1962 raise util.Abort(_("you can't specify a revision and a date"))
1950 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
1963 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
1951
1964
1952 if not pats and not opts['all']:
1965 if not pats and not opts['all']:
1953 raise util.Abort(_('no files or directories specified; '
1966 raise util.Abort(_('no files or directories specified; '
1954 'use --all to revert the whole repo'))
1967 'use --all to revert the whole repo'))
1955
1968
1956 parent, p2 = repo.dirstate.parents()
1969 parent, p2 = repo.dirstate.parents()
1957 if not opts['rev'] and p2 != nullid:
1970 if not opts['rev'] and p2 != nullid:
1958 raise util.Abort(_('uncommitted merge - please provide a '
1971 raise util.Abort(_('uncommitted merge - please provide a '
1959 'specific revision'))
1972 'specific revision'))
1960 node = repo.changectx(opts['rev']).node()
1973 node = repo.changectx(opts['rev']).node()
1961 mf = repo.manifest.read(repo.changelog.read(node)[0])
1974 mf = repo.manifest.read(repo.changelog.read(node)[0])
1962 if node == parent:
1975 if node == parent:
1963 pmf = mf
1976 pmf = mf
1964 else:
1977 else:
1965 pmf = None
1978 pmf = None
1966
1979
1967 wlock = repo.wlock()
1980 wlock = repo.wlock()
1968
1981
1969 # need all matching names in dirstate and manifest of target rev,
1982 # need all matching names in dirstate and manifest of target rev,
1970 # so have to walk both. do not print errors if files exist in one
1983 # so have to walk both. do not print errors if files exist in one
1971 # but not other.
1984 # but not other.
1972
1985
1973 names = {}
1986 names = {}
1974 target_only = {}
1987 target_only = {}
1975
1988
1976 # walk dirstate.
1989 # walk dirstate.
1977
1990
1978 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
1991 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
1979 badmatch=mf.has_key):
1992 badmatch=mf.has_key):
1980 names[abs] = (rel, exact)
1993 names[abs] = (rel, exact)
1981 if src == 'b':
1994 if src == 'b':
1982 target_only[abs] = True
1995 target_only[abs] = True
1983
1996
1984 # walk target manifest.
1997 # walk target manifest.
1985
1998
1986 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1999 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1987 badmatch=names.has_key):
2000 badmatch=names.has_key):
1988 if abs in names: continue
2001 if abs in names: continue
1989 names[abs] = (rel, exact)
2002 names[abs] = (rel, exact)
1990 target_only[abs] = True
2003 target_only[abs] = True
1991
2004
1992 changes = repo.status(match=names.has_key, wlock=wlock)[:5]
2005 changes = repo.status(match=names.has_key, wlock=wlock)[:5]
1993 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2006 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
1994
2007
1995 revert = ([], _('reverting %s\n'))
2008 revert = ([], _('reverting %s\n'))
1996 add = ([], _('adding %s\n'))
2009 add = ([], _('adding %s\n'))
1997 remove = ([], _('removing %s\n'))
2010 remove = ([], _('removing %s\n'))
1998 forget = ([], _('forgetting %s\n'))
2011 forget = ([], _('forgetting %s\n'))
1999 undelete = ([], _('undeleting %s\n'))
2012 undelete = ([], _('undeleting %s\n'))
2000 update = {}
2013 update = {}
2001
2014
2002 disptable = (
2015 disptable = (
2003 # dispatch table:
2016 # dispatch table:
2004 # file state
2017 # file state
2005 # action if in target manifest
2018 # action if in target manifest
2006 # action if not in target manifest
2019 # action if not in target manifest
2007 # make backup if in target manifest
2020 # make backup if in target manifest
2008 # make backup if not in target manifest
2021 # make backup if not in target manifest
2009 (modified, revert, remove, True, True),
2022 (modified, revert, remove, True, True),
2010 (added, revert, forget, True, False),
2023 (added, revert, forget, True, False),
2011 (removed, undelete, None, False, False),
2024 (removed, undelete, None, False, False),
2012 (deleted, revert, remove, False, False),
2025 (deleted, revert, remove, False, False),
2013 (unknown, add, None, True, False),
2026 (unknown, add, None, True, False),
2014 (target_only, add, None, False, False),
2027 (target_only, add, None, False, False),
2015 )
2028 )
2016
2029
2017 entries = names.items()
2030 entries = names.items()
2018 entries.sort()
2031 entries.sort()
2019
2032
2020 for abs, (rel, exact) in entries:
2033 for abs, (rel, exact) in entries:
2021 mfentry = mf.get(abs)
2034 mfentry = mf.get(abs)
2022 def handle(xlist, dobackup):
2035 def handle(xlist, dobackup):
2023 xlist[0].append(abs)
2036 xlist[0].append(abs)
2024 update[abs] = 1
2037 update[abs] = 1
2025 if dobackup and not opts['no_backup'] and os.path.exists(rel):
2038 if dobackup and not opts['no_backup'] and os.path.exists(rel):
2026 bakname = "%s.orig" % rel
2039 bakname = "%s.orig" % rel
2027 ui.note(_('saving current version of %s as %s\n') %
2040 ui.note(_('saving current version of %s as %s\n') %
2028 (rel, bakname))
2041 (rel, bakname))
2029 if not opts.get('dry_run'):
2042 if not opts.get('dry_run'):
2030 util.copyfile(rel, bakname)
2043 util.copyfile(rel, bakname)
2031 if ui.verbose or not exact:
2044 if ui.verbose or not exact:
2032 ui.status(xlist[1] % rel)
2045 ui.status(xlist[1] % rel)
2033 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2046 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2034 if abs not in table: continue
2047 if abs not in table: continue
2035 # file has changed in dirstate
2048 # file has changed in dirstate
2036 if mfentry:
2049 if mfentry:
2037 handle(hitlist, backuphit)
2050 handle(hitlist, backuphit)
2038 elif misslist is not None:
2051 elif misslist is not None:
2039 handle(misslist, backupmiss)
2052 handle(misslist, backupmiss)
2040 else:
2053 else:
2041 if exact: ui.warn(_('file not managed: %s\n') % rel)
2054 if exact: ui.warn(_('file not managed: %s\n') % rel)
2042 break
2055 break
2043 else:
2056 else:
2044 # file has not changed in dirstate
2057 # file has not changed in dirstate
2045 if node == parent:
2058 if node == parent:
2046 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2059 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2047 continue
2060 continue
2048 if pmf is None:
2061 if pmf is None:
2049 # only need parent manifest in this unlikely case,
2062 # only need parent manifest in this unlikely case,
2050 # so do not read by default
2063 # so do not read by default
2051 pmf = repo.manifest.read(repo.changelog.read(parent)[0])
2064 pmf = repo.manifest.read(repo.changelog.read(parent)[0])
2052 if abs in pmf:
2065 if abs in pmf:
2053 if mfentry:
2066 if mfentry:
2054 # if version of file is same in parent and target
2067 # if version of file is same in parent and target
2055 # manifests, do nothing
2068 # manifests, do nothing
2056 if pmf[abs] != mfentry:
2069 if pmf[abs] != mfentry:
2057 handle(revert, False)
2070 handle(revert, False)
2058 else:
2071 else:
2059 handle(remove, False)
2072 handle(remove, False)
2060
2073
2061 if not opts.get('dry_run'):
2074 if not opts.get('dry_run'):
2062 repo.dirstate.forget(forget[0])
2075 repo.dirstate.forget(forget[0])
2063 r = hg.revert(repo, node, update.has_key, wlock)
2076 r = hg.revert(repo, node, update.has_key, wlock)
2064 repo.dirstate.update(add[0], 'a')
2077 repo.dirstate.update(add[0], 'a')
2065 repo.dirstate.update(undelete[0], 'n')
2078 repo.dirstate.update(undelete[0], 'n')
2066 repo.dirstate.update(remove[0], 'r')
2079 repo.dirstate.update(remove[0], 'r')
2067 return r
2080 return r
2068
2081
2069 def rollback(ui, repo):
2082 def rollback(ui, repo):
2070 """roll back the last transaction in this repository
2083 """roll back the last transaction in this repository
2071
2084
2072 Roll back the last transaction in this repository, restoring the
2085 Roll back the last transaction in this repository, restoring the
2073 project to its state prior to the transaction.
2086 project to its state prior to the transaction.
2074
2087
2075 Transactions are used to encapsulate the effects of all commands
2088 Transactions are used to encapsulate the effects of all commands
2076 that create new changesets or propagate existing changesets into a
2089 that create new changesets or propagate existing changesets into a
2077 repository. For example, the following commands are transactional,
2090 repository. For example, the following commands are transactional,
2078 and their effects can be rolled back:
2091 and their effects can be rolled back:
2079
2092
2080 commit
2093 commit
2081 import
2094 import
2082 pull
2095 pull
2083 push (with this repository as destination)
2096 push (with this repository as destination)
2084 unbundle
2097 unbundle
2085
2098
2086 This command should be used with care. There is only one level of
2099 This command should be used with care. There is only one level of
2087 rollback, and there is no way to undo a rollback.
2100 rollback, and there is no way to undo a rollback.
2088
2101
2089 This command is not intended for use on public repositories. Once
2102 This command is not intended for use on public repositories. Once
2090 changes are visible for pull by other users, rolling a transaction
2103 changes are visible for pull by other users, rolling a transaction
2091 back locally is ineffective (someone else may already have pulled
2104 back locally is ineffective (someone else may already have pulled
2092 the changes). Furthermore, a race is possible with readers of the
2105 the changes). Furthermore, a race is possible with readers of the
2093 repository; for example an in-progress pull from the repository
2106 repository; for example an in-progress pull from the repository
2094 may fail if a rollback is performed.
2107 may fail if a rollback is performed.
2095 """
2108 """
2096 repo.rollback()
2109 repo.rollback()
2097
2110
2098 def root(ui, repo):
2111 def root(ui, repo):
2099 """print the root (top) of the current working dir
2112 """print the root (top) of the current working dir
2100
2113
2101 Print the root directory of the current repository.
2114 Print the root directory of the current repository.
2102 """
2115 """
2103 ui.write(repo.root + "\n")
2116 ui.write(repo.root + "\n")
2104
2117
2105 def serve(ui, repo, **opts):
2118 def serve(ui, repo, **opts):
2106 """export the repository via HTTP
2119 """export the repository via HTTP
2107
2120
2108 Start a local HTTP repository browser and pull server.
2121 Start a local HTTP repository browser and pull server.
2109
2122
2110 By default, the server logs accesses to stdout and errors to
2123 By default, the server logs accesses to stdout and errors to
2111 stderr. Use the "-A" and "-E" options to log to files.
2124 stderr. Use the "-A" and "-E" options to log to files.
2112 """
2125 """
2113
2126
2114 if opts["stdio"]:
2127 if opts["stdio"]:
2115 if repo is None:
2128 if repo is None:
2116 raise hg.RepoError(_("There is no Mercurial repository here"
2129 raise hg.RepoError(_("There is no Mercurial repository here"
2117 " (.hg not found)"))
2130 " (.hg not found)"))
2118 s = sshserver.sshserver(ui, repo)
2131 s = sshserver.sshserver(ui, repo)
2119 s.serve_forever()
2132 s.serve_forever()
2120
2133
2121 optlist = ("name templates style address port ipv6"
2134 optlist = ("name templates style address port ipv6"
2122 " accesslog errorlog webdir_conf")
2135 " accesslog errorlog webdir_conf")
2123 for o in optlist.split():
2136 for o in optlist.split():
2124 if opts[o]:
2137 if opts[o]:
2125 ui.setconfig("web", o, str(opts[o]))
2138 ui.setconfig("web", o, str(opts[o]))
2126
2139
2127 if repo is None and not ui.config("web", "webdir_conf"):
2140 if repo is None and not ui.config("web", "webdir_conf"):
2128 raise hg.RepoError(_("There is no Mercurial repository here"
2141 raise hg.RepoError(_("There is no Mercurial repository here"
2129 " (.hg not found)"))
2142 " (.hg not found)"))
2130
2143
2131 if opts['daemon'] and not opts['daemon_pipefds']:
2144 if opts['daemon'] and not opts['daemon_pipefds']:
2132 rfd, wfd = os.pipe()
2145 rfd, wfd = os.pipe()
2133 args = sys.argv[:]
2146 args = sys.argv[:]
2134 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
2147 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
2135 pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
2148 pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
2136 args[0], args)
2149 args[0], args)
2137 os.close(wfd)
2150 os.close(wfd)
2138 os.read(rfd, 1)
2151 os.read(rfd, 1)
2139 os._exit(0)
2152 os._exit(0)
2140
2153
2141 httpd = hgweb.server.create_server(ui, repo)
2154 httpd = hgweb.server.create_server(ui, repo)
2142
2155
2143 if ui.verbose:
2156 if ui.verbose:
2144 if httpd.port != 80:
2157 if httpd.port != 80:
2145 ui.status(_('listening at http://%s:%d/\n') %
2158 ui.status(_('listening at http://%s:%d/\n') %
2146 (httpd.addr, httpd.port))
2159 (httpd.addr, httpd.port))
2147 else:
2160 else:
2148 ui.status(_('listening at http://%s/\n') % httpd.addr)
2161 ui.status(_('listening at http://%s/\n') % httpd.addr)
2149
2162
2150 if opts['pid_file']:
2163 if opts['pid_file']:
2151 fp = open(opts['pid_file'], 'w')
2164 fp = open(opts['pid_file'], 'w')
2152 fp.write(str(os.getpid()) + '\n')
2165 fp.write(str(os.getpid()) + '\n')
2153 fp.close()
2166 fp.close()
2154
2167
2155 if opts['daemon_pipefds']:
2168 if opts['daemon_pipefds']:
2156 rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
2169 rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
2157 os.close(rfd)
2170 os.close(rfd)
2158 os.write(wfd, 'y')
2171 os.write(wfd, 'y')
2159 os.close(wfd)
2172 os.close(wfd)
2160 sys.stdout.flush()
2173 sys.stdout.flush()
2161 sys.stderr.flush()
2174 sys.stderr.flush()
2162 fd = os.open(util.nulldev, os.O_RDWR)
2175 fd = os.open(util.nulldev, os.O_RDWR)
2163 if fd != 0: os.dup2(fd, 0)
2176 if fd != 0: os.dup2(fd, 0)
2164 if fd != 1: os.dup2(fd, 1)
2177 if fd != 1: os.dup2(fd, 1)
2165 if fd != 2: os.dup2(fd, 2)
2178 if fd != 2: os.dup2(fd, 2)
2166 if fd not in (0, 1, 2): os.close(fd)
2179 if fd not in (0, 1, 2): os.close(fd)
2167
2180
2168 httpd.serve_forever()
2181 httpd.serve_forever()
2169
2182
2170 def status(ui, repo, *pats, **opts):
2183 def status(ui, repo, *pats, **opts):
2171 """show changed files in the working directory
2184 """show changed files in the working directory
2172
2185
2173 Show status of files in the repository. If names are given, only
2186 Show status of files in the repository. If names are given, only
2174 files that match are shown. Files that are clean or ignored, are
2187 files that match are shown. Files that are clean or ignored, are
2175 not listed unless -c (clean), -i (ignored) or -A is given.
2188 not listed unless -c (clean), -i (ignored) or -A is given.
2176
2189
2190 NOTE: status may appear to disagree with diff if permissions have
2191 changed or a merge has occurred. The standard diff format does not
2192 report permission changes and diff only reports changes relative
2193 to one merge parent.
2194
2177 If one revision is given, it is used as the base revision.
2195 If one revision is given, it is used as the base revision.
2178 If two revisions are given, the difference between them is shown.
2196 If two revisions are given, the difference between them is shown.
2179
2197
2180 The codes used to show the status of files are:
2198 The codes used to show the status of files are:
2181 M = modified
2199 M = modified
2182 A = added
2200 A = added
2183 R = removed
2201 R = removed
2184 C = clean
2202 C = clean
2185 ! = deleted, but still tracked
2203 ! = deleted, but still tracked
2186 ? = not tracked
2204 ? = not tracked
2187 I = ignored (not shown by default)
2205 I = ignored (not shown by default)
2188 = the previous added file was copied from here
2206 = the previous added file was copied from here
2189 """
2207 """
2190
2208
2191 all = opts['all']
2209 all = opts['all']
2192 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2210 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2193
2211
2194 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2212 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2195 cwd = (pats and repo.getcwd()) or ''
2213 cwd = (pats and repo.getcwd()) or ''
2196 modified, added, removed, deleted, unknown, ignored, clean = [
2214 modified, added, removed, deleted, unknown, ignored, clean = [
2197 [util.pathto(cwd, x) for x in n]
2215 [util.pathto(cwd, x) for x in n]
2198 for n in repo.status(node1=node1, node2=node2, files=files,
2216 for n in repo.status(node1=node1, node2=node2, files=files,
2199 match=matchfn,
2217 match=matchfn,
2200 list_ignored=all or opts['ignored'],
2218 list_ignored=all or opts['ignored'],
2201 list_clean=all or opts['clean'])]
2219 list_clean=all or opts['clean'])]
2202
2220
2203 changetypes = (('modified', 'M', modified),
2221 changetypes = (('modified', 'M', modified),
2204 ('added', 'A', added),
2222 ('added', 'A', added),
2205 ('removed', 'R', removed),
2223 ('removed', 'R', removed),
2206 ('deleted', '!', deleted),
2224 ('deleted', '!', deleted),
2207 ('unknown', '?', unknown),
2225 ('unknown', '?', unknown),
2208 ('ignored', 'I', ignored))
2226 ('ignored', 'I', ignored))
2209
2227
2210 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2228 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2211
2229
2212 end = opts['print0'] and '\0' or '\n'
2230 end = opts['print0'] and '\0' or '\n'
2213
2231
2214 for opt, char, changes in ([ct for ct in explicit_changetypes
2232 for opt, char, changes in ([ct for ct in explicit_changetypes
2215 if all or opts[ct[0]]]
2233 if all or opts[ct[0]]]
2216 or changetypes):
2234 or changetypes):
2217 if opts['no_status']:
2235 if opts['no_status']:
2218 format = "%%s%s" % end
2236 format = "%%s%s" % end
2219 else:
2237 else:
2220 format = "%s %%s%s" % (char, end)
2238 format = "%s %%s%s" % (char, end)
2221
2239
2222 for f in changes:
2240 for f in changes:
2223 ui.write(format % f)
2241 ui.write(format % f)
2224 if ((all or opts.get('copies')) and not opts.get('no_status')):
2242 if ((all or opts.get('copies')) and not opts.get('no_status')):
2225 copied = repo.dirstate.copied(f)
2243 copied = repo.dirstate.copied(f)
2226 if copied:
2244 if copied:
2227 ui.write(' %s%s' % (copied, end))
2245 ui.write(' %s%s' % (copied, end))
2228
2246
2229 def tag(ui, repo, name, rev_=None, **opts):
2247 def tag(ui, repo, name, rev_=None, **opts):
2230 """add a tag for the current tip or a given revision
2248 """add a tag for the current tip or a given revision
2231
2249
2232 Name a particular revision using <name>.
2250 Name a particular revision using <name>.
2233
2251
2234 Tags are used to name particular revisions of the repository and are
2252 Tags are used to name particular revisions of the repository and are
2235 very useful to compare different revision, to go back to significant
2253 very useful to compare different revision, to go back to significant
2236 earlier versions or to mark branch points as releases, etc.
2254 earlier versions or to mark branch points as releases, etc.
2237
2255
2238 If no revision is given, the parent of the working directory is used.
2256 If no revision is given, the parent of the working directory is used.
2239
2257
2240 To facilitate version control, distribution, and merging of tags,
2258 To facilitate version control, distribution, and merging of tags,
2241 they are stored as a file named ".hgtags" which is managed
2259 they are stored as a file named ".hgtags" which is managed
2242 similarly to other project files and can be hand-edited if
2260 similarly to other project files and can be hand-edited if
2243 necessary. The file '.hg/localtags' is used for local tags (not
2261 necessary. The file '.hg/localtags' is used for local tags (not
2244 shared among repositories).
2262 shared among repositories).
2245 """
2263 """
2246 if name in ['tip', '.', 'null']:
2264 if name in ['tip', '.', 'null']:
2247 raise util.Abort(_("the name '%s' is reserved") % name)
2265 raise util.Abort(_("the name '%s' is reserved") % name)
2248 if rev_ is not None:
2266 if rev_ is not None:
2249 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2267 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2250 "please use 'hg tag [-r REV] NAME' instead\n"))
2268 "please use 'hg tag [-r REV] NAME' instead\n"))
2251 if opts['rev']:
2269 if opts['rev']:
2252 raise util.Abort(_("use only one form to specify the revision"))
2270 raise util.Abort(_("use only one form to specify the revision"))
2253 if opts['rev']:
2271 if opts['rev']:
2254 rev_ = opts['rev']
2272 rev_ = opts['rev']
2255 if not rev_ and repo.dirstate.parents()[1] != nullid:
2273 if not rev_ and repo.dirstate.parents()[1] != nullid:
2256 raise util.Abort(_('uncommitted merge - please provide a '
2274 raise util.Abort(_('uncommitted merge - please provide a '
2257 'specific revision'))
2275 'specific revision'))
2258 r = repo.changectx(rev_).node()
2276 r = repo.changectx(rev_).node()
2259
2277
2260 message = opts['message']
2278 message = opts['message']
2261 if not message:
2279 if not message:
2262 message = _('Added tag %s for changeset %s') % (name, short(r))
2280 message = _('Added tag %s for changeset %s') % (name, short(r))
2263
2281
2264 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2282 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2265
2283
2266 def tags(ui, repo):
2284 def tags(ui, repo):
2267 """list repository tags
2285 """list repository tags
2268
2286
2269 List the repository tags.
2287 List the repository tags.
2270
2288
2271 This lists both regular and local tags.
2289 This lists both regular and local tags.
2272 """
2290 """
2273
2291
2274 l = repo.tagslist()
2292 l = repo.tagslist()
2275 l.reverse()
2293 l.reverse()
2276 hexfunc = ui.debugflag and hex or short
2294 hexfunc = ui.debugflag and hex or short
2277 for t, n in l:
2295 for t, n in l:
2278 try:
2296 try:
2279 r = "%5d:%s" % (repo.changelog.rev(n), hexfunc(n))
2297 r = "%5d:%s" % (repo.changelog.rev(n), hexfunc(n))
2280 except KeyError:
2298 except KeyError:
2281 r = " ?:?"
2299 r = " ?:?"
2282 if ui.quiet:
2300 if ui.quiet:
2283 ui.write("%s\n" % t)
2301 ui.write("%s\n" % t)
2284 else:
2302 else:
2285 t = util.localsub(t, 30)
2303 t = util.localsub(t, 30)
2286 t += " " * (30 - util.locallen(t))
2304 t += " " * (30 - util.locallen(t))
2287 ui.write("%s %s\n" % (t, r))
2305 ui.write("%s %s\n" % (t, r))
2288
2306
2289 def tip(ui, repo, **opts):
2307 def tip(ui, repo, **opts):
2290 """show the tip revision
2308 """show the tip revision
2291
2309
2292 Show the tip revision.
2310 Show the tip revision.
2293 """
2311 """
2294 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2312 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2295
2313
2296 def unbundle(ui, repo, fname, **opts):
2314 def unbundle(ui, repo, fname, **opts):
2297 """apply a changegroup file
2315 """apply a changegroup file
2298
2316
2299 Apply a compressed changegroup file generated by the bundle
2317 Apply a compressed changegroup file generated by the bundle
2300 command.
2318 command.
2301 """
2319 """
2302 gen = changegroup.readbundle(urllib.urlopen(fname))
2320 gen = changegroup.readbundle(urllib.urlopen(fname))
2303 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2321 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2304 return postincoming(ui, repo, modheads, opts['update'])
2322 return postincoming(ui, repo, modheads, opts['update'])
2305
2323
2306 def update(ui, repo, node=None, clean=False, branch=None, date=None):
2324 def update(ui, repo, node=None, clean=False, branch=None, date=None):
2307 """update or merge working directory
2325 """update or merge working directory
2308
2326
2309 Update the working directory to the specified revision.
2327 Update the working directory to the specified revision.
2310
2328
2311 If there are no outstanding changes in the working directory and
2329 If there are no outstanding changes in the working directory and
2312 there is a linear relationship between the current version and the
2330 there is a linear relationship between the current version and the
2313 requested version, the result is the requested version.
2331 requested version, the result is the requested version.
2314
2332
2315 To merge the working directory with another revision, use the
2333 To merge the working directory with another revision, use the
2316 merge command.
2334 merge command.
2317
2335
2318 By default, update will refuse to run if doing so would require
2336 By default, update will refuse to run if doing so would require
2319 merging or discarding local changes.
2337 merging or discarding local changes.
2320 """
2338 """
2321 if date:
2339 if date:
2322 if node:
2340 if node:
2323 raise util.Abort(_("you can't specify a revision and a date"))
2341 raise util.Abort(_("you can't specify a revision and a date"))
2324 node = cmdutil.finddate(ui, repo, date)
2342 node = cmdutil.finddate(ui, repo, date)
2325
2343
2326 node = _lookup(repo, node, branch)
2344 node = _lookup(repo, node, branch)
2327 if clean:
2345 if clean:
2328 return hg.clean(repo, node)
2346 return hg.clean(repo, node)
2329 else:
2347 else:
2330 return hg.update(repo, node)
2348 return hg.update(repo, node)
2331
2349
2332 def _lookup(repo, node, branch=None):
2350 def _lookup(repo, node, branch=None):
2333 if branch:
2351 if branch:
2334 repo.ui.warn(_("the --branch option is deprecated, "
2352 repo.ui.warn(_("the --branch option is deprecated, "
2335 "please use 'hg branch' instead\n"))
2353 "please use 'hg branch' instead\n"))
2336 br = repo.branchlookup(branch=branch)
2354 br = repo.branchlookup(branch=branch)
2337 found = []
2355 found = []
2338 for x in br:
2356 for x in br:
2339 if branch in br[x]:
2357 if branch in br[x]:
2340 found.append(x)
2358 found.append(x)
2341 if len(found) > 1:
2359 if len(found) > 1:
2342 repo.ui.warn(_("Found multiple heads for %s\n") % branch)
2360 repo.ui.warn(_("Found multiple heads for %s\n") % branch)
2343 for x in found:
2361 for x in found:
2344 cmdutil.show_changeset(ui, repo, {}).show(changenode=x)
2362 cmdutil.show_changeset(ui, repo, {}).show(changenode=x)
2345 raise util.Abort("")
2363 raise util.Abort("")
2346 if len(found) == 1:
2364 if len(found) == 1:
2347 node = found[0]
2365 node = found[0]
2348 repo.ui.warn(_("Using head %s for branch %s\n")
2366 repo.ui.warn(_("Using head %s for branch %s\n")
2349 % (short(node), branch))
2367 % (short(node), branch))
2350 else:
2368 else:
2351 raise util.Abort(_("branch %s not found") % branch)
2369 raise util.Abort(_("branch %s not found") % branch)
2352 else:
2370 else:
2353 node = node and repo.lookup(node) or repo.changelog.tip()
2371 node = node and repo.lookup(node) or repo.changelog.tip()
2354 return node
2372 return node
2355
2373
2356 def verify(ui, repo):
2374 def verify(ui, repo):
2357 """verify the integrity of the repository
2375 """verify the integrity of the repository
2358
2376
2359 Verify the integrity of the current repository.
2377 Verify the integrity of the current repository.
2360
2378
2361 This will perform an extensive check of the repository's
2379 This will perform an extensive check of the repository's
2362 integrity, validating the hashes and checksums of each entry in
2380 integrity, validating the hashes and checksums of each entry in
2363 the changelog, manifest, and tracked files, as well as the
2381 the changelog, manifest, and tracked files, as well as the
2364 integrity of their crosslinks and indices.
2382 integrity of their crosslinks and indices.
2365 """
2383 """
2366 return hg.verify(repo)
2384 return hg.verify(repo)
2367
2385
2368 def version_(ui):
2386 def version_(ui):
2369 """output version and copyright information"""
2387 """output version and copyright information"""
2370 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2388 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2371 % version.get_version())
2389 % version.get_version())
2372 ui.status(_(
2390 ui.status(_(
2373 "\nCopyright (C) 2005, 2006 Matt Mackall <mpm@selenic.com>\n"
2391 "\nCopyright (C) 2005, 2006 Matt Mackall <mpm@selenic.com>\n"
2374 "This is free software; see the source for copying conditions. "
2392 "This is free software; see the source for copying conditions. "
2375 "There is NO\nwarranty; "
2393 "There is NO\nwarranty; "
2376 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2394 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2377 ))
2395 ))
2378
2396
2379 # Command options and aliases are listed here, alphabetically
2397 # Command options and aliases are listed here, alphabetically
2380
2398
2381 globalopts = [
2399 globalopts = [
2382 ('R', 'repository', '',
2400 ('R', 'repository', '',
2383 _('repository root directory or symbolic path name')),
2401 _('repository root directory or symbolic path name')),
2384 ('', 'cwd', '', _('change working directory')),
2402 ('', 'cwd', '', _('change working directory')),
2385 ('y', 'noninteractive', None,
2403 ('y', 'noninteractive', None,
2386 _('do not prompt, assume \'yes\' for any required answers')),
2404 _('do not prompt, assume \'yes\' for any required answers')),
2387 ('q', 'quiet', None, _('suppress output')),
2405 ('q', 'quiet', None, _('suppress output')),
2388 ('v', 'verbose', None, _('enable additional output')),
2406 ('v', 'verbose', None, _('enable additional output')),
2389 ('', 'config', [], _('set/override config option')),
2407 ('', 'config', [], _('set/override config option')),
2390 ('', 'debug', None, _('enable debugging output')),
2408 ('', 'debug', None, _('enable debugging output')),
2391 ('', 'debugger', None, _('start debugger')),
2409 ('', 'debugger', None, _('start debugger')),
2392 ('', 'encoding', util._encoding, _('set the charset encoding')),
2410 ('', 'encoding', util._encoding, _('set the charset encoding')),
2393 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2411 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2394 ('', 'lsprof', None, _('print improved command execution profile')),
2412 ('', 'lsprof', None, _('print improved command execution profile')),
2395 ('', 'traceback', None, _('print traceback on exception')),
2413 ('', 'traceback', None, _('print traceback on exception')),
2396 ('', 'time', None, _('time how long the command takes')),
2414 ('', 'time', None, _('time how long the command takes')),
2397 ('', 'profile', None, _('print command execution profile')),
2415 ('', 'profile', None, _('print command execution profile')),
2398 ('', 'version', None, _('output version information and exit')),
2416 ('', 'version', None, _('output version information and exit')),
2399 ('h', 'help', None, _('display help and exit')),
2417 ('h', 'help', None, _('display help and exit')),
2400 ]
2418 ]
2401
2419
2402 dryrunopts = [('n', 'dry-run', None,
2420 dryrunopts = [('n', 'dry-run', None,
2403 _('do not perform actions, just print output'))]
2421 _('do not perform actions, just print output'))]
2404
2422
2405 remoteopts = [
2423 remoteopts = [
2406 ('e', 'ssh', '', _('specify ssh command to use')),
2424 ('e', 'ssh', '', _('specify ssh command to use')),
2407 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2425 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2408 ]
2426 ]
2409
2427
2410 walkopts = [
2428 walkopts = [
2411 ('I', 'include', [], _('include names matching the given patterns')),
2429 ('I', 'include', [], _('include names matching the given patterns')),
2412 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2430 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2413 ]
2431 ]
2414
2432
2415 table = {
2433 table = {
2416 "^add":
2434 "^add":
2417 (add,
2435 (add,
2418 walkopts + dryrunopts,
2436 walkopts + dryrunopts,
2419 _('hg add [OPTION]... [FILE]...')),
2437 _('hg add [OPTION]... [FILE]...')),
2420 "addremove":
2438 "addremove":
2421 (addremove,
2439 (addremove,
2422 [('s', 'similarity', '',
2440 [('s', 'similarity', '',
2423 _('guess renamed files by similarity (0<=s<=100)')),
2441 _('guess renamed files by similarity (0<=s<=100)')),
2424 ] + walkopts + dryrunopts,
2442 ] + walkopts + dryrunopts,
2425 _('hg addremove [OPTION]... [FILE]...')),
2443 _('hg addremove [OPTION]... [FILE]...')),
2426 "^annotate":
2444 "^annotate":
2427 (annotate,
2445 (annotate,
2428 [('r', 'rev', '', _('annotate the specified revision')),
2446 [('r', 'rev', '', _('annotate the specified revision')),
2429 ('f', 'follow', None, _('follow file copies and renames')),
2447 ('f', 'follow', None, _('follow file copies and renames')),
2430 ('a', 'text', None, _('treat all files as text')),
2448 ('a', 'text', None, _('treat all files as text')),
2431 ('u', 'user', None, _('list the author')),
2449 ('u', 'user', None, _('list the author')),
2432 ('d', 'date', None, _('list the date')),
2450 ('d', 'date', None, _('list the date')),
2433 ('n', 'number', None, _('list the revision number (default)')),
2451 ('n', 'number', None, _('list the revision number (default)')),
2434 ('c', 'changeset', None, _('list the changeset')),
2452 ('c', 'changeset', None, _('list the changeset')),
2435 ] + walkopts,
2453 ] + walkopts,
2436 _('hg annotate [-r REV] [-a] [-u] [-d] [-n] [-c] FILE...')),
2454 _('hg annotate [-r REV] [-a] [-u] [-d] [-n] [-c] FILE...')),
2437 "archive":
2455 "archive":
2438 (archive,
2456 (archive,
2439 [('', 'no-decode', None, _('do not pass files through decoders')),
2457 [('', 'no-decode', None, _('do not pass files through decoders')),
2440 ('p', 'prefix', '', _('directory prefix for files in archive')),
2458 ('p', 'prefix', '', _('directory prefix for files in archive')),
2441 ('r', 'rev', '', _('revision to distribute')),
2459 ('r', 'rev', '', _('revision to distribute')),
2442 ('t', 'type', '', _('type of distribution to create')),
2460 ('t', 'type', '', _('type of distribution to create')),
2443 ] + walkopts,
2461 ] + walkopts,
2444 _('hg archive [OPTION]... DEST')),
2462 _('hg archive [OPTION]... DEST')),
2445 "backout":
2463 "backout":
2446 (backout,
2464 (backout,
2447 [('', 'merge', None,
2465 [('', 'merge', None,
2448 _('merge with old dirstate parent after backout')),
2466 _('merge with old dirstate parent after backout')),
2449 ('m', 'message', '', _('use <text> as commit message')),
2467 ('m', 'message', '', _('use <text> as commit message')),
2450 ('l', 'logfile', '', _('read commit message from <file>')),
2468 ('l', 'logfile', '', _('read commit message from <file>')),
2451 ('d', 'date', '', _('record datecode as commit date')),
2469 ('d', 'date', '', _('record datecode as commit date')),
2452 ('', 'parent', '', _('parent to choose when backing out merge')),
2470 ('', 'parent', '', _('parent to choose when backing out merge')),
2453 ('u', 'user', '', _('record user as committer')),
2471 ('u', 'user', '', _('record user as committer')),
2454 ] + walkopts,
2472 ] + walkopts,
2455 _('hg backout [OPTION]... REV')),
2473 _('hg backout [OPTION]... REV')),
2456 "branch": (branch, [], _('hg branch [NAME]')),
2474 "branch": (branch, [], _('hg branch [NAME]')),
2457 "branches": (branches, [], _('hg branches')),
2475 "branches": (branches, [], _('hg branches')),
2458 "bundle":
2476 "bundle":
2459 (bundle,
2477 (bundle,
2460 [('f', 'force', None,
2478 [('f', 'force', None,
2461 _('run even when remote repository is unrelated')),
2479 _('run even when remote repository is unrelated')),
2462 ('r', 'rev', [],
2480 ('r', 'rev', [],
2463 _('a changeset you would like to bundle')),
2481 _('a changeset you would like to bundle')),
2464 ('', 'base', [],
2482 ('', 'base', [],
2465 _('a base changeset to specify instead of a destination')),
2483 _('a base changeset to specify instead of a destination')),
2466 ] + remoteopts,
2484 ] + remoteopts,
2467 _('hg bundle [--base REV]... [--rev REV]... FILE [DEST]')),
2485 _('hg bundle [--base REV]... [--rev REV]... FILE [DEST]')),
2468 "cat":
2486 "cat":
2469 (cat,
2487 (cat,
2470 [('o', 'output', '', _('print output to file with formatted name')),
2488 [('o', 'output', '', _('print output to file with formatted name')),
2471 ('r', 'rev', '', _('print the given revision')),
2489 ('r', 'rev', '', _('print the given revision')),
2472 ] + walkopts,
2490 ] + walkopts,
2473 _('hg cat [OPTION]... FILE...')),
2491 _('hg cat [OPTION]... FILE...')),
2474 "^clone":
2492 "^clone":
2475 (clone,
2493 (clone,
2476 [('U', 'noupdate', None, _('do not update the new working directory')),
2494 [('U', 'noupdate', None, _('do not update the new working directory')),
2477 ('r', 'rev', [],
2495 ('r', 'rev', [],
2478 _('a changeset you would like to have after cloning')),
2496 _('a changeset you would like to have after cloning')),
2479 ('', 'pull', None, _('use pull protocol to copy metadata')),
2497 ('', 'pull', None, _('use pull protocol to copy metadata')),
2480 ('', 'uncompressed', None,
2498 ('', 'uncompressed', None,
2481 _('use uncompressed transfer (fast over LAN)')),
2499 _('use uncompressed transfer (fast over LAN)')),
2482 ] + remoteopts,
2500 ] + remoteopts,
2483 _('hg clone [OPTION]... SOURCE [DEST]')),
2501 _('hg clone [OPTION]... SOURCE [DEST]')),
2484 "^commit|ci":
2502 "^commit|ci":
2485 (commit,
2503 (commit,
2486 [('A', 'addremove', None,
2504 [('A', 'addremove', None,
2487 _('mark new/missing files as added/removed before committing')),
2505 _('mark new/missing files as added/removed before committing')),
2488 ('m', 'message', '', _('use <text> as commit message')),
2506 ('m', 'message', '', _('use <text> as commit message')),
2489 ('l', 'logfile', '', _('read the commit message from <file>')),
2507 ('l', 'logfile', '', _('read the commit message from <file>')),
2490 ('d', 'date', '', _('record datecode as commit date')),
2508 ('d', 'date', '', _('record datecode as commit date')),
2491 ('u', 'user', '', _('record user as commiter')),
2509 ('u', 'user', '', _('record user as commiter')),
2492 ] + walkopts,
2510 ] + walkopts,
2493 _('hg commit [OPTION]... [FILE]...')),
2511 _('hg commit [OPTION]... [FILE]...')),
2494 "copy|cp":
2512 "copy|cp":
2495 (copy,
2513 (copy,
2496 [('A', 'after', None, _('record a copy that has already occurred')),
2514 [('A', 'after', None, _('record a copy that has already occurred')),
2497 ('f', 'force', None,
2515 ('f', 'force', None,
2498 _('forcibly copy over an existing managed file')),
2516 _('forcibly copy over an existing managed file')),
2499 ] + walkopts + dryrunopts,
2517 ] + walkopts + dryrunopts,
2500 _('hg copy [OPTION]... [SOURCE]... DEST')),
2518 _('hg copy [OPTION]... [SOURCE]... DEST')),
2501 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2519 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2502 "debugcomplete":
2520 "debugcomplete":
2503 (debugcomplete,
2521 (debugcomplete,
2504 [('o', 'options', None, _('show the command options'))],
2522 [('o', 'options', None, _('show the command options'))],
2505 _('debugcomplete [-o] CMD')),
2523 _('debugcomplete [-o] CMD')),
2506 "debugrebuildstate":
2524 "debugrebuildstate":
2507 (debugrebuildstate,
2525 (debugrebuildstate,
2508 [('r', 'rev', '', _('revision to rebuild to'))],
2526 [('r', 'rev', '', _('revision to rebuild to'))],
2509 _('debugrebuildstate [-r REV] [REV]')),
2527 _('debugrebuildstate [-r REV] [REV]')),
2510 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2528 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2511 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2529 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2512 "debugstate": (debugstate, [], _('debugstate')),
2530 "debugstate": (debugstate, [], _('debugstate')),
2513 "debugdate": (debugdate,
2531 "debugdate": (debugdate,
2514 [('e','extended', None, _('try extended date formats'))],
2532 [('e','extended', None, _('try extended date formats'))],
2515 _('debugdata [-e] DATE [RANGE]')),
2533 _('debugdata [-e] DATE [RANGE]')),
2516 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2534 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2517 "debugindex": (debugindex, [], _('debugindex FILE')),
2535 "debugindex": (debugindex, [], _('debugindex FILE')),
2518 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2536 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2519 "debugrename": (debugrename, [], _('debugrename FILE [REV]')),
2537 "debugrename": (debugrename, [], _('debugrename FILE [REV]')),
2520 "debugwalk":
2538 "debugwalk":
2521 (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')),
2539 (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')),
2522 "^diff":
2540 "^diff":
2523 (diff,
2541 (diff,
2524 [('r', 'rev', [], _('revision')),
2542 [('r', 'rev', [], _('revision')),
2525 ('a', 'text', None, _('treat all files as text')),
2543 ('a', 'text', None, _('treat all files as text')),
2526 ('p', 'show-function', None,
2544 ('p', 'show-function', None,
2527 _('show which function each change is in')),
2545 _('show which function each change is in')),
2528 ('g', 'git', None, _('use git extended diff format')),
2546 ('g', 'git', None, _('use git extended diff format')),
2529 ('', 'nodates', None, _("don't include dates in diff headers")),
2547 ('', 'nodates', None, _("don't include dates in diff headers")),
2530 ('w', 'ignore-all-space', None,
2548 ('w', 'ignore-all-space', None,
2531 _('ignore white space when comparing lines')),
2549 _('ignore white space when comparing lines')),
2532 ('b', 'ignore-space-change', None,
2550 ('b', 'ignore-space-change', None,
2533 _('ignore changes in the amount of white space')),
2551 _('ignore changes in the amount of white space')),
2534 ('B', 'ignore-blank-lines', None,
2552 ('B', 'ignore-blank-lines', None,
2535 _('ignore changes whose lines are all blank')),
2553 _('ignore changes whose lines are all blank')),
2536 ] + walkopts,
2554 ] + walkopts,
2537 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2555 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2538 "^export":
2556 "^export":
2539 (export,
2557 (export,
2540 [('o', 'output', '', _('print output to file with formatted name')),
2558 [('o', 'output', '', _('print output to file with formatted name')),
2541 ('a', 'text', None, _('treat all files as text')),
2559 ('a', 'text', None, _('treat all files as text')),
2542 ('g', 'git', None, _('use git extended diff format')),
2560 ('g', 'git', None, _('use git extended diff format')),
2543 ('', 'nodates', None, _("don't include dates in diff headers")),
2561 ('', 'nodates', None, _("don't include dates in diff headers")),
2544 ('', 'switch-parent', None, _('diff against the second parent'))],
2562 ('', 'switch-parent', None, _('diff against the second parent'))],
2545 _('hg export [-a] [-o OUTFILESPEC] REV...')),
2563 _('hg export [-a] [-o OUTFILESPEC] REV...')),
2546 "grep":
2564 "grep":
2547 (grep,
2565 (grep,
2548 [('0', 'print0', None, _('end fields with NUL')),
2566 [('0', 'print0', None, _('end fields with NUL')),
2549 ('', 'all', None, _('print all revisions that match')),
2567 ('', 'all', None, _('print all revisions that match')),
2550 ('f', 'follow', None,
2568 ('f', 'follow', None,
2551 _('follow changeset history, or file history across copies and renames')),
2569 _('follow changeset history, or file history across copies and renames')),
2552 ('i', 'ignore-case', None, _('ignore case when matching')),
2570 ('i', 'ignore-case', None, _('ignore case when matching')),
2553 ('l', 'files-with-matches', None,
2571 ('l', 'files-with-matches', None,
2554 _('print only filenames and revs that match')),
2572 _('print only filenames and revs that match')),
2555 ('n', 'line-number', None, _('print matching line numbers')),
2573 ('n', 'line-number', None, _('print matching line numbers')),
2556 ('r', 'rev', [], _('search in given revision range')),
2574 ('r', 'rev', [], _('search in given revision range')),
2557 ('u', 'user', None, _('print user who committed change')),
2575 ('u', 'user', None, _('print user who committed change')),
2558 ] + walkopts,
2576 ] + walkopts,
2559 _('hg grep [OPTION]... PATTERN [FILE]...')),
2577 _('hg grep [OPTION]... PATTERN [FILE]...')),
2560 "heads":
2578 "heads":
2561 (heads,
2579 (heads,
2562 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2580 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2563 ('', 'style', '', _('display using template map file')),
2581 ('', 'style', '', _('display using template map file')),
2564 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2582 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2565 ('', 'template', '', _('display with template'))],
2583 ('', 'template', '', _('display with template'))],
2566 _('hg heads [-r REV]')),
2584 _('hg heads [-r REV]')),
2567 "help": (help_, [], _('hg help [COMMAND]')),
2585 "help": (help_, [], _('hg help [COMMAND]')),
2568 "identify|id": (identify, [], _('hg identify')),
2586 "identify|id": (identify, [], _('hg identify')),
2569 "import|patch":
2587 "import|patch":
2570 (import_,
2588 (import_,
2571 [('p', 'strip', 1,
2589 [('p', 'strip', 1,
2572 _('directory strip option for patch. This has the same\n'
2590 _('directory strip option for patch. This has the same\n'
2573 'meaning as the corresponding patch option')),
2591 'meaning as the corresponding patch option')),
2574 ('m', 'message', '', _('use <text> as commit message')),
2592 ('m', 'message', '', _('use <text> as commit message')),
2575 ('b', 'base', '', _('base path (DEPRECATED)')),
2593 ('b', 'base', '', _('base path (DEPRECATED)')),
2576 ('f', 'force', None,
2594 ('f', 'force', None,
2577 _('skip check for outstanding uncommitted changes'))],
2595 _('skip check for outstanding uncommitted changes'))],
2578 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')),
2596 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')),
2579 "incoming|in": (incoming,
2597 "incoming|in": (incoming,
2580 [('M', 'no-merges', None, _('do not show merges')),
2598 [('M', 'no-merges', None, _('do not show merges')),
2581 ('f', 'force', None,
2599 ('f', 'force', None,
2582 _('run even when remote repository is unrelated')),
2600 _('run even when remote repository is unrelated')),
2583 ('', 'style', '', _('display using template map file')),
2601 ('', 'style', '', _('display using template map file')),
2584 ('n', 'newest-first', None, _('show newest record first')),
2602 ('n', 'newest-first', None, _('show newest record first')),
2585 ('', 'bundle', '', _('file to store the bundles into')),
2603 ('', 'bundle', '', _('file to store the bundles into')),
2586 ('p', 'patch', None, _('show patch')),
2604 ('p', 'patch', None, _('show patch')),
2587 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2605 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2588 ('', 'template', '', _('display with template')),
2606 ('', 'template', '', _('display with template')),
2589 ] + remoteopts,
2607 ] + remoteopts,
2590 _('hg incoming [-p] [-n] [-M] [-r REV]...'
2608 _('hg incoming [-p] [-n] [-M] [-r REV]...'
2591 ' [--bundle FILENAME] [SOURCE]')),
2609 ' [--bundle FILENAME] [SOURCE]')),
2592 "^init":
2610 "^init":
2593 (init, remoteopts, _('hg init [-e FILE] [--remotecmd FILE] [DEST]')),
2611 (init, remoteopts, _('hg init [-e FILE] [--remotecmd FILE] [DEST]')),
2594 "locate":
2612 "locate":
2595 (locate,
2613 (locate,
2596 [('r', 'rev', '', _('search the repository as it stood at rev')),
2614 [('r', 'rev', '', _('search the repository as it stood at rev')),
2597 ('0', 'print0', None,
2615 ('0', 'print0', None,
2598 _('end filenames with NUL, for use with xargs')),
2616 _('end filenames with NUL, for use with xargs')),
2599 ('f', 'fullpath', None,
2617 ('f', 'fullpath', None,
2600 _('print complete paths from the filesystem root')),
2618 _('print complete paths from the filesystem root')),
2601 ] + walkopts,
2619 ] + walkopts,
2602 _('hg locate [OPTION]... [PATTERN]...')),
2620 _('hg locate [OPTION]... [PATTERN]...')),
2603 "^log|history":
2621 "^log|history":
2604 (log,
2622 (log,
2605 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2623 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2606 ('f', 'follow', None,
2624 ('f', 'follow', None,
2607 _('follow changeset history, or file history across copies and renames')),
2625 _('follow changeset history, or file history across copies and renames')),
2608 ('', 'follow-first', None,
2626 ('', 'follow-first', None,
2609 _('only follow the first parent of merge changesets')),
2627 _('only follow the first parent of merge changesets')),
2610 ('d', 'date', '', _('show revs matching date spec')),
2628 ('d', 'date', '', _('show revs matching date spec')),
2611 ('C', 'copies', None, _('show copied files')),
2629 ('C', 'copies', None, _('show copied files')),
2612 ('k', 'keyword', [], _('search for a keyword')),
2630 ('k', 'keyword', [], _('search for a keyword')),
2613 ('l', 'limit', '', _('limit number of changes displayed')),
2631 ('l', 'limit', '', _('limit number of changes displayed')),
2614 ('r', 'rev', [], _('show the specified revision or range')),
2632 ('r', 'rev', [], _('show the specified revision or range')),
2615 ('', 'removed', None, _('include revs where files were removed')),
2633 ('', 'removed', None, _('include revs where files were removed')),
2616 ('M', 'no-merges', None, _('do not show merges')),
2634 ('M', 'no-merges', None, _('do not show merges')),
2617 ('', 'style', '', _('display using template map file')),
2635 ('', 'style', '', _('display using template map file')),
2618 ('m', 'only-merges', None, _('show only merges')),
2636 ('m', 'only-merges', None, _('show only merges')),
2619 ('p', 'patch', None, _('show patch')),
2637 ('p', 'patch', None, _('show patch')),
2620 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2638 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2621 ('', 'template', '', _('display with template')),
2639 ('', 'template', '', _('display with template')),
2622 ] + walkopts,
2640 ] + walkopts,
2623 _('hg log [OPTION]... [FILE]')),
2641 _('hg log [OPTION]... [FILE]')),
2624 "manifest": (manifest, [], _('hg manifest [REV]')),
2642 "manifest": (manifest, [], _('hg manifest [REV]')),
2625 "merge":
2643 "merge":
2626 (merge,
2644 (merge,
2627 [('b', 'branch', '', _('merge with head of a specific branch (DEPRECATED)')),
2645 [('b', 'branch', '', _('merge with head of a specific branch (DEPRECATED)')),
2628 ('f', 'force', None, _('force a merge with outstanding changes'))],
2646 ('f', 'force', None, _('force a merge with outstanding changes'))],
2629 _('hg merge [-f] [REV]')),
2647 _('hg merge [-f] [REV]')),
2630 "outgoing|out": (outgoing,
2648 "outgoing|out": (outgoing,
2631 [('M', 'no-merges', None, _('do not show merges')),
2649 [('M', 'no-merges', None, _('do not show merges')),
2632 ('f', 'force', None,
2650 ('f', 'force', None,
2633 _('run even when remote repository is unrelated')),
2651 _('run even when remote repository is unrelated')),
2634 ('p', 'patch', None, _('show patch')),
2652 ('p', 'patch', None, _('show patch')),
2635 ('', 'style', '', _('display using template map file')),
2653 ('', 'style', '', _('display using template map file')),
2636 ('r', 'rev', [], _('a specific revision you would like to push')),
2654 ('r', 'rev', [], _('a specific revision you would like to push')),
2637 ('n', 'newest-first', None, _('show newest record first')),
2655 ('n', 'newest-first', None, _('show newest record first')),
2638 ('', 'template', '', _('display with template')),
2656 ('', 'template', '', _('display with template')),
2639 ] + remoteopts,
2657 ] + remoteopts,
2640 _('hg outgoing [-M] [-p] [-n] [-r REV]... [DEST]')),
2658 _('hg outgoing [-M] [-p] [-n] [-r REV]... [DEST]')),
2641 "^parents":
2659 "^parents":
2642 (parents,
2660 (parents,
2643 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2661 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2644 ('r', 'rev', '', _('show parents from the specified rev')),
2662 ('r', 'rev', '', _('show parents from the specified rev')),
2645 ('', 'style', '', _('display using template map file')),
2663 ('', 'style', '', _('display using template map file')),
2646 ('', 'template', '', _('display with template'))],
2664 ('', 'template', '', _('display with template'))],
2647 _('hg parents [-r REV] [FILE]')),
2665 _('hg parents [-r REV] [FILE]')),
2648 "paths": (paths, [], _('hg paths [NAME]')),
2666 "paths": (paths, [], _('hg paths [NAME]')),
2649 "^pull":
2667 "^pull":
2650 (pull,
2668 (pull,
2651 [('u', 'update', None,
2669 [('u', 'update', None,
2652 _('update to new tip if changesets were pulled')),
2670 _('update to new tip if changesets were pulled')),
2653 ('f', 'force', None,
2671 ('f', 'force', None,
2654 _('run even when remote repository is unrelated')),
2672 _('run even when remote repository is unrelated')),
2655 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2673 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2656 ] + remoteopts,
2674 ] + remoteopts,
2657 _('hg pull [-u] [-r REV]... [-e FILE] [--remotecmd FILE] [SOURCE]')),
2675 _('hg pull [-u] [-r REV]... [-e FILE] [--remotecmd FILE] [SOURCE]')),
2658 "^push":
2676 "^push":
2659 (push,
2677 (push,
2660 [('f', 'force', None, _('force push')),
2678 [('f', 'force', None, _('force push')),
2661 ('r', 'rev', [], _('a specific revision you would like to push')),
2679 ('r', 'rev', [], _('a specific revision you would like to push')),
2662 ] + remoteopts,
2680 ] + remoteopts,
2663 _('hg push [-f] [-r REV]... [-e FILE] [--remotecmd FILE] [DEST]')),
2681 _('hg push [-f] [-r REV]... [-e FILE] [--remotecmd FILE] [DEST]')),
2664 "debugrawcommit|rawcommit":
2682 "debugrawcommit|rawcommit":
2665 (rawcommit,
2683 (rawcommit,
2666 [('p', 'parent', [], _('parent')),
2684 [('p', 'parent', [], _('parent')),
2667 ('d', 'date', '', _('date code')),
2685 ('d', 'date', '', _('date code')),
2668 ('u', 'user', '', _('user')),
2686 ('u', 'user', '', _('user')),
2669 ('F', 'files', '', _('file list')),
2687 ('F', 'files', '', _('file list')),
2670 ('m', 'message', '', _('commit message')),
2688 ('m', 'message', '', _('commit message')),
2671 ('l', 'logfile', '', _('commit message file'))],
2689 ('l', 'logfile', '', _('commit message file'))],
2672 _('hg debugrawcommit [OPTION]... [FILE]...')),
2690 _('hg debugrawcommit [OPTION]... [FILE]...')),
2673 "recover": (recover, [], _('hg recover')),
2691 "recover": (recover, [], _('hg recover')),
2674 "^remove|rm":
2692 "^remove|rm":
2675 (remove,
2693 (remove,
2676 [('A', 'after', None, _('record remove that has already occurred')),
2694 [('A', 'after', None, _('record remove that has already occurred')),
2677 ('f', 'force', None, _('remove file even if modified')),
2695 ('f', 'force', None, _('remove file even if modified')),
2678 ] + walkopts,
2696 ] + walkopts,
2679 _('hg remove [OPTION]... FILE...')),
2697 _('hg remove [OPTION]... FILE...')),
2680 "rename|mv":
2698 "rename|mv":
2681 (rename,
2699 (rename,
2682 [('A', 'after', None, _('record a rename that has already occurred')),
2700 [('A', 'after', None, _('record a rename that has already occurred')),
2683 ('f', 'force', None,
2701 ('f', 'force', None,
2684 _('forcibly copy over an existing managed file')),
2702 _('forcibly copy over an existing managed file')),
2685 ] + walkopts + dryrunopts,
2703 ] + walkopts + dryrunopts,
2686 _('hg rename [OPTION]... SOURCE... DEST')),
2704 _('hg rename [OPTION]... SOURCE... DEST')),
2687 "^revert":
2705 "^revert":
2688 (revert,
2706 (revert,
2689 [('a', 'all', None, _('revert all changes when no arguments given')),
2707 [('a', 'all', None, _('revert all changes when no arguments given')),
2690 ('d', 'date', '', _('tipmost revision matching date')),
2708 ('d', 'date', '', _('tipmost revision matching date')),
2691 ('r', 'rev', '', _('revision to revert to')),
2709 ('r', 'rev', '', _('revision to revert to')),
2692 ('', 'no-backup', None, _('do not save backup copies of files')),
2710 ('', 'no-backup', None, _('do not save backup copies of files')),
2693 ] + walkopts + dryrunopts,
2711 ] + walkopts + dryrunopts,
2694 _('hg revert [-r REV] [NAME]...')),
2712 _('hg revert [-r REV] [NAME]...')),
2695 "rollback": (rollback, [], _('hg rollback')),
2713 "rollback": (rollback, [], _('hg rollback')),
2696 "root": (root, [], _('hg root')),
2714 "root": (root, [], _('hg root')),
2697 "showconfig|debugconfig":
2715 "showconfig|debugconfig":
2698 (showconfig,
2716 (showconfig,
2699 [('u', 'untrusted', None, _('show untrusted configuration options'))],
2717 [('u', 'untrusted', None, _('show untrusted configuration options'))],
2700 _('showconfig [-u] [NAME]...')),
2718 _('showconfig [-u] [NAME]...')),
2701 "^serve":
2719 "^serve":
2702 (serve,
2720 (serve,
2703 [('A', 'accesslog', '', _('name of access log file to write to')),
2721 [('A', 'accesslog', '', _('name of access log file to write to')),
2704 ('d', 'daemon', None, _('run server in background')),
2722 ('d', 'daemon', None, _('run server in background')),
2705 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
2723 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
2706 ('E', 'errorlog', '', _('name of error log file to write to')),
2724 ('E', 'errorlog', '', _('name of error log file to write to')),
2707 ('p', 'port', 0, _('port to use (default: 8000)')),
2725 ('p', 'port', 0, _('port to use (default: 8000)')),
2708 ('a', 'address', '', _('address to use')),
2726 ('a', 'address', '', _('address to use')),
2709 ('n', 'name', '',
2727 ('n', 'name', '',
2710 _('name to show in web pages (default: working dir)')),
2728 _('name to show in web pages (default: working dir)')),
2711 ('', 'webdir-conf', '', _('name of the webdir config file'
2729 ('', 'webdir-conf', '', _('name of the webdir config file'
2712 ' (serve more than one repo)')),
2730 ' (serve more than one repo)')),
2713 ('', 'pid-file', '', _('name of file to write process ID to')),
2731 ('', 'pid-file', '', _('name of file to write process ID to')),
2714 ('', 'stdio', None, _('for remote clients')),
2732 ('', 'stdio', None, _('for remote clients')),
2715 ('t', 'templates', '', _('web templates to use')),
2733 ('t', 'templates', '', _('web templates to use')),
2716 ('', 'style', '', _('template style to use')),
2734 ('', 'style', '', _('template style to use')),
2717 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2735 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2718 _('hg serve [OPTION]...')),
2736 _('hg serve [OPTION]...')),
2719 "^status|st":
2737 "^status|st":
2720 (status,
2738 (status,
2721 [('A', 'all', None, _('show status of all files')),
2739 [('A', 'all', None, _('show status of all files')),
2722 ('m', 'modified', None, _('show only modified files')),
2740 ('m', 'modified', None, _('show only modified files')),
2723 ('a', 'added', None, _('show only added files')),
2741 ('a', 'added', None, _('show only added files')),
2724 ('r', 'removed', None, _('show only removed files')),
2742 ('r', 'removed', None, _('show only removed files')),
2725 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
2743 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
2726 ('c', 'clean', None, _('show only files without changes')),
2744 ('c', 'clean', None, _('show only files without changes')),
2727 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2745 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2728 ('i', 'ignored', None, _('show ignored files')),
2746 ('i', 'ignored', None, _('show ignored files')),
2729 ('n', 'no-status', None, _('hide status prefix')),
2747 ('n', 'no-status', None, _('hide status prefix')),
2730 ('C', 'copies', None, _('show source of copied files')),
2748 ('C', 'copies', None, _('show source of copied files')),
2731 ('0', 'print0', None,
2749 ('0', 'print0', None,
2732 _('end filenames with NUL, for use with xargs')),
2750 _('end filenames with NUL, for use with xargs')),
2733 ('', 'rev', [], _('show difference from revision')),
2751 ('', 'rev', [], _('show difference from revision')),
2734 ] + walkopts,
2752 ] + walkopts,
2735 _('hg status [OPTION]... [FILE]...')),
2753 _('hg status [OPTION]... [FILE]...')),
2736 "tag":
2754 "tag":
2737 (tag,
2755 (tag,
2738 [('l', 'local', None, _('make the tag local')),
2756 [('l', 'local', None, _('make the tag local')),
2739 ('m', 'message', '', _('message for tag commit log entry')),
2757 ('m', 'message', '', _('message for tag commit log entry')),
2740 ('d', 'date', '', _('record datecode as commit date')),
2758 ('d', 'date', '', _('record datecode as commit date')),
2741 ('u', 'user', '', _('record user as commiter')),
2759 ('u', 'user', '', _('record user as commiter')),
2742 ('r', 'rev', '', _('revision to tag'))],
2760 ('r', 'rev', '', _('revision to tag'))],
2743 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
2761 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
2744 "tags": (tags, [], _('hg tags')),
2762 "tags": (tags, [], _('hg tags')),
2745 "tip":
2763 "tip":
2746 (tip,
2764 (tip,
2747 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2765 [('b', 'branches', None, _('show branches (DEPRECATED)')),
2748 ('', 'style', '', _('display using template map file')),
2766 ('', 'style', '', _('display using template map file')),
2749 ('p', 'patch', None, _('show patch')),
2767 ('p', 'patch', None, _('show patch')),
2750 ('', 'template', '', _('display with template'))],
2768 ('', 'template', '', _('display with template'))],
2751 _('hg tip [-p]')),
2769 _('hg tip [-p]')),
2752 "unbundle":
2770 "unbundle":
2753 (unbundle,
2771 (unbundle,
2754 [('u', 'update', None,
2772 [('u', 'update', None,
2755 _('update to new tip if changesets were unbundled'))],
2773 _('update to new tip if changesets were unbundled'))],
2756 _('hg unbundle [-u] FILE')),
2774 _('hg unbundle [-u] FILE')),
2757 "^update|up|checkout|co":
2775 "^update|up|checkout|co":
2758 (update,
2776 (update,
2759 [('b', 'branch', '',
2777 [('b', 'branch', '',
2760 _('checkout the head of a specific branch (DEPRECATED)')),
2778 _('checkout the head of a specific branch (DEPRECATED)')),
2761 ('C', 'clean', None, _('overwrite locally modified files')),
2779 ('C', 'clean', None, _('overwrite locally modified files')),
2762 ('d', 'date', '', _('tipmost revision matching date'))],
2780 ('d', 'date', '', _('tipmost revision matching date'))],
2763 _('hg update [-C] [REV]')),
2781 _('hg update [-C] [REV]')),
2764 "verify": (verify, [], _('hg verify')),
2782 "verify": (verify, [], _('hg verify')),
2765 "version": (version_, [], _('hg version')),
2783 "version": (version_, [], _('hg version')),
2766 }
2784 }
2767
2785
2768 norepo = ("clone init version help debugancestor debugcomplete debugdata"
2786 norepo = ("clone init version help debugancestor debugcomplete debugdata"
2769 " debugindex debugindexdot debugdate")
2787 " debugindex debugindexdot debugdate")
2770 optionalrepo = ("paths serve showconfig")
2788 optionalrepo = ("paths serve showconfig")
2771
2789
2772 def findpossible(ui, cmd):
2790 def findpossible(ui, cmd):
2773 """
2791 """
2774 Return cmd -> (aliases, command table entry)
2792 Return cmd -> (aliases, command table entry)
2775 for each matching command.
2793 for each matching command.
2776 Return debug commands (or their aliases) only if no normal command matches.
2794 Return debug commands (or their aliases) only if no normal command matches.
2777 """
2795 """
2778 choice = {}
2796 choice = {}
2779 debugchoice = {}
2797 debugchoice = {}
2780 for e in table.keys():
2798 for e in table.keys():
2781 aliases = e.lstrip("^").split("|")
2799 aliases = e.lstrip("^").split("|")
2782 found = None
2800 found = None
2783 if cmd in aliases:
2801 if cmd in aliases:
2784 found = cmd
2802 found = cmd
2785 elif not ui.config("ui", "strict"):
2803 elif not ui.config("ui", "strict"):
2786 for a in aliases:
2804 for a in aliases:
2787 if a.startswith(cmd):
2805 if a.startswith(cmd):
2788 found = a
2806 found = a
2789 break
2807 break
2790 if found is not None:
2808 if found is not None:
2791 if aliases[0].startswith("debug") or found.startswith("debug"):
2809 if aliases[0].startswith("debug") or found.startswith("debug"):
2792 debugchoice[found] = (aliases, table[e])
2810 debugchoice[found] = (aliases, table[e])
2793 else:
2811 else:
2794 choice[found] = (aliases, table[e])
2812 choice[found] = (aliases, table[e])
2795
2813
2796 if not choice and debugchoice:
2814 if not choice and debugchoice:
2797 choice = debugchoice
2815 choice = debugchoice
2798
2816
2799 return choice
2817 return choice
2800
2818
2801 def findcmd(ui, cmd):
2819 def findcmd(ui, cmd):
2802 """Return (aliases, command table entry) for command string."""
2820 """Return (aliases, command table entry) for command string."""
2803 choice = findpossible(ui, cmd)
2821 choice = findpossible(ui, cmd)
2804
2822
2805 if choice.has_key(cmd):
2823 if choice.has_key(cmd):
2806 return choice[cmd]
2824 return choice[cmd]
2807
2825
2808 if len(choice) > 1:
2826 if len(choice) > 1:
2809 clist = choice.keys()
2827 clist = choice.keys()
2810 clist.sort()
2828 clist.sort()
2811 raise AmbiguousCommand(cmd, clist)
2829 raise AmbiguousCommand(cmd, clist)
2812
2830
2813 if choice:
2831 if choice:
2814 return choice.values()[0]
2832 return choice.values()[0]
2815
2833
2816 raise UnknownCommand(cmd)
2834 raise UnknownCommand(cmd)
2817
2835
2818 def catchterm(*args):
2836 def catchterm(*args):
2819 raise util.SignalInterrupt
2837 raise util.SignalInterrupt
2820
2838
2821 def run():
2839 def run():
2822 sys.exit(dispatch(sys.argv[1:]))
2840 sys.exit(dispatch(sys.argv[1:]))
2823
2841
2824 class ParseError(Exception):
2842 class ParseError(Exception):
2825 """Exception raised on errors in parsing the command line."""
2843 """Exception raised on errors in parsing the command line."""
2826
2844
2827 def parse(ui, args):
2845 def parse(ui, args):
2828 options = {}
2846 options = {}
2829 cmdoptions = {}
2847 cmdoptions = {}
2830
2848
2831 try:
2849 try:
2832 args = fancyopts.fancyopts(args, globalopts, options)
2850 args = fancyopts.fancyopts(args, globalopts, options)
2833 except fancyopts.getopt.GetoptError, inst:
2851 except fancyopts.getopt.GetoptError, inst:
2834 raise ParseError(None, inst)
2852 raise ParseError(None, inst)
2835
2853
2836 if args:
2854 if args:
2837 cmd, args = args[0], args[1:]
2855 cmd, args = args[0], args[1:]
2838 aliases, i = findcmd(ui, cmd)
2856 aliases, i = findcmd(ui, cmd)
2839 cmd = aliases[0]
2857 cmd = aliases[0]
2840 defaults = ui.config("defaults", cmd)
2858 defaults = ui.config("defaults", cmd)
2841 if defaults:
2859 if defaults:
2842 args = shlex.split(defaults) + args
2860 args = shlex.split(defaults) + args
2843 c = list(i[1])
2861 c = list(i[1])
2844 else:
2862 else:
2845 cmd = None
2863 cmd = None
2846 c = []
2864 c = []
2847
2865
2848 # combine global options into local
2866 # combine global options into local
2849 for o in globalopts:
2867 for o in globalopts:
2850 c.append((o[0], o[1], options[o[1]], o[3]))
2868 c.append((o[0], o[1], options[o[1]], o[3]))
2851
2869
2852 try:
2870 try:
2853 args = fancyopts.fancyopts(args, c, cmdoptions)
2871 args = fancyopts.fancyopts(args, c, cmdoptions)
2854 except fancyopts.getopt.GetoptError, inst:
2872 except fancyopts.getopt.GetoptError, inst:
2855 raise ParseError(cmd, inst)
2873 raise ParseError(cmd, inst)
2856
2874
2857 # separate global options back out
2875 # separate global options back out
2858 for o in globalopts:
2876 for o in globalopts:
2859 n = o[1]
2877 n = o[1]
2860 options[n] = cmdoptions[n]
2878 options[n] = cmdoptions[n]
2861 del cmdoptions[n]
2879 del cmdoptions[n]
2862
2880
2863 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
2881 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
2864
2882
2865 external = {}
2883 external = {}
2866
2884
2867 def findext(name):
2885 def findext(name):
2868 '''return module with given extension name'''
2886 '''return module with given extension name'''
2869 try:
2887 try:
2870 return sys.modules[external[name]]
2888 return sys.modules[external[name]]
2871 except KeyError:
2889 except KeyError:
2872 for k, v in external.iteritems():
2890 for k, v in external.iteritems():
2873 if k.endswith('.' + name) or k.endswith('/' + name) or v == name:
2891 if k.endswith('.' + name) or k.endswith('/' + name) or v == name:
2874 return sys.modules[v]
2892 return sys.modules[v]
2875 raise KeyError(name)
2893 raise KeyError(name)
2876
2894
2877 def load_extensions(ui):
2895 def load_extensions(ui):
2878 added = []
2896 added = []
2879 for ext_name, load_from_name in ui.extensions():
2897 for ext_name, load_from_name in ui.extensions():
2880 if ext_name in external:
2898 if ext_name in external:
2881 continue
2899 continue
2882 try:
2900 try:
2883 if load_from_name:
2901 if load_from_name:
2884 # the module will be loaded in sys.modules
2902 # the module will be loaded in sys.modules
2885 # choose an unique name so that it doesn't
2903 # choose an unique name so that it doesn't
2886 # conflicts with other modules
2904 # conflicts with other modules
2887 module_name = "hgext_%s" % ext_name.replace('.', '_')
2905 module_name = "hgext_%s" % ext_name.replace('.', '_')
2888 mod = imp.load_source(module_name, load_from_name)
2906 mod = imp.load_source(module_name, load_from_name)
2889 else:
2907 else:
2890 def importh(name):
2908 def importh(name):
2891 mod = __import__(name)
2909 mod = __import__(name)
2892 components = name.split('.')
2910 components = name.split('.')
2893 for comp in components[1:]:
2911 for comp in components[1:]:
2894 mod = getattr(mod, comp)
2912 mod = getattr(mod, comp)
2895 return mod
2913 return mod
2896 try:
2914 try:
2897 mod = importh("hgext.%s" % ext_name)
2915 mod = importh("hgext.%s" % ext_name)
2898 except ImportError:
2916 except ImportError:
2899 mod = importh(ext_name)
2917 mod = importh(ext_name)
2900 external[ext_name] = mod.__name__
2918 external[ext_name] = mod.__name__
2901 added.append((mod, ext_name))
2919 added.append((mod, ext_name))
2902 except (util.SignalInterrupt, KeyboardInterrupt):
2920 except (util.SignalInterrupt, KeyboardInterrupt):
2903 raise
2921 raise
2904 except Exception, inst:
2922 except Exception, inst:
2905 ui.warn(_("*** failed to import extension %s: %s\n") %
2923 ui.warn(_("*** failed to import extension %s: %s\n") %
2906 (ext_name, inst))
2924 (ext_name, inst))
2907 if ui.print_exc():
2925 if ui.print_exc():
2908 return 1
2926 return 1
2909
2927
2910 for mod, name in added:
2928 for mod, name in added:
2911 uisetup = getattr(mod, 'uisetup', None)
2929 uisetup = getattr(mod, 'uisetup', None)
2912 if uisetup:
2930 if uisetup:
2913 uisetup(ui)
2931 uisetup(ui)
2914 cmdtable = getattr(mod, 'cmdtable', {})
2932 cmdtable = getattr(mod, 'cmdtable', {})
2915 for t in cmdtable:
2933 for t in cmdtable:
2916 if t in table:
2934 if t in table:
2917 ui.warn(_("module %s overrides %s\n") % (name, t))
2935 ui.warn(_("module %s overrides %s\n") % (name, t))
2918 table.update(cmdtable)
2936 table.update(cmdtable)
2919
2937
2920 def parseconfig(config):
2938 def parseconfig(config):
2921 """parse the --config options from the command line"""
2939 """parse the --config options from the command line"""
2922 parsed = []
2940 parsed = []
2923 for cfg in config:
2941 for cfg in config:
2924 try:
2942 try:
2925 name, value = cfg.split('=', 1)
2943 name, value = cfg.split('=', 1)
2926 section, name = name.split('.', 1)
2944 section, name = name.split('.', 1)
2927 if not section or not name:
2945 if not section or not name:
2928 raise IndexError
2946 raise IndexError
2929 parsed.append((section, name, value))
2947 parsed.append((section, name, value))
2930 except (IndexError, ValueError):
2948 except (IndexError, ValueError):
2931 raise util.Abort(_('malformed --config option: %s') % cfg)
2949 raise util.Abort(_('malformed --config option: %s') % cfg)
2932 return parsed
2950 return parsed
2933
2951
2934 def dispatch(args):
2952 def dispatch(args):
2935 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
2953 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
2936 num = getattr(signal, name, None)
2954 num = getattr(signal, name, None)
2937 if num: signal.signal(num, catchterm)
2955 if num: signal.signal(num, catchterm)
2938
2956
2939 try:
2957 try:
2940 u = ui.ui(traceback='--traceback' in sys.argv[1:])
2958 u = ui.ui(traceback='--traceback' in sys.argv[1:])
2941 except util.Abort, inst:
2959 except util.Abort, inst:
2942 sys.stderr.write(_("abort: %s\n") % inst)
2960 sys.stderr.write(_("abort: %s\n") % inst)
2943 return -1
2961 return -1
2944
2962
2945 load_extensions(u)
2963 load_extensions(u)
2946 u.addreadhook(load_extensions)
2964 u.addreadhook(load_extensions)
2947
2965
2948 try:
2966 try:
2949 cmd, func, args, options, cmdoptions = parse(u, args)
2967 cmd, func, args, options, cmdoptions = parse(u, args)
2950 if options["encoding"]:
2968 if options["encoding"]:
2951 util._encoding = options["encoding"]
2969 util._encoding = options["encoding"]
2952 if options["encodingmode"]:
2970 if options["encodingmode"]:
2953 util._encodingmode = options["encodingmode"]
2971 util._encodingmode = options["encodingmode"]
2954 if options["time"]:
2972 if options["time"]:
2955 def get_times():
2973 def get_times():
2956 t = os.times()
2974 t = os.times()
2957 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
2975 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
2958 t = (t[0], t[1], t[2], t[3], time.clock())
2976 t = (t[0], t[1], t[2], t[3], time.clock())
2959 return t
2977 return t
2960 s = get_times()
2978 s = get_times()
2961 def print_time():
2979 def print_time():
2962 t = get_times()
2980 t = get_times()
2963 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
2981 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
2964 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
2982 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
2965 atexit.register(print_time)
2983 atexit.register(print_time)
2966
2984
2967 # enter the debugger before command execution
2985 # enter the debugger before command execution
2968 if options['debugger']:
2986 if options['debugger']:
2969 pdb.set_trace()
2987 pdb.set_trace()
2970
2988
2971 try:
2989 try:
2972 if options['cwd']:
2990 if options['cwd']:
2973 try:
2991 try:
2974 os.chdir(options['cwd'])
2992 os.chdir(options['cwd'])
2975 except OSError, inst:
2993 except OSError, inst:
2976 raise util.Abort('%s: %s' %
2994 raise util.Abort('%s: %s' %
2977 (options['cwd'], inst.strerror))
2995 (options['cwd'], inst.strerror))
2978
2996
2979 u.updateopts(options["verbose"], options["debug"], options["quiet"],
2997 u.updateopts(options["verbose"], options["debug"], options["quiet"],
2980 not options["noninteractive"], options["traceback"],
2998 not options["noninteractive"], options["traceback"],
2981 parseconfig(options["config"]))
2999 parseconfig(options["config"]))
2982
3000
2983 path = u.expandpath(options["repository"]) or ""
3001 path = u.expandpath(options["repository"]) or ""
2984 repo = path and hg.repository(u, path=path) or None
3002 repo = path and hg.repository(u, path=path) or None
2985 if repo and not repo.local():
3003 if repo and not repo.local():
2986 raise util.Abort(_("repository '%s' is not local") % path)
3004 raise util.Abort(_("repository '%s' is not local") % path)
2987
3005
2988 if options['help']:
3006 if options['help']:
2989 return help_(u, cmd, options['version'])
3007 return help_(u, cmd, options['version'])
2990 elif options['version']:
3008 elif options['version']:
2991 return version_(u)
3009 return version_(u)
2992 elif not cmd:
3010 elif not cmd:
2993 return help_(u, 'shortlist')
3011 return help_(u, 'shortlist')
2994
3012
2995 if cmd not in norepo.split():
3013 if cmd not in norepo.split():
2996 try:
3014 try:
2997 if not repo:
3015 if not repo:
2998 repo = hg.repository(u, path=path)
3016 repo = hg.repository(u, path=path)
2999 u = repo.ui
3017 u = repo.ui
3000 for name in external.itervalues():
3018 for name in external.itervalues():
3001 mod = sys.modules[name]
3019 mod = sys.modules[name]
3002 if hasattr(mod, 'reposetup'):
3020 if hasattr(mod, 'reposetup'):
3003 mod.reposetup(u, repo)
3021 mod.reposetup(u, repo)
3004 hg.repo_setup_hooks.append(mod.reposetup)
3022 hg.repo_setup_hooks.append(mod.reposetup)
3005 except hg.RepoError:
3023 except hg.RepoError:
3006 if cmd not in optionalrepo.split():
3024 if cmd not in optionalrepo.split():
3007 raise
3025 raise
3008 d = lambda: func(u, repo, *args, **cmdoptions)
3026 d = lambda: func(u, repo, *args, **cmdoptions)
3009 else:
3027 else:
3010 d = lambda: func(u, *args, **cmdoptions)
3028 d = lambda: func(u, *args, **cmdoptions)
3011
3029
3012 try:
3030 try:
3013 if options['profile']:
3031 if options['profile']:
3014 import hotshot, hotshot.stats
3032 import hotshot, hotshot.stats
3015 prof = hotshot.Profile("hg.prof")
3033 prof = hotshot.Profile("hg.prof")
3016 try:
3034 try:
3017 try:
3035 try:
3018 return prof.runcall(d)
3036 return prof.runcall(d)
3019 except:
3037 except:
3020 try:
3038 try:
3021 u.warn(_('exception raised - generating '
3039 u.warn(_('exception raised - generating '
3022 'profile anyway\n'))
3040 'profile anyway\n'))
3023 except:
3041 except:
3024 pass
3042 pass
3025 raise
3043 raise
3026 finally:
3044 finally:
3027 prof.close()
3045 prof.close()
3028 stats = hotshot.stats.load("hg.prof")
3046 stats = hotshot.stats.load("hg.prof")
3029 stats.strip_dirs()
3047 stats.strip_dirs()
3030 stats.sort_stats('time', 'calls')
3048 stats.sort_stats('time', 'calls')
3031 stats.print_stats(40)
3049 stats.print_stats(40)
3032 elif options['lsprof']:
3050 elif options['lsprof']:
3033 try:
3051 try:
3034 from mercurial import lsprof
3052 from mercurial import lsprof
3035 except ImportError:
3053 except ImportError:
3036 raise util.Abort(_(
3054 raise util.Abort(_(
3037 'lsprof not available - install from '
3055 'lsprof not available - install from '
3038 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
3056 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
3039 p = lsprof.Profiler()
3057 p = lsprof.Profiler()
3040 p.enable(subcalls=True)
3058 p.enable(subcalls=True)
3041 try:
3059 try:
3042 return d()
3060 return d()
3043 finally:
3061 finally:
3044 p.disable()
3062 p.disable()
3045 stats = lsprof.Stats(p.getstats())
3063 stats = lsprof.Stats(p.getstats())
3046 stats.sort()
3064 stats.sort()
3047 stats.pprint(top=10, file=sys.stderr, climit=5)
3065 stats.pprint(top=10, file=sys.stderr, climit=5)
3048 else:
3066 else:
3049 return d()
3067 return d()
3050 finally:
3068 finally:
3051 u.flush()
3069 u.flush()
3052 except:
3070 except:
3053 # enter the debugger when we hit an exception
3071 # enter the debugger when we hit an exception
3054 if options['debugger']:
3072 if options['debugger']:
3055 pdb.post_mortem(sys.exc_info()[2])
3073 pdb.post_mortem(sys.exc_info()[2])
3056 u.print_exc()
3074 u.print_exc()
3057 raise
3075 raise
3058 except ParseError, inst:
3076 except ParseError, inst:
3059 if inst.args[0]:
3077 if inst.args[0]:
3060 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
3078 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
3061 help_(u, inst.args[0])
3079 help_(u, inst.args[0])
3062 else:
3080 else:
3063 u.warn(_("hg: %s\n") % inst.args[1])
3081 u.warn(_("hg: %s\n") % inst.args[1])
3064 help_(u, 'shortlist')
3082 help_(u, 'shortlist')
3065 except AmbiguousCommand, inst:
3083 except AmbiguousCommand, inst:
3066 u.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
3084 u.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
3067 (inst.args[0], " ".join(inst.args[1])))
3085 (inst.args[0], " ".join(inst.args[1])))
3068 except UnknownCommand, inst:
3086 except UnknownCommand, inst:
3069 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
3087 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
3070 help_(u, 'shortlist')
3088 help_(u, 'shortlist')
3071 except hg.RepoError, inst:
3089 except hg.RepoError, inst:
3072 u.warn(_("abort: %s!\n") % inst)
3090 u.warn(_("abort: %s!\n") % inst)
3073 except lock.LockHeld, inst:
3091 except lock.LockHeld, inst:
3074 if inst.errno == errno.ETIMEDOUT:
3092 if inst.errno == errno.ETIMEDOUT:
3075 reason = _('timed out waiting for lock held by %s') % inst.locker
3093 reason = _('timed out waiting for lock held by %s') % inst.locker
3076 else:
3094 else:
3077 reason = _('lock held by %s') % inst.locker
3095 reason = _('lock held by %s') % inst.locker
3078 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
3096 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
3079 except lock.LockUnavailable, inst:
3097 except lock.LockUnavailable, inst:
3080 u.warn(_("abort: could not lock %s: %s\n") %
3098 u.warn(_("abort: could not lock %s: %s\n") %
3081 (inst.desc or inst.filename, inst.strerror))
3099 (inst.desc or inst.filename, inst.strerror))
3082 except revlog.RevlogError, inst:
3100 except revlog.RevlogError, inst:
3083 u.warn(_("abort: %s!\n") % inst)
3101 u.warn(_("abort: %s!\n") % inst)
3084 except util.SignalInterrupt:
3102 except util.SignalInterrupt:
3085 u.warn(_("killed!\n"))
3103 u.warn(_("killed!\n"))
3086 except KeyboardInterrupt:
3104 except KeyboardInterrupt:
3087 try:
3105 try:
3088 u.warn(_("interrupted!\n"))
3106 u.warn(_("interrupted!\n"))
3089 except IOError, inst:
3107 except IOError, inst:
3090 if inst.errno == errno.EPIPE:
3108 if inst.errno == errno.EPIPE:
3091 if u.debugflag:
3109 if u.debugflag:
3092 u.warn(_("\nbroken pipe\n"))
3110 u.warn(_("\nbroken pipe\n"))
3093 else:
3111 else:
3094 raise
3112 raise
3095 except IOError, inst:
3113 except IOError, inst:
3096 if hasattr(inst, "code"):
3114 if hasattr(inst, "code"):
3097 u.warn(_("abort: %s\n") % inst)
3115 u.warn(_("abort: %s\n") % inst)
3098 elif hasattr(inst, "reason"):
3116 elif hasattr(inst, "reason"):
3099 u.warn(_("abort: error: %s\n") % inst.reason[1])
3117 u.warn(_("abort: error: %s\n") % inst.reason[1])
3100 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
3118 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
3101 if u.debugflag:
3119 if u.debugflag:
3102 u.warn(_("broken pipe\n"))
3120 u.warn(_("broken pipe\n"))
3103 elif getattr(inst, "strerror", None):
3121 elif getattr(inst, "strerror", None):
3104 if getattr(inst, "filename", None):
3122 if getattr(inst, "filename", None):
3105 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3123 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3106 else:
3124 else:
3107 u.warn(_("abort: %s\n") % inst.strerror)
3125 u.warn(_("abort: %s\n") % inst.strerror)
3108 else:
3126 else:
3109 raise
3127 raise
3110 except OSError, inst:
3128 except OSError, inst:
3111 if getattr(inst, "filename", None):
3129 if getattr(inst, "filename", None):
3112 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3130 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3113 else:
3131 else:
3114 u.warn(_("abort: %s\n") % inst.strerror)
3132 u.warn(_("abort: %s\n") % inst.strerror)
3115 except util.UnexpectedOutput, inst:
3133 except util.UnexpectedOutput, inst:
3116 u.warn(_("abort: %s") % inst[0])
3134 u.warn(_("abort: %s") % inst[0])
3117 if not isinstance(inst[1], basestring):
3135 if not isinstance(inst[1], basestring):
3118 u.warn(" %r\n" % (inst[1],))
3136 u.warn(" %r\n" % (inst[1],))
3119 elif not inst[1]:
3137 elif not inst[1]:
3120 u.warn(_(" empty string\n"))
3138 u.warn(_(" empty string\n"))
3121 else:
3139 else:
3122 u.warn("\n%r\n" % util.ellipsis(inst[1]))
3140 u.warn("\n%r\n" % util.ellipsis(inst[1]))
3123 except util.Abort, inst:
3141 except util.Abort, inst:
3124 u.warn(_("abort: %s\n") % inst)
3142 u.warn(_("abort: %s\n") % inst)
3125 except TypeError, inst:
3143 except TypeError, inst:
3126 # was this an argument error?
3144 # was this an argument error?
3127 tb = traceback.extract_tb(sys.exc_info()[2])
3145 tb = traceback.extract_tb(sys.exc_info()[2])
3128 if len(tb) > 2: # no
3146 if len(tb) > 2: # no
3129 raise
3147 raise
3130 u.debug(inst, "\n")
3148 u.debug(inst, "\n")
3131 u.warn(_("%s: invalid arguments\n") % cmd)
3149 u.warn(_("%s: invalid arguments\n") % cmd)
3132 help_(u, cmd)
3150 help_(u, cmd)
3133 except SystemExit, inst:
3151 except SystemExit, inst:
3134 # Commands shouldn't sys.exit directly, but give a return code.
3152 # Commands shouldn't sys.exit directly, but give a return code.
3135 # Just in case catch this and and pass exit code to caller.
3153 # Just in case catch this and and pass exit code to caller.
3136 return inst.code
3154 return inst.code
3137 except:
3155 except:
3138 u.warn(_("** unknown exception encountered, details follow\n"))
3156 u.warn(_("** unknown exception encountered, details follow\n"))
3139 u.warn(_("** report bug details to "
3157 u.warn(_("** report bug details to "
3140 "http://www.selenic.com/mercurial/bts\n"))
3158 "http://www.selenic.com/mercurial/bts\n"))
3141 u.warn(_("** or mercurial@selenic.com\n"))
3159 u.warn(_("** or mercurial@selenic.com\n"))
3142 u.warn(_("** Mercurial Distributed SCM (version %s)\n")
3160 u.warn(_("** Mercurial Distributed SCM (version %s)\n")
3143 % version.get_version())
3161 % version.get_version())
3144 raise
3162 raise
3145
3163
3146 return -1
3164 return -1
General Comments 0
You need to be logged in to leave comments. Login now