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