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