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