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