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