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