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