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