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