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