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