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