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