##// END OF EJS Templates
bookmarks: allow deactivating current bookmark with -i
Kevin Bullock -
r14189:328422b0 default
parent child Browse files
Show More
@@ -1,4971 +1,4974 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, bin, nullid, nullrev, short
8 from node import hex, bin, 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, scmutil, util, revlog, extensions, copies, error, bookmarks
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
13 import patch, help, url, encoding, templatekw, discovery
13 import patch, help, url, encoding, templatekw, discovery
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, revset, templatefilters
16 import minirst, revset, templatefilters
17 import dagparser, context, simplemerge
17 import dagparser, context, simplemerge
18 import random, setdiscovery, treediscovery, dagutil
18 import random, setdiscovery, treediscovery, dagutil
19
19
20 # Commands start here, listed alphabetically
20 # Commands start here, listed alphabetically
21
21
22 def add(ui, repo, *pats, **opts):
22 def add(ui, repo, *pats, **opts):
23 """add the specified files on the next commit
23 """add the specified files on the next commit
24
24
25 Schedule files to be version controlled and added to the
25 Schedule files to be version controlled and added to the
26 repository.
26 repository.
27
27
28 The files will be added to the repository at the next commit. To
28 The files will be added to the repository at the next commit. To
29 undo an add before that, see :hg:`forget`.
29 undo an add before that, see :hg:`forget`.
30
30
31 If no names are given, add all files to the repository.
31 If no names are given, add all files to the repository.
32
32
33 .. container:: verbose
33 .. container:: verbose
34
34
35 An example showing how new (unknown) files are added
35 An example showing how new (unknown) files are added
36 automatically by :hg:`add`::
36 automatically by :hg:`add`::
37
37
38 $ ls
38 $ ls
39 foo.c
39 foo.c
40 $ hg status
40 $ hg status
41 ? foo.c
41 ? foo.c
42 $ hg add
42 $ hg add
43 adding foo.c
43 adding foo.c
44 $ hg status
44 $ hg status
45 A foo.c
45 A foo.c
46
46
47 Returns 0 if all files are successfully added.
47 Returns 0 if all files are successfully added.
48 """
48 """
49
49
50 m = cmdutil.match(repo, pats, opts)
50 m = cmdutil.match(repo, pats, opts)
51 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
51 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
52 opts.get('subrepos'), prefix="")
52 opts.get('subrepos'), prefix="")
53 return rejected and 1 or 0
53 return rejected and 1 or 0
54
54
55 def addremove(ui, repo, *pats, **opts):
55 def addremove(ui, repo, *pats, **opts):
56 """add all new files, delete all missing files
56 """add all new files, delete all missing files
57
57
58 Add all new files and remove all missing files from the
58 Add all new files and remove all missing files from the
59 repository.
59 repository.
60
60
61 New files are ignored if they match any of the patterns in
61 New files are ignored if they match any of the patterns in
62 ``.hgignore``. As with add, these changes take effect at the next
62 ``.hgignore``. As with add, these changes take effect at the next
63 commit.
63 commit.
64
64
65 Use the -s/--similarity option to detect renamed files. With a
65 Use the -s/--similarity option to detect renamed files. With a
66 parameter greater than 0, this compares every removed file with
66 parameter greater than 0, this compares every removed file with
67 every added file and records those similar enough as renames. This
67 every added file and records those similar enough as renames. This
68 option takes a percentage between 0 (disabled) and 100 (files must
68 option takes a percentage between 0 (disabled) and 100 (files must
69 be identical) as its parameter. Detecting renamed files this way
69 be identical) as its parameter. Detecting renamed files this way
70 can be expensive. After using this option, :hg:`status -C` can be
70 can be expensive. After using this option, :hg:`status -C` can be
71 used to check which files were identified as moved or renamed.
71 used to check which files were identified as moved or renamed.
72
72
73 Returns 0 if all files are successfully added.
73 Returns 0 if all files are successfully added.
74 """
74 """
75 try:
75 try:
76 sim = float(opts.get('similarity') or 100)
76 sim = float(opts.get('similarity') or 100)
77 except ValueError:
77 except ValueError:
78 raise util.Abort(_('similarity must be a number'))
78 raise util.Abort(_('similarity must be a number'))
79 if sim < 0 or sim > 100:
79 if sim < 0 or sim > 100:
80 raise util.Abort(_('similarity must be between 0 and 100'))
80 raise util.Abort(_('similarity must be between 0 and 100'))
81 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
81 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
82
82
83 def annotate(ui, repo, *pats, **opts):
83 def annotate(ui, repo, *pats, **opts):
84 """show changeset information by line for each file
84 """show changeset information by line for each file
85
85
86 List changes in files, showing the revision id responsible for
86 List changes in files, showing the revision id responsible for
87 each line
87 each line
88
88
89 This command is useful for discovering when a change was made and
89 This command is useful for discovering when a change was made and
90 by whom.
90 by whom.
91
91
92 Without the -a/--text option, annotate will avoid processing files
92 Without the -a/--text option, annotate will avoid processing files
93 it detects as binary. With -a, annotate will annotate the file
93 it detects as binary. With -a, annotate will annotate the file
94 anyway, although the results will probably be neither useful
94 anyway, although the results will probably be neither useful
95 nor desirable.
95 nor desirable.
96
96
97 Returns 0 on success.
97 Returns 0 on success.
98 """
98 """
99 if opts.get('follow'):
99 if opts.get('follow'):
100 # --follow is deprecated and now just an alias for -f/--file
100 # --follow is deprecated and now just an alias for -f/--file
101 # to mimic the behavior of Mercurial before version 1.5
101 # to mimic the behavior of Mercurial before version 1.5
102 opts['file'] = 1
102 opts['file'] = 1
103
103
104 datefunc = ui.quiet and util.shortdate or util.datestr
104 datefunc = ui.quiet and util.shortdate or util.datestr
105 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
105 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
106
106
107 if not pats:
107 if not pats:
108 raise util.Abort(_('at least one filename or pattern is required'))
108 raise util.Abort(_('at least one filename or pattern is required'))
109
109
110 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
110 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
111 ('number', lambda x: str(x[0].rev())),
111 ('number', lambda x: str(x[0].rev())),
112 ('changeset', lambda x: short(x[0].node())),
112 ('changeset', lambda x: short(x[0].node())),
113 ('date', getdate),
113 ('date', getdate),
114 ('file', lambda x: x[0].path()),
114 ('file', lambda x: x[0].path()),
115 ]
115 ]
116
116
117 if (not opts.get('user') and not opts.get('changeset')
117 if (not opts.get('user') and not opts.get('changeset')
118 and not opts.get('date') and not opts.get('file')):
118 and not opts.get('date') and not opts.get('file')):
119 opts['number'] = 1
119 opts['number'] = 1
120
120
121 linenumber = opts.get('line_number') is not None
121 linenumber = opts.get('line_number') is not None
122 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
122 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
123 raise util.Abort(_('at least one of -n/-c is required for -l'))
123 raise util.Abort(_('at least one of -n/-c is required for -l'))
124
124
125 funcmap = [func for op, func in opmap if opts.get(op)]
125 funcmap = [func for op, func in opmap if opts.get(op)]
126 if linenumber:
126 if linenumber:
127 lastfunc = funcmap[-1]
127 lastfunc = funcmap[-1]
128 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
128 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
129
129
130 def bad(x, y):
130 def bad(x, y):
131 raise util.Abort("%s: %s" % (x, y))
131 raise util.Abort("%s: %s" % (x, y))
132
132
133 ctx = cmdutil.revsingle(repo, opts.get('rev'))
133 ctx = cmdutil.revsingle(repo, opts.get('rev'))
134 m = cmdutil.match(repo, pats, opts)
134 m = cmdutil.match(repo, pats, opts)
135 m.bad = bad
135 m.bad = bad
136 follow = not opts.get('no_follow')
136 follow = not opts.get('no_follow')
137 for abs in ctx.walk(m):
137 for abs in ctx.walk(m):
138 fctx = ctx[abs]
138 fctx = ctx[abs]
139 if not opts.get('text') and util.binary(fctx.data()):
139 if not opts.get('text') and util.binary(fctx.data()):
140 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
140 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
141 continue
141 continue
142
142
143 lines = fctx.annotate(follow=follow, linenumber=linenumber)
143 lines = fctx.annotate(follow=follow, linenumber=linenumber)
144 pieces = []
144 pieces = []
145
145
146 for f in funcmap:
146 for f in funcmap:
147 l = [f(n) for n, dummy in lines]
147 l = [f(n) for n, dummy in lines]
148 if l:
148 if l:
149 sized = [(x, encoding.colwidth(x)) for x in l]
149 sized = [(x, encoding.colwidth(x)) for x in l]
150 ml = max([w for x, w in sized])
150 ml = max([w for x, w in sized])
151 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
151 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
152
152
153 if pieces:
153 if pieces:
154 for p, l in zip(zip(*pieces), lines):
154 for p, l in zip(zip(*pieces), lines):
155 ui.write("%s: %s" % (" ".join(p), l[1]))
155 ui.write("%s: %s" % (" ".join(p), l[1]))
156
156
157 def archive(ui, repo, dest, **opts):
157 def archive(ui, repo, dest, **opts):
158 '''create an unversioned archive of a repository revision
158 '''create an unversioned archive of a repository revision
159
159
160 By default, the revision used is the parent of the working
160 By default, the revision used is the parent of the working
161 directory; use -r/--rev to specify a different revision.
161 directory; use -r/--rev to specify a different revision.
162
162
163 The archive type is automatically detected based on file
163 The archive type is automatically detected based on file
164 extension (or override using -t/--type).
164 extension (or override using -t/--type).
165
165
166 Valid types are:
166 Valid types are:
167
167
168 :``files``: a directory full of files (default)
168 :``files``: a directory full of files (default)
169 :``tar``: tar archive, uncompressed
169 :``tar``: tar archive, uncompressed
170 :``tbz2``: tar archive, compressed using bzip2
170 :``tbz2``: tar archive, compressed using bzip2
171 :``tgz``: tar archive, compressed using gzip
171 :``tgz``: tar archive, compressed using gzip
172 :``uzip``: zip archive, uncompressed
172 :``uzip``: zip archive, uncompressed
173 :``zip``: zip archive, compressed using deflate
173 :``zip``: zip archive, compressed using deflate
174
174
175 The exact name of the destination archive or directory is given
175 The exact name of the destination archive or directory is given
176 using a format string; see :hg:`help export` for details.
176 using a format string; see :hg:`help export` for details.
177
177
178 Each member added to an archive file has a directory prefix
178 Each member added to an archive file has a directory prefix
179 prepended. Use -p/--prefix to specify a format string for the
179 prepended. Use -p/--prefix to specify a format string for the
180 prefix. The default is the basename of the archive, with suffixes
180 prefix. The default is the basename of the archive, with suffixes
181 removed.
181 removed.
182
182
183 Returns 0 on success.
183 Returns 0 on success.
184 '''
184 '''
185
185
186 ctx = cmdutil.revsingle(repo, opts.get('rev'))
186 ctx = cmdutil.revsingle(repo, opts.get('rev'))
187 if not ctx:
187 if not ctx:
188 raise util.Abort(_('no working directory: please specify a revision'))
188 raise util.Abort(_('no working directory: please specify a revision'))
189 node = ctx.node()
189 node = ctx.node()
190 dest = cmdutil.make_filename(repo, dest, node)
190 dest = cmdutil.make_filename(repo, dest, node)
191 if os.path.realpath(dest) == repo.root:
191 if os.path.realpath(dest) == repo.root:
192 raise util.Abort(_('repository root cannot be destination'))
192 raise util.Abort(_('repository root cannot be destination'))
193
193
194 kind = opts.get('type') or archival.guesskind(dest) or 'files'
194 kind = opts.get('type') or archival.guesskind(dest) or 'files'
195 prefix = opts.get('prefix')
195 prefix = opts.get('prefix')
196
196
197 if dest == '-':
197 if dest == '-':
198 if kind == 'files':
198 if kind == 'files':
199 raise util.Abort(_('cannot archive plain files to stdout'))
199 raise util.Abort(_('cannot archive plain files to stdout'))
200 dest = sys.stdout
200 dest = sys.stdout
201 if not prefix:
201 if not prefix:
202 prefix = os.path.basename(repo.root) + '-%h'
202 prefix = os.path.basename(repo.root) + '-%h'
203
203
204 prefix = cmdutil.make_filename(repo, prefix, node)
204 prefix = cmdutil.make_filename(repo, prefix, node)
205 matchfn = cmdutil.match(repo, [], opts)
205 matchfn = cmdutil.match(repo, [], opts)
206 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
206 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
207 matchfn, prefix, subrepos=opts.get('subrepos'))
207 matchfn, prefix, subrepos=opts.get('subrepos'))
208
208
209 def backout(ui, repo, node=None, rev=None, **opts):
209 def backout(ui, repo, node=None, rev=None, **opts):
210 '''reverse effect of earlier changeset
210 '''reverse effect of earlier changeset
211
211
212 Prepare a new changeset with the effect of REV undone in the
212 Prepare a new changeset with the effect of REV undone in the
213 current working directory.
213 current working directory.
214
214
215 If REV is the parent of the working directory, then this new changeset
215 If REV is the parent of the working directory, then this new changeset
216 is committed automatically. Otherwise, hg needs to merge the
216 is committed automatically. Otherwise, hg needs to merge the
217 changes and the merged result is left uncommitted.
217 changes and the merged result is left uncommitted.
218
218
219 By default, the pending changeset will have one parent,
219 By default, the pending changeset will have one parent,
220 maintaining a linear history. With --merge, the pending changeset
220 maintaining a linear history. With --merge, the pending changeset
221 will instead have two parents: the old parent of the working
221 will instead have two parents: the old parent of the working
222 directory and a new child of REV that simply undoes REV.
222 directory and a new child of REV that simply undoes REV.
223
223
224 Before version 1.7, the behavior without --merge was equivalent to
224 Before version 1.7, the behavior without --merge was equivalent to
225 specifying --merge followed by :hg:`update --clean .` to cancel
225 specifying --merge followed by :hg:`update --clean .` to cancel
226 the merge and leave the child of REV as a head to be merged
226 the merge and leave the child of REV as a head to be merged
227 separately.
227 separately.
228
228
229 See :hg:`help dates` for a list of formats valid for -d/--date.
229 See :hg:`help dates` for a list of formats valid for -d/--date.
230
230
231 Returns 0 on success.
231 Returns 0 on success.
232 '''
232 '''
233 if rev and node:
233 if rev and node:
234 raise util.Abort(_("please specify just one revision"))
234 raise util.Abort(_("please specify just one revision"))
235
235
236 if not rev:
236 if not rev:
237 rev = node
237 rev = node
238
238
239 if not rev:
239 if not rev:
240 raise util.Abort(_("please specify a revision to backout"))
240 raise util.Abort(_("please specify a revision to backout"))
241
241
242 date = opts.get('date')
242 date = opts.get('date')
243 if date:
243 if date:
244 opts['date'] = util.parsedate(date)
244 opts['date'] = util.parsedate(date)
245
245
246 cmdutil.bail_if_changed(repo)
246 cmdutil.bail_if_changed(repo)
247 node = cmdutil.revsingle(repo, rev).node()
247 node = cmdutil.revsingle(repo, rev).node()
248
248
249 op1, op2 = repo.dirstate.parents()
249 op1, op2 = repo.dirstate.parents()
250 a = repo.changelog.ancestor(op1, node)
250 a = repo.changelog.ancestor(op1, node)
251 if a != node:
251 if a != node:
252 raise util.Abort(_('cannot backout change on a different branch'))
252 raise util.Abort(_('cannot backout change on a different branch'))
253
253
254 p1, p2 = repo.changelog.parents(node)
254 p1, p2 = repo.changelog.parents(node)
255 if p1 == nullid:
255 if p1 == nullid:
256 raise util.Abort(_('cannot backout a change with no parents'))
256 raise util.Abort(_('cannot backout a change with no parents'))
257 if p2 != nullid:
257 if p2 != nullid:
258 if not opts.get('parent'):
258 if not opts.get('parent'):
259 raise util.Abort(_('cannot backout a merge changeset without '
259 raise util.Abort(_('cannot backout a merge changeset without '
260 '--parent'))
260 '--parent'))
261 p = repo.lookup(opts['parent'])
261 p = repo.lookup(opts['parent'])
262 if p not in (p1, p2):
262 if p not in (p1, p2):
263 raise util.Abort(_('%s is not a parent of %s') %
263 raise util.Abort(_('%s is not a parent of %s') %
264 (short(p), short(node)))
264 (short(p), short(node)))
265 parent = p
265 parent = p
266 else:
266 else:
267 if opts.get('parent'):
267 if opts.get('parent'):
268 raise util.Abort(_('cannot use --parent on non-merge changeset'))
268 raise util.Abort(_('cannot use --parent on non-merge changeset'))
269 parent = p1
269 parent = p1
270
270
271 # the backout should appear on the same branch
271 # the backout should appear on the same branch
272 branch = repo.dirstate.branch()
272 branch = repo.dirstate.branch()
273 hg.clean(repo, node, show_stats=False)
273 hg.clean(repo, node, show_stats=False)
274 repo.dirstate.setbranch(branch)
274 repo.dirstate.setbranch(branch)
275 revert_opts = opts.copy()
275 revert_opts = opts.copy()
276 revert_opts['date'] = None
276 revert_opts['date'] = None
277 revert_opts['all'] = True
277 revert_opts['all'] = True
278 revert_opts['rev'] = hex(parent)
278 revert_opts['rev'] = hex(parent)
279 revert_opts['no_backup'] = None
279 revert_opts['no_backup'] = None
280 revert(ui, repo, **revert_opts)
280 revert(ui, repo, **revert_opts)
281 if not opts.get('merge') and op1 != node:
281 if not opts.get('merge') and op1 != node:
282 try:
282 try:
283 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
283 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
284 return hg.update(repo, op1)
284 return hg.update(repo, op1)
285 finally:
285 finally:
286 ui.setconfig('ui', 'forcemerge', '')
286 ui.setconfig('ui', 'forcemerge', '')
287
287
288 commit_opts = opts.copy()
288 commit_opts = opts.copy()
289 commit_opts['addremove'] = False
289 commit_opts['addremove'] = False
290 if not commit_opts['message'] and not commit_opts['logfile']:
290 if not commit_opts['message'] and not commit_opts['logfile']:
291 # we don't translate commit messages
291 # we don't translate commit messages
292 commit_opts['message'] = "Backed out changeset %s" % short(node)
292 commit_opts['message'] = "Backed out changeset %s" % short(node)
293 commit_opts['force_editor'] = True
293 commit_opts['force_editor'] = True
294 commit(ui, repo, **commit_opts)
294 commit(ui, repo, **commit_opts)
295 def nice(node):
295 def nice(node):
296 return '%d:%s' % (repo.changelog.rev(node), short(node))
296 return '%d:%s' % (repo.changelog.rev(node), short(node))
297 ui.status(_('changeset %s backs out changeset %s\n') %
297 ui.status(_('changeset %s backs out changeset %s\n') %
298 (nice(repo.changelog.tip()), nice(node)))
298 (nice(repo.changelog.tip()), nice(node)))
299 if opts.get('merge') and op1 != node:
299 if opts.get('merge') and op1 != node:
300 hg.clean(repo, op1, show_stats=False)
300 hg.clean(repo, op1, show_stats=False)
301 ui.status(_('merging with changeset %s\n')
301 ui.status(_('merging with changeset %s\n')
302 % nice(repo.changelog.tip()))
302 % nice(repo.changelog.tip()))
303 try:
303 try:
304 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
304 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
305 return hg.merge(repo, hex(repo.changelog.tip()))
305 return hg.merge(repo, hex(repo.changelog.tip()))
306 finally:
306 finally:
307 ui.setconfig('ui', 'forcemerge', '')
307 ui.setconfig('ui', 'forcemerge', '')
308 return 0
308 return 0
309
309
310 def bisect(ui, repo, rev=None, extra=None, command=None,
310 def bisect(ui, repo, rev=None, extra=None, command=None,
311 reset=None, good=None, bad=None, skip=None, extend=None,
311 reset=None, good=None, bad=None, skip=None, extend=None,
312 noupdate=None):
312 noupdate=None):
313 """subdivision search of changesets
313 """subdivision search of changesets
314
314
315 This command helps to find changesets which introduce problems. To
315 This command helps to find changesets which introduce problems. To
316 use, mark the earliest changeset you know exhibits the problem as
316 use, mark the earliest changeset you know exhibits the problem as
317 bad, then mark the latest changeset which is free from the problem
317 bad, then mark the latest changeset which is free from the problem
318 as good. Bisect will update your working directory to a revision
318 as good. Bisect will update your working directory to a revision
319 for testing (unless the -U/--noupdate option is specified). Once
319 for testing (unless the -U/--noupdate option is specified). Once
320 you have performed tests, mark the working directory as good or
320 you have performed tests, mark the working directory as good or
321 bad, and bisect will either update to another candidate changeset
321 bad, and bisect will either update to another candidate changeset
322 or announce that it has found the bad revision.
322 or announce that it has found the bad revision.
323
323
324 As a shortcut, you can also use the revision argument to mark a
324 As a shortcut, you can also use the revision argument to mark a
325 revision as good or bad without checking it out first.
325 revision as good or bad without checking it out first.
326
326
327 If you supply a command, it will be used for automatic bisection.
327 If you supply a command, it will be used for automatic bisection.
328 Its exit status will be used to mark revisions as good or bad:
328 Its exit status will be used to mark revisions as good or bad:
329 status 0 means good, 125 means to skip the revision, 127
329 status 0 means good, 125 means to skip the revision, 127
330 (command not found) will abort the bisection, and any other
330 (command not found) will abort the bisection, and any other
331 non-zero exit status means the revision is bad.
331 non-zero exit status means the revision is bad.
332
332
333 Returns 0 on success.
333 Returns 0 on success.
334 """
334 """
335 def extendbisectrange(nodes, good):
335 def extendbisectrange(nodes, good):
336 # bisect is incomplete when it ends on a merge node and
336 # bisect is incomplete when it ends on a merge node and
337 # one of the parent was not checked.
337 # one of the parent was not checked.
338 parents = repo[nodes[0]].parents()
338 parents = repo[nodes[0]].parents()
339 if len(parents) > 1:
339 if len(parents) > 1:
340 side = good and state['bad'] or state['good']
340 side = good and state['bad'] or state['good']
341 num = len(set(i.node() for i in parents) & set(side))
341 num = len(set(i.node() for i in parents) & set(side))
342 if num == 1:
342 if num == 1:
343 return parents[0].ancestor(parents[1])
343 return parents[0].ancestor(parents[1])
344 return None
344 return None
345
345
346 def print_result(nodes, good):
346 def print_result(nodes, good):
347 displayer = cmdutil.show_changeset(ui, repo, {})
347 displayer = cmdutil.show_changeset(ui, repo, {})
348 if len(nodes) == 1:
348 if len(nodes) == 1:
349 # narrowed it down to a single revision
349 # narrowed it down to a single revision
350 if good:
350 if good:
351 ui.write(_("The first good revision is:\n"))
351 ui.write(_("The first good revision is:\n"))
352 else:
352 else:
353 ui.write(_("The first bad revision is:\n"))
353 ui.write(_("The first bad revision is:\n"))
354 displayer.show(repo[nodes[0]])
354 displayer.show(repo[nodes[0]])
355 extendnode = extendbisectrange(nodes, good)
355 extendnode = extendbisectrange(nodes, good)
356 if extendnode is not None:
356 if extendnode is not None:
357 ui.write(_('Not all ancestors of this changeset have been'
357 ui.write(_('Not all ancestors of this changeset have been'
358 ' checked.\nUse bisect --extend to continue the '
358 ' checked.\nUse bisect --extend to continue the '
359 'bisection from\nthe common ancestor, %s.\n')
359 'bisection from\nthe common ancestor, %s.\n')
360 % extendnode)
360 % extendnode)
361 else:
361 else:
362 # multiple possible revisions
362 # multiple possible revisions
363 if good:
363 if good:
364 ui.write(_("Due to skipped revisions, the first "
364 ui.write(_("Due to skipped revisions, the first "
365 "good revision could be any of:\n"))
365 "good revision could be any of:\n"))
366 else:
366 else:
367 ui.write(_("Due to skipped revisions, the first "
367 ui.write(_("Due to skipped revisions, the first "
368 "bad revision could be any of:\n"))
368 "bad revision could be any of:\n"))
369 for n in nodes:
369 for n in nodes:
370 displayer.show(repo[n])
370 displayer.show(repo[n])
371 displayer.close()
371 displayer.close()
372
372
373 def check_state(state, interactive=True):
373 def check_state(state, interactive=True):
374 if not state['good'] or not state['bad']:
374 if not state['good'] or not state['bad']:
375 if (good or bad or skip or reset) and interactive:
375 if (good or bad or skip or reset) and interactive:
376 return
376 return
377 if not state['good']:
377 if not state['good']:
378 raise util.Abort(_('cannot bisect (no known good revisions)'))
378 raise util.Abort(_('cannot bisect (no known good revisions)'))
379 else:
379 else:
380 raise util.Abort(_('cannot bisect (no known bad revisions)'))
380 raise util.Abort(_('cannot bisect (no known bad revisions)'))
381 return True
381 return True
382
382
383 # backward compatibility
383 # backward compatibility
384 if rev in "good bad reset init".split():
384 if rev in "good bad reset init".split():
385 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
385 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
386 cmd, rev, extra = rev, extra, None
386 cmd, rev, extra = rev, extra, None
387 if cmd == "good":
387 if cmd == "good":
388 good = True
388 good = True
389 elif cmd == "bad":
389 elif cmd == "bad":
390 bad = True
390 bad = True
391 else:
391 else:
392 reset = True
392 reset = True
393 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
393 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
394 raise util.Abort(_('incompatible arguments'))
394 raise util.Abort(_('incompatible arguments'))
395
395
396 if reset:
396 if reset:
397 p = repo.join("bisect.state")
397 p = repo.join("bisect.state")
398 if os.path.exists(p):
398 if os.path.exists(p):
399 os.unlink(p)
399 os.unlink(p)
400 return
400 return
401
401
402 state = hbisect.load_state(repo)
402 state = hbisect.load_state(repo)
403
403
404 if command:
404 if command:
405 changesets = 1
405 changesets = 1
406 try:
406 try:
407 while changesets:
407 while changesets:
408 # update state
408 # update state
409 status = util.system(command)
409 status = util.system(command)
410 if status == 125:
410 if status == 125:
411 transition = "skip"
411 transition = "skip"
412 elif status == 0:
412 elif status == 0:
413 transition = "good"
413 transition = "good"
414 # status < 0 means process was killed
414 # status < 0 means process was killed
415 elif status == 127:
415 elif status == 127:
416 raise util.Abort(_("failed to execute %s") % command)
416 raise util.Abort(_("failed to execute %s") % command)
417 elif status < 0:
417 elif status < 0:
418 raise util.Abort(_("%s killed") % command)
418 raise util.Abort(_("%s killed") % command)
419 else:
419 else:
420 transition = "bad"
420 transition = "bad"
421 ctx = cmdutil.revsingle(repo, rev)
421 ctx = cmdutil.revsingle(repo, rev)
422 rev = None # clear for future iterations
422 rev = None # clear for future iterations
423 state[transition].append(ctx.node())
423 state[transition].append(ctx.node())
424 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
424 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
425 check_state(state, interactive=False)
425 check_state(state, interactive=False)
426 # bisect
426 # bisect
427 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
427 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
428 # update to next check
428 # update to next check
429 cmdutil.bail_if_changed(repo)
429 cmdutil.bail_if_changed(repo)
430 hg.clean(repo, nodes[0], show_stats=False)
430 hg.clean(repo, nodes[0], show_stats=False)
431 finally:
431 finally:
432 hbisect.save_state(repo, state)
432 hbisect.save_state(repo, state)
433 print_result(nodes, good)
433 print_result(nodes, good)
434 return
434 return
435
435
436 # update state
436 # update state
437
437
438 if rev:
438 if rev:
439 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
439 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
440 else:
440 else:
441 nodes = [repo.lookup('.')]
441 nodes = [repo.lookup('.')]
442
442
443 if good or bad or skip:
443 if good or bad or skip:
444 if good:
444 if good:
445 state['good'] += nodes
445 state['good'] += nodes
446 elif bad:
446 elif bad:
447 state['bad'] += nodes
447 state['bad'] += nodes
448 elif skip:
448 elif skip:
449 state['skip'] += nodes
449 state['skip'] += nodes
450 hbisect.save_state(repo, state)
450 hbisect.save_state(repo, state)
451
451
452 if not check_state(state):
452 if not check_state(state):
453 return
453 return
454
454
455 # actually bisect
455 # actually bisect
456 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
456 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
457 if extend:
457 if extend:
458 if not changesets:
458 if not changesets:
459 extendnode = extendbisectrange(nodes, good)
459 extendnode = extendbisectrange(nodes, good)
460 if extendnode is not None:
460 if extendnode is not None:
461 ui.write(_("Extending search to changeset %d:%s\n"
461 ui.write(_("Extending search to changeset %d:%s\n"
462 % (extendnode.rev(), extendnode)))
462 % (extendnode.rev(), extendnode)))
463 if noupdate:
463 if noupdate:
464 return
464 return
465 cmdutil.bail_if_changed(repo)
465 cmdutil.bail_if_changed(repo)
466 return hg.clean(repo, extendnode.node())
466 return hg.clean(repo, extendnode.node())
467 raise util.Abort(_("nothing to extend"))
467 raise util.Abort(_("nothing to extend"))
468
468
469 if changesets == 0:
469 if changesets == 0:
470 print_result(nodes, good)
470 print_result(nodes, good)
471 else:
471 else:
472 assert len(nodes) == 1 # only a single node can be tested next
472 assert len(nodes) == 1 # only a single node can be tested next
473 node = nodes[0]
473 node = nodes[0]
474 # compute the approximate number of remaining tests
474 # compute the approximate number of remaining tests
475 tests, size = 0, 2
475 tests, size = 0, 2
476 while size <= changesets:
476 while size <= changesets:
477 tests, size = tests + 1, size * 2
477 tests, size = tests + 1, size * 2
478 rev = repo.changelog.rev(node)
478 rev = repo.changelog.rev(node)
479 ui.write(_("Testing changeset %d:%s "
479 ui.write(_("Testing changeset %d:%s "
480 "(%d changesets remaining, ~%d tests)\n")
480 "(%d changesets remaining, ~%d tests)\n")
481 % (rev, short(node), changesets, tests))
481 % (rev, short(node), changesets, tests))
482 if not noupdate:
482 if not noupdate:
483 cmdutil.bail_if_changed(repo)
483 cmdutil.bail_if_changed(repo)
484 return hg.clean(repo, node)
484 return hg.clean(repo, node)
485
485
486 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
486 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
487 rename=None, inactive=False):
487 rename=None, inactive=False):
488 '''track a line of development with movable markers
488 '''track a line of development with movable markers
489
489
490 Bookmarks are pointers to certain commits that move when
490 Bookmarks are pointers to certain commits that move when
491 committing. Bookmarks are local. They can be renamed, copied and
491 committing. Bookmarks are local. They can be renamed, copied and
492 deleted. It is possible to use bookmark names in :hg:`merge` and
492 deleted. It is possible to use bookmark names in :hg:`merge` and
493 :hg:`update` to merge and update respectively to a given bookmark.
493 :hg:`update` to merge and update respectively to a given bookmark.
494
494
495 You can use :hg:`bookmark NAME` to set a bookmark on the working
495 You can use :hg:`bookmark NAME` to set a bookmark on the working
496 directory's parent revision with the given name. If you specify
496 directory's parent revision with the given name. If you specify
497 a revision using -r REV (where REV may be an existing bookmark),
497 a revision using -r REV (where REV may be an existing bookmark),
498 the bookmark is assigned to that revision.
498 the bookmark is assigned to that revision.
499
499
500 Bookmarks can be pushed and pulled between repositories (see :hg:`help
500 Bookmarks can be pushed and pulled between repositories (see :hg:`help
501 push` and :hg:`help pull`). This requires both the local and remote
501 push` and :hg:`help pull`). This requires both the local and remote
502 repositories to support bookmarks. For versions prior to 1.8, this means
502 repositories to support bookmarks. For versions prior to 1.8, this means
503 the bookmarks extension must be enabled.
503 the bookmarks extension must be enabled.
504 '''
504 '''
505 hexfn = ui.debugflag and hex or short
505 hexfn = ui.debugflag and hex or short
506 marks = repo._bookmarks
506 marks = repo._bookmarks
507 cur = repo.changectx('.').node()
507 cur = repo.changectx('.').node()
508
508
509 if rename:
509 if rename:
510 if rename not in marks:
510 if rename not in marks:
511 raise util.Abort(_("bookmark '%s' does not exist") % rename)
511 raise util.Abort(_("bookmark '%s' does not exist") % rename)
512 if mark in marks and not force:
512 if mark in marks and not force:
513 raise util.Abort(_("bookmark '%s' already exists "
513 raise util.Abort(_("bookmark '%s' already exists "
514 "(use -f to force)") % mark)
514 "(use -f to force)") % mark)
515 if mark is None:
515 if mark is None:
516 raise util.Abort(_("new bookmark name required"))
516 raise util.Abort(_("new bookmark name required"))
517 marks[mark] = marks[rename]
517 marks[mark] = marks[rename]
518 if repo._bookmarkcurrent == rename and not inactive:
518 if repo._bookmarkcurrent == rename and not inactive:
519 bookmarks.setcurrent(repo, mark)
519 bookmarks.setcurrent(repo, mark)
520 del marks[rename]
520 del marks[rename]
521 bookmarks.write(repo)
521 bookmarks.write(repo)
522 return
522 return
523
523
524 if delete:
524 if delete:
525 if mark is None:
525 if mark is None:
526 raise util.Abort(_("bookmark name required"))
526 raise util.Abort(_("bookmark name required"))
527 if mark not in marks:
527 if mark not in marks:
528 raise util.Abort(_("bookmark '%s' does not exist") % mark)
528 raise util.Abort(_("bookmark '%s' does not exist") % mark)
529 if mark == repo._bookmarkcurrent:
529 if mark == repo._bookmarkcurrent:
530 bookmarks.setcurrent(repo, None)
530 bookmarks.setcurrent(repo, None)
531 del marks[mark]
531 del marks[mark]
532 bookmarks.write(repo)
532 bookmarks.write(repo)
533 return
533 return
534
534
535 if mark is not None:
535 if mark is not None:
536 if "\n" in mark:
536 if "\n" in mark:
537 raise util.Abort(_("bookmark name cannot contain newlines"))
537 raise util.Abort(_("bookmark name cannot contain newlines"))
538 mark = mark.strip()
538 mark = mark.strip()
539 if not mark:
539 if not mark:
540 raise util.Abort(_("bookmark names cannot consist entirely of "
540 raise util.Abort(_("bookmark names cannot consist entirely of "
541 "whitespace"))
541 "whitespace"))
542 if inactive and mark == repo._bookmarkcurrent:
543 bookmarks.setcurrent(repo, None)
544 return
542 if mark in marks and not force:
545 if mark in marks and not force:
543 raise util.Abort(_("bookmark '%s' already exists "
546 raise util.Abort(_("bookmark '%s' already exists "
544 "(use -f to force)") % mark)
547 "(use -f to force)") % mark)
545 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
548 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
546 and not force):
549 and not force):
547 raise util.Abort(
550 raise util.Abort(
548 _("a bookmark cannot have the name of an existing branch"))
551 _("a bookmark cannot have the name of an existing branch"))
549 if rev:
552 if rev:
550 marks[mark] = repo.lookup(rev)
553 marks[mark] = repo.lookup(rev)
551 else:
554 else:
552 marks[mark] = repo.changectx('.').node()
555 marks[mark] = repo.changectx('.').node()
553 if not inactive and repo.changectx('.').node() == marks[mark]:
556 if not inactive and repo.changectx('.').node() == marks[mark]:
554 bookmarks.setcurrent(repo, mark)
557 bookmarks.setcurrent(repo, mark)
555 bookmarks.write(repo)
558 bookmarks.write(repo)
556 return
559 return
557
560
558 if mark is None:
561 if mark is None:
559 if rev:
562 if rev:
560 raise util.Abort(_("bookmark name required"))
563 raise util.Abort(_("bookmark name required"))
561 if len(marks) == 0:
564 if len(marks) == 0:
562 ui.status(_("no bookmarks set\n"))
565 ui.status(_("no bookmarks set\n"))
563 else:
566 else:
564 for bmark, n in sorted(marks.iteritems()):
567 for bmark, n in sorted(marks.iteritems()):
565 current = repo._bookmarkcurrent
568 current = repo._bookmarkcurrent
566 if bmark == current and n == cur:
569 if bmark == current and n == cur:
567 prefix, label = '*', 'bookmarks.current'
570 prefix, label = '*', 'bookmarks.current'
568 else:
571 else:
569 prefix, label = ' ', ''
572 prefix, label = ' ', ''
570
573
571 if ui.quiet:
574 if ui.quiet:
572 ui.write("%s\n" % bmark, label=label)
575 ui.write("%s\n" % bmark, label=label)
573 else:
576 else:
574 ui.write(" %s %-25s %d:%s\n" % (
577 ui.write(" %s %-25s %d:%s\n" % (
575 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
578 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
576 label=label)
579 label=label)
577 return
580 return
578
581
579 def branch(ui, repo, label=None, **opts):
582 def branch(ui, repo, label=None, **opts):
580 """set or show the current branch name
583 """set or show the current branch name
581
584
582 With no argument, show the current branch name. With one argument,
585 With no argument, show the current branch name. With one argument,
583 set the working directory branch name (the branch will not exist
586 set the working directory branch name (the branch will not exist
584 in the repository until the next commit). Standard practice
587 in the repository until the next commit). Standard practice
585 recommends that primary development take place on the 'default'
588 recommends that primary development take place on the 'default'
586 branch.
589 branch.
587
590
588 Unless -f/--force is specified, branch will not let you set a
591 Unless -f/--force is specified, branch will not let you set a
589 branch name that already exists, even if it's inactive.
592 branch name that already exists, even if it's inactive.
590
593
591 Use -C/--clean to reset the working directory branch to that of
594 Use -C/--clean to reset the working directory branch to that of
592 the parent of the working directory, negating a previous branch
595 the parent of the working directory, negating a previous branch
593 change.
596 change.
594
597
595 Use the command :hg:`update` to switch to an existing branch. Use
598 Use the command :hg:`update` to switch to an existing branch. Use
596 :hg:`commit --close-branch` to mark this branch as closed.
599 :hg:`commit --close-branch` to mark this branch as closed.
597
600
598 Returns 0 on success.
601 Returns 0 on success.
599 """
602 """
600
603
601 if opts.get('clean'):
604 if opts.get('clean'):
602 label = repo[None].p1().branch()
605 label = repo[None].p1().branch()
603 repo.dirstate.setbranch(label)
606 repo.dirstate.setbranch(label)
604 ui.status(_('reset working directory to branch %s\n') % label)
607 ui.status(_('reset working directory to branch %s\n') % label)
605 elif label:
608 elif label:
606 if not opts.get('force') and label in repo.branchtags():
609 if not opts.get('force') and label in repo.branchtags():
607 if label not in [p.branch() for p in repo.parents()]:
610 if label not in [p.branch() for p in repo.parents()]:
608 raise util.Abort(_('a branch of the same name already exists'
611 raise util.Abort(_('a branch of the same name already exists'
609 " (use 'hg update' to switch to it)"))
612 " (use 'hg update' to switch to it)"))
610 repo.dirstate.setbranch(label)
613 repo.dirstate.setbranch(label)
611 ui.status(_('marked working directory as branch %s\n') % label)
614 ui.status(_('marked working directory as branch %s\n') % label)
612 else:
615 else:
613 ui.write("%s\n" % repo.dirstate.branch())
616 ui.write("%s\n" % repo.dirstate.branch())
614
617
615 def branches(ui, repo, active=False, closed=False):
618 def branches(ui, repo, active=False, closed=False):
616 """list repository named branches
619 """list repository named branches
617
620
618 List the repository's named branches, indicating which ones are
621 List the repository's named branches, indicating which ones are
619 inactive. If -c/--closed is specified, also list branches which have
622 inactive. If -c/--closed is specified, also list branches which have
620 been marked closed (see :hg:`commit --close-branch`).
623 been marked closed (see :hg:`commit --close-branch`).
621
624
622 If -a/--active is specified, only show active branches. A branch
625 If -a/--active is specified, only show active branches. A branch
623 is considered active if it contains repository heads.
626 is considered active if it contains repository heads.
624
627
625 Use the command :hg:`update` to switch to an existing branch.
628 Use the command :hg:`update` to switch to an existing branch.
626
629
627 Returns 0.
630 Returns 0.
628 """
631 """
629
632
630 hexfunc = ui.debugflag and hex or short
633 hexfunc = ui.debugflag and hex or short
631 activebranches = [repo[n].branch() for n in repo.heads()]
634 activebranches = [repo[n].branch() for n in repo.heads()]
632 def testactive(tag, node):
635 def testactive(tag, node):
633 realhead = tag in activebranches
636 realhead = tag in activebranches
634 open = node in repo.branchheads(tag, closed=False)
637 open = node in repo.branchheads(tag, closed=False)
635 return realhead and open
638 return realhead and open
636 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
639 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
637 for tag, node in repo.branchtags().items()],
640 for tag, node in repo.branchtags().items()],
638 reverse=True)
641 reverse=True)
639
642
640 for isactive, node, tag in branches:
643 for isactive, node, tag in branches:
641 if (not active) or isactive:
644 if (not active) or isactive:
642 if ui.quiet:
645 if ui.quiet:
643 ui.write("%s\n" % tag)
646 ui.write("%s\n" % tag)
644 else:
647 else:
645 hn = repo.lookup(node)
648 hn = repo.lookup(node)
646 if isactive:
649 if isactive:
647 label = 'branches.active'
650 label = 'branches.active'
648 notice = ''
651 notice = ''
649 elif hn not in repo.branchheads(tag, closed=False):
652 elif hn not in repo.branchheads(tag, closed=False):
650 if not closed:
653 if not closed:
651 continue
654 continue
652 label = 'branches.closed'
655 label = 'branches.closed'
653 notice = _(' (closed)')
656 notice = _(' (closed)')
654 else:
657 else:
655 label = 'branches.inactive'
658 label = 'branches.inactive'
656 notice = _(' (inactive)')
659 notice = _(' (inactive)')
657 if tag == repo.dirstate.branch():
660 if tag == repo.dirstate.branch():
658 label = 'branches.current'
661 label = 'branches.current'
659 rev = str(node).rjust(31 - encoding.colwidth(tag))
662 rev = str(node).rjust(31 - encoding.colwidth(tag))
660 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
663 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
661 tag = ui.label(tag, label)
664 tag = ui.label(tag, label)
662 ui.write("%s %s%s\n" % (tag, rev, notice))
665 ui.write("%s %s%s\n" % (tag, rev, notice))
663
666
664 def bundle(ui, repo, fname, dest=None, **opts):
667 def bundle(ui, repo, fname, dest=None, **opts):
665 """create a changegroup file
668 """create a changegroup file
666
669
667 Generate a compressed changegroup file collecting changesets not
670 Generate a compressed changegroup file collecting changesets not
668 known to be in another repository.
671 known to be in another repository.
669
672
670 If you omit the destination repository, then hg assumes the
673 If you omit the destination repository, then hg assumes the
671 destination will have all the nodes you specify with --base
674 destination will have all the nodes you specify with --base
672 parameters. To create a bundle containing all changesets, use
675 parameters. To create a bundle containing all changesets, use
673 -a/--all (or --base null).
676 -a/--all (or --base null).
674
677
675 You can change compression method with the -t/--type option.
678 You can change compression method with the -t/--type option.
676 The available compression methods are: none, bzip2, and
679 The available compression methods are: none, bzip2, and
677 gzip (by default, bundles are compressed using bzip2).
680 gzip (by default, bundles are compressed using bzip2).
678
681
679 The bundle file can then be transferred using conventional means
682 The bundle file can then be transferred using conventional means
680 and applied to another repository with the unbundle or pull
683 and applied to another repository with the unbundle or pull
681 command. This is useful when direct push and pull are not
684 command. This is useful when direct push and pull are not
682 available or when exporting an entire repository is undesirable.
685 available or when exporting an entire repository is undesirable.
683
686
684 Applying bundles preserves all changeset contents including
687 Applying bundles preserves all changeset contents including
685 permissions, copy/rename information, and revision history.
688 permissions, copy/rename information, and revision history.
686
689
687 Returns 0 on success, 1 if no changes found.
690 Returns 0 on success, 1 if no changes found.
688 """
691 """
689 revs = None
692 revs = None
690 if 'rev' in opts:
693 if 'rev' in opts:
691 revs = cmdutil.revrange(repo, opts['rev'])
694 revs = cmdutil.revrange(repo, opts['rev'])
692
695
693 if opts.get('all'):
696 if opts.get('all'):
694 base = ['null']
697 base = ['null']
695 else:
698 else:
696 base = cmdutil.revrange(repo, opts.get('base'))
699 base = cmdutil.revrange(repo, opts.get('base'))
697 if base:
700 if base:
698 if dest:
701 if dest:
699 raise util.Abort(_("--base is incompatible with specifying "
702 raise util.Abort(_("--base is incompatible with specifying "
700 "a destination"))
703 "a destination"))
701 common = [repo.lookup(rev) for rev in base]
704 common = [repo.lookup(rev) for rev in base]
702 else:
705 else:
703 dest = ui.expandpath(dest or 'default-push', dest or 'default')
706 dest = ui.expandpath(dest or 'default-push', dest or 'default')
704 dest, branches = hg.parseurl(dest, opts.get('branch'))
707 dest, branches = hg.parseurl(dest, opts.get('branch'))
705 other = hg.repository(hg.remoteui(repo, opts), dest)
708 other = hg.repository(hg.remoteui(repo, opts), dest)
706 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
709 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
707 inc = discovery.findcommonincoming(repo, other, force=opts.get('force'))
710 inc = discovery.findcommonincoming(repo, other, force=opts.get('force'))
708 common, _anyinc, _heads = inc
711 common, _anyinc, _heads = inc
709
712
710 nodes = revs and map(repo.lookup, revs) or revs
713 nodes = revs and map(repo.lookup, revs) or revs
711 cg = repo.getbundle('bundle', common=common, heads=nodes)
714 cg = repo.getbundle('bundle', common=common, heads=nodes)
712 if not cg:
715 if not cg:
713 ui.status(_("no changes found\n"))
716 ui.status(_("no changes found\n"))
714 return 1
717 return 1
715
718
716 bundletype = opts.get('type', 'bzip2').lower()
719 bundletype = opts.get('type', 'bzip2').lower()
717 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
720 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
718 bundletype = btypes.get(bundletype)
721 bundletype = btypes.get(bundletype)
719 if bundletype not in changegroup.bundletypes:
722 if bundletype not in changegroup.bundletypes:
720 raise util.Abort(_('unknown bundle type specified with --type'))
723 raise util.Abort(_('unknown bundle type specified with --type'))
721
724
722 changegroup.writebundle(cg, fname, bundletype)
725 changegroup.writebundle(cg, fname, bundletype)
723
726
724 def cat(ui, repo, file1, *pats, **opts):
727 def cat(ui, repo, file1, *pats, **opts):
725 """output the current or given revision of files
728 """output the current or given revision of files
726
729
727 Print the specified files as they were at the given revision. If
730 Print the specified files as they were at the given revision. If
728 no revision is given, the parent of the working directory is used,
731 no revision is given, the parent of the working directory is used,
729 or tip if no revision is checked out.
732 or tip if no revision is checked out.
730
733
731 Output may be to a file, in which case the name of the file is
734 Output may be to a file, in which case the name of the file is
732 given using a format string. The formatting rules are the same as
735 given using a format string. The formatting rules are the same as
733 for the export command, with the following additions:
736 for the export command, with the following additions:
734
737
735 :``%s``: basename of file being printed
738 :``%s``: basename of file being printed
736 :``%d``: dirname of file being printed, or '.' if in repository root
739 :``%d``: dirname of file being printed, or '.' if in repository root
737 :``%p``: root-relative path name of file being printed
740 :``%p``: root-relative path name of file being printed
738
741
739 Returns 0 on success.
742 Returns 0 on success.
740 """
743 """
741 ctx = cmdutil.revsingle(repo, opts.get('rev'))
744 ctx = cmdutil.revsingle(repo, opts.get('rev'))
742 err = 1
745 err = 1
743 m = cmdutil.match(repo, (file1,) + pats, opts)
746 m = cmdutil.match(repo, (file1,) + pats, opts)
744 for abs in ctx.walk(m):
747 for abs in ctx.walk(m):
745 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
748 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
746 data = ctx[abs].data()
749 data = ctx[abs].data()
747 if opts.get('decode'):
750 if opts.get('decode'):
748 data = repo.wwritedata(abs, data)
751 data = repo.wwritedata(abs, data)
749 fp.write(data)
752 fp.write(data)
750 fp.close()
753 fp.close()
751 err = 0
754 err = 0
752 return err
755 return err
753
756
754 def clone(ui, source, dest=None, **opts):
757 def clone(ui, source, dest=None, **opts):
755 """make a copy of an existing repository
758 """make a copy of an existing repository
756
759
757 Create a copy of an existing repository in a new directory.
760 Create a copy of an existing repository in a new directory.
758
761
759 If no destination directory name is specified, it defaults to the
762 If no destination directory name is specified, it defaults to the
760 basename of the source.
763 basename of the source.
761
764
762 The location of the source is added to the new repository's
765 The location of the source is added to the new repository's
763 ``.hg/hgrc`` file, as the default to be used for future pulls.
766 ``.hg/hgrc`` file, as the default to be used for future pulls.
764
767
765 See :hg:`help urls` for valid source format details.
768 See :hg:`help urls` for valid source format details.
766
769
767 It is possible to specify an ``ssh://`` URL as the destination, but no
770 It is possible to specify an ``ssh://`` URL as the destination, but no
768 ``.hg/hgrc`` and working directory will be created on the remote side.
771 ``.hg/hgrc`` and working directory will be created on the remote side.
769 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
772 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
770
773
771 A set of changesets (tags, or branch names) to pull may be specified
774 A set of changesets (tags, or branch names) to pull may be specified
772 by listing each changeset (tag, or branch name) with -r/--rev.
775 by listing each changeset (tag, or branch name) with -r/--rev.
773 If -r/--rev is used, the cloned repository will contain only a subset
776 If -r/--rev is used, the cloned repository will contain only a subset
774 of the changesets of the source repository. Only the set of changesets
777 of the changesets of the source repository. Only the set of changesets
775 defined by all -r/--rev options (including all their ancestors)
778 defined by all -r/--rev options (including all their ancestors)
776 will be pulled into the destination repository.
779 will be pulled into the destination repository.
777 No subsequent changesets (including subsequent tags) will be present
780 No subsequent changesets (including subsequent tags) will be present
778 in the destination.
781 in the destination.
779
782
780 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
783 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
781 local source repositories.
784 local source repositories.
782
785
783 For efficiency, hardlinks are used for cloning whenever the source
786 For efficiency, hardlinks are used for cloning whenever the source
784 and destination are on the same filesystem (note this applies only
787 and destination are on the same filesystem (note this applies only
785 to the repository data, not to the working directory). Some
788 to the repository data, not to the working directory). Some
786 filesystems, such as AFS, implement hardlinking incorrectly, but
789 filesystems, such as AFS, implement hardlinking incorrectly, but
787 do not report errors. In these cases, use the --pull option to
790 do not report errors. In these cases, use the --pull option to
788 avoid hardlinking.
791 avoid hardlinking.
789
792
790 In some cases, you can clone repositories and the working directory
793 In some cases, you can clone repositories and the working directory
791 using full hardlinks with ::
794 using full hardlinks with ::
792
795
793 $ cp -al REPO REPOCLONE
796 $ cp -al REPO REPOCLONE
794
797
795 This is the fastest way to clone, but it is not always safe. The
798 This is the fastest way to clone, but it is not always safe. The
796 operation is not atomic (making sure REPO is not modified during
799 operation is not atomic (making sure REPO is not modified during
797 the operation is up to you) and you have to make sure your editor
800 the operation is up to you) and you have to make sure your editor
798 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
801 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
799 this is not compatible with certain extensions that place their
802 this is not compatible with certain extensions that place their
800 metadata under the .hg directory, such as mq.
803 metadata under the .hg directory, such as mq.
801
804
802 Mercurial will update the working directory to the first applicable
805 Mercurial will update the working directory to the first applicable
803 revision from this list:
806 revision from this list:
804
807
805 a) null if -U or the source repository has no changesets
808 a) null if -U or the source repository has no changesets
806 b) if -u . and the source repository is local, the first parent of
809 b) if -u . and the source repository is local, the first parent of
807 the source repository's working directory
810 the source repository's working directory
808 c) the changeset specified with -u (if a branch name, this means the
811 c) the changeset specified with -u (if a branch name, this means the
809 latest head of that branch)
812 latest head of that branch)
810 d) the changeset specified with -r
813 d) the changeset specified with -r
811 e) the tipmost head specified with -b
814 e) the tipmost head specified with -b
812 f) the tipmost head specified with the url#branch source syntax
815 f) the tipmost head specified with the url#branch source syntax
813 g) the tipmost head of the default branch
816 g) the tipmost head of the default branch
814 h) tip
817 h) tip
815
818
816 Returns 0 on success.
819 Returns 0 on success.
817 """
820 """
818 if opts.get('noupdate') and opts.get('updaterev'):
821 if opts.get('noupdate') and opts.get('updaterev'):
819 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
822 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
820
823
821 r = hg.clone(hg.remoteui(ui, opts), source, dest,
824 r = hg.clone(hg.remoteui(ui, opts), source, dest,
822 pull=opts.get('pull'),
825 pull=opts.get('pull'),
823 stream=opts.get('uncompressed'),
826 stream=opts.get('uncompressed'),
824 rev=opts.get('rev'),
827 rev=opts.get('rev'),
825 update=opts.get('updaterev') or not opts.get('noupdate'),
828 update=opts.get('updaterev') or not opts.get('noupdate'),
826 branch=opts.get('branch'))
829 branch=opts.get('branch'))
827
830
828 return r is None
831 return r is None
829
832
830 def commit(ui, repo, *pats, **opts):
833 def commit(ui, repo, *pats, **opts):
831 """commit the specified files or all outstanding changes
834 """commit the specified files or all outstanding changes
832
835
833 Commit changes to the given files into the repository. Unlike a
836 Commit changes to the given files into the repository. Unlike a
834 centralized SCM, this operation is a local operation. See
837 centralized SCM, this operation is a local operation. See
835 :hg:`push` for a way to actively distribute your changes.
838 :hg:`push` for a way to actively distribute your changes.
836
839
837 If a list of files is omitted, all changes reported by :hg:`status`
840 If a list of files is omitted, all changes reported by :hg:`status`
838 will be committed.
841 will be committed.
839
842
840 If you are committing the result of a merge, do not provide any
843 If you are committing the result of a merge, do not provide any
841 filenames or -I/-X filters.
844 filenames or -I/-X filters.
842
845
843 If no commit message is specified, Mercurial starts your
846 If no commit message is specified, Mercurial starts your
844 configured editor where you can enter a message. In case your
847 configured editor where you can enter a message. In case your
845 commit fails, you will find a backup of your message in
848 commit fails, you will find a backup of your message in
846 ``.hg/last-message.txt``.
849 ``.hg/last-message.txt``.
847
850
848 See :hg:`help dates` for a list of formats valid for -d/--date.
851 See :hg:`help dates` for a list of formats valid for -d/--date.
849
852
850 Returns 0 on success, 1 if nothing changed.
853 Returns 0 on success, 1 if nothing changed.
851 """
854 """
852 extra = {}
855 extra = {}
853 if opts.get('close_branch'):
856 if opts.get('close_branch'):
854 if repo['.'].node() not in repo.branchheads():
857 if repo['.'].node() not in repo.branchheads():
855 # The topo heads set is included in the branch heads set of the
858 # The topo heads set is included in the branch heads set of the
856 # current branch, so it's sufficient to test branchheads
859 # current branch, so it's sufficient to test branchheads
857 raise util.Abort(_('can only close branch heads'))
860 raise util.Abort(_('can only close branch heads'))
858 extra['close'] = 1
861 extra['close'] = 1
859 e = cmdutil.commiteditor
862 e = cmdutil.commiteditor
860 if opts.get('force_editor'):
863 if opts.get('force_editor'):
861 e = cmdutil.commitforceeditor
864 e = cmdutil.commitforceeditor
862
865
863 def commitfunc(ui, repo, message, match, opts):
866 def commitfunc(ui, repo, message, match, opts):
864 return repo.commit(message, opts.get('user'), opts.get('date'), match,
867 return repo.commit(message, opts.get('user'), opts.get('date'), match,
865 editor=e, extra=extra)
868 editor=e, extra=extra)
866
869
867 branch = repo[None].branch()
870 branch = repo[None].branch()
868 bheads = repo.branchheads(branch)
871 bheads = repo.branchheads(branch)
869
872
870 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
873 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
871 if not node:
874 if not node:
872 stat = repo.status(match=cmdutil.match(repo, pats, opts))
875 stat = repo.status(match=cmdutil.match(repo, pats, opts))
873 if stat[3]:
876 if stat[3]:
874 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
877 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
875 % len(stat[3]))
878 % len(stat[3]))
876 else:
879 else:
877 ui.status(_("nothing changed\n"))
880 ui.status(_("nothing changed\n"))
878 return 1
881 return 1
879
882
880 ctx = repo[node]
883 ctx = repo[node]
881 parents = ctx.parents()
884 parents = ctx.parents()
882
885
883 if bheads and not [x for x in parents
886 if bheads and not [x for x in parents
884 if x.node() in bheads and x.branch() == branch]:
887 if x.node() in bheads and x.branch() == branch]:
885 ui.status(_('created new head\n'))
888 ui.status(_('created new head\n'))
886 # The message is not printed for initial roots. For the other
889 # The message is not printed for initial roots. For the other
887 # changesets, it is printed in the following situations:
890 # changesets, it is printed in the following situations:
888 #
891 #
889 # Par column: for the 2 parents with ...
892 # Par column: for the 2 parents with ...
890 # N: null or no parent
893 # N: null or no parent
891 # B: parent is on another named branch
894 # B: parent is on another named branch
892 # C: parent is a regular non head changeset
895 # C: parent is a regular non head changeset
893 # H: parent was a branch head of the current branch
896 # H: parent was a branch head of the current branch
894 # Msg column: whether we print "created new head" message
897 # Msg column: whether we print "created new head" message
895 # In the following, it is assumed that there already exists some
898 # In the following, it is assumed that there already exists some
896 # initial branch heads of the current branch, otherwise nothing is
899 # initial branch heads of the current branch, otherwise nothing is
897 # printed anyway.
900 # printed anyway.
898 #
901 #
899 # Par Msg Comment
902 # Par Msg Comment
900 # NN y additional topo root
903 # NN y additional topo root
901 #
904 #
902 # BN y additional branch root
905 # BN y additional branch root
903 # CN y additional topo head
906 # CN y additional topo head
904 # HN n usual case
907 # HN n usual case
905 #
908 #
906 # BB y weird additional branch root
909 # BB y weird additional branch root
907 # CB y branch merge
910 # CB y branch merge
908 # HB n merge with named branch
911 # HB n merge with named branch
909 #
912 #
910 # CC y additional head from merge
913 # CC y additional head from merge
911 # CH n merge with a head
914 # CH n merge with a head
912 #
915 #
913 # HH n head merge: head count decreases
916 # HH n head merge: head count decreases
914
917
915 if not opts.get('close_branch'):
918 if not opts.get('close_branch'):
916 for r in parents:
919 for r in parents:
917 if r.extra().get('close') and r.branch() == branch:
920 if r.extra().get('close') and r.branch() == branch:
918 ui.status(_('reopening closed branch head %d\n') % r)
921 ui.status(_('reopening closed branch head %d\n') % r)
919
922
920 if ui.debugflag:
923 if ui.debugflag:
921 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
924 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
922 elif ui.verbose:
925 elif ui.verbose:
923 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
926 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
924
927
925 def copy(ui, repo, *pats, **opts):
928 def copy(ui, repo, *pats, **opts):
926 """mark files as copied for the next commit
929 """mark files as copied for the next commit
927
930
928 Mark dest as having copies of source files. If dest is a
931 Mark dest as having copies of source files. If dest is a
929 directory, copies are put in that directory. If dest is a file,
932 directory, copies are put in that directory. If dest is a file,
930 the source must be a single file.
933 the source must be a single file.
931
934
932 By default, this command copies the contents of files as they
935 By default, this command copies the contents of files as they
933 exist in the working directory. If invoked with -A/--after, the
936 exist in the working directory. If invoked with -A/--after, the
934 operation is recorded, but no copying is performed.
937 operation is recorded, but no copying is performed.
935
938
936 This command takes effect with the next commit. To undo a copy
939 This command takes effect with the next commit. To undo a copy
937 before that, see :hg:`revert`.
940 before that, see :hg:`revert`.
938
941
939 Returns 0 on success, 1 if errors are encountered.
942 Returns 0 on success, 1 if errors are encountered.
940 """
943 """
941 wlock = repo.wlock(False)
944 wlock = repo.wlock(False)
942 try:
945 try:
943 return cmdutil.copy(ui, repo, pats, opts)
946 return cmdutil.copy(ui, repo, pats, opts)
944 finally:
947 finally:
945 wlock.release()
948 wlock.release()
946
949
947 def debugancestor(ui, repo, *args):
950 def debugancestor(ui, repo, *args):
948 """find the ancestor revision of two revisions in a given index"""
951 """find the ancestor revision of two revisions in a given index"""
949 if len(args) == 3:
952 if len(args) == 3:
950 index, rev1, rev2 = args
953 index, rev1, rev2 = args
951 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
954 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
952 lookup = r.lookup
955 lookup = r.lookup
953 elif len(args) == 2:
956 elif len(args) == 2:
954 if not repo:
957 if not repo:
955 raise util.Abort(_("there is no Mercurial repository here "
958 raise util.Abort(_("there is no Mercurial repository here "
956 "(.hg not found)"))
959 "(.hg not found)"))
957 rev1, rev2 = args
960 rev1, rev2 = args
958 r = repo.changelog
961 r = repo.changelog
959 lookup = repo.lookup
962 lookup = repo.lookup
960 else:
963 else:
961 raise util.Abort(_('either two or three arguments required'))
964 raise util.Abort(_('either two or three arguments required'))
962 a = r.ancestor(lookup(rev1), lookup(rev2))
965 a = r.ancestor(lookup(rev1), lookup(rev2))
963 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
966 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
964
967
965 def debugbuilddag(ui, repo, text,
968 def debugbuilddag(ui, repo, text,
966 mergeable_file=False,
969 mergeable_file=False,
967 overwritten_file=False,
970 overwritten_file=False,
968 new_file=False):
971 new_file=False):
969 """builds a repo with a given dag from scratch in the current empty repo
972 """builds a repo with a given dag from scratch in the current empty repo
970
973
971 Elements:
974 Elements:
972
975
973 - "+n" is a linear run of n nodes based on the current default parent
976 - "+n" is a linear run of n nodes based on the current default parent
974 - "." is a single node based on the current default parent
977 - "." is a single node based on the current default parent
975 - "$" resets the default parent to null (implied at the start);
978 - "$" resets the default parent to null (implied at the start);
976 otherwise the default parent is always the last node created
979 otherwise the default parent is always the last node created
977 - "<p" sets the default parent to the backref p
980 - "<p" sets the default parent to the backref p
978 - "*p" is a fork at parent p, which is a backref
981 - "*p" is a fork at parent p, which is a backref
979 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
982 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
980 - "/p2" is a merge of the preceding node and p2
983 - "/p2" is a merge of the preceding node and p2
981 - ":tag" defines a local tag for the preceding node
984 - ":tag" defines a local tag for the preceding node
982 - "@branch" sets the named branch for subsequent nodes
985 - "@branch" sets the named branch for subsequent nodes
983 - "#...\\n" is a comment up to the end of the line
986 - "#...\\n" is a comment up to the end of the line
984
987
985 Whitespace between the above elements is ignored.
988 Whitespace between the above elements is ignored.
986
989
987 A backref is either
990 A backref is either
988
991
989 - a number n, which references the node curr-n, where curr is the current
992 - a number n, which references the node curr-n, where curr is the current
990 node, or
993 node, or
991 - the name of a local tag you placed earlier using ":tag", or
994 - the name of a local tag you placed earlier using ":tag", or
992 - empty to denote the default parent.
995 - empty to denote the default parent.
993
996
994 All string valued-elements are either strictly alphanumeric, or must
997 All string valued-elements are either strictly alphanumeric, or must
995 be enclosed in double quotes ("..."), with "\\" as escape character.
998 be enclosed in double quotes ("..."), with "\\" as escape character.
996 """
999 """
997
1000
998 cl = repo.changelog
1001 cl = repo.changelog
999 if len(cl) > 0:
1002 if len(cl) > 0:
1000 raise util.Abort(_('repository is not empty'))
1003 raise util.Abort(_('repository is not empty'))
1001
1004
1002 if mergeable_file:
1005 if mergeable_file:
1003 linesperrev = 2
1006 linesperrev = 2
1004 # determine number of revs in DAG
1007 # determine number of revs in DAG
1005 n = 0
1008 n = 0
1006 for type, data in dagparser.parsedag(text):
1009 for type, data in dagparser.parsedag(text):
1007 if type == 'n':
1010 if type == 'n':
1008 n += 1
1011 n += 1
1009 # make a file with k lines per rev
1012 # make a file with k lines per rev
1010 initialmergedlines = [str(i) for i in xrange(0, n * linesperrev)]
1013 initialmergedlines = [str(i) for i in xrange(0, n * linesperrev)]
1011 initialmergedlines.append("")
1014 initialmergedlines.append("")
1012
1015
1013 tags = []
1016 tags = []
1014
1017
1015 tr = repo.transaction("builddag")
1018 tr = repo.transaction("builddag")
1016 try:
1019 try:
1017
1020
1018 at = -1
1021 at = -1
1019 atbranch = 'default'
1022 atbranch = 'default'
1020 nodeids = []
1023 nodeids = []
1021 for type, data in dagparser.parsedag(text):
1024 for type, data in dagparser.parsedag(text):
1022 if type == 'n':
1025 if type == 'n':
1023 ui.note('node %s\n' % str(data))
1026 ui.note('node %s\n' % str(data))
1024 id, ps = data
1027 id, ps = data
1025
1028
1026 files = []
1029 files = []
1027 fctxs = {}
1030 fctxs = {}
1028
1031
1029 p2 = None
1032 p2 = None
1030 if mergeable_file:
1033 if mergeable_file:
1031 fn = "mf"
1034 fn = "mf"
1032 p1 = repo[ps[0]]
1035 p1 = repo[ps[0]]
1033 if len(ps) > 1:
1036 if len(ps) > 1:
1034 p2 = repo[ps[1]]
1037 p2 = repo[ps[1]]
1035 pa = p1.ancestor(p2)
1038 pa = p1.ancestor(p2)
1036 base, local, other = [x[fn].data() for x in pa, p1, p2]
1039 base, local, other = [x[fn].data() for x in pa, p1, p2]
1037 m3 = simplemerge.Merge3Text(base, local, other)
1040 m3 = simplemerge.Merge3Text(base, local, other)
1038 ml = [l.strip() for l in m3.merge_lines()]
1041 ml = [l.strip() for l in m3.merge_lines()]
1039 ml.append("")
1042 ml.append("")
1040 elif at > 0:
1043 elif at > 0:
1041 ml = p1[fn].data().split("\n")
1044 ml = p1[fn].data().split("\n")
1042 else:
1045 else:
1043 ml = initialmergedlines
1046 ml = initialmergedlines
1044 ml[id * linesperrev] += " r%i" % id
1047 ml[id * linesperrev] += " r%i" % id
1045 mergedtext = "\n".join(ml)
1048 mergedtext = "\n".join(ml)
1046 files.append(fn)
1049 files.append(fn)
1047 fctxs[fn] = context.memfilectx(fn, mergedtext)
1050 fctxs[fn] = context.memfilectx(fn, mergedtext)
1048
1051
1049 if overwritten_file:
1052 if overwritten_file:
1050 fn = "of"
1053 fn = "of"
1051 files.append(fn)
1054 files.append(fn)
1052 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1055 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1053
1056
1054 if new_file:
1057 if new_file:
1055 fn = "nf%i" % id
1058 fn = "nf%i" % id
1056 files.append(fn)
1059 files.append(fn)
1057 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1060 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1058 if len(ps) > 1:
1061 if len(ps) > 1:
1059 if not p2:
1062 if not p2:
1060 p2 = repo[ps[1]]
1063 p2 = repo[ps[1]]
1061 for fn in p2:
1064 for fn in p2:
1062 if fn.startswith("nf"):
1065 if fn.startswith("nf"):
1063 files.append(fn)
1066 files.append(fn)
1064 fctxs[fn] = p2[fn]
1067 fctxs[fn] = p2[fn]
1065
1068
1066 def fctxfn(repo, cx, path):
1069 def fctxfn(repo, cx, path):
1067 return fctxs.get(path)
1070 return fctxs.get(path)
1068
1071
1069 if len(ps) == 0 or ps[0] < 0:
1072 if len(ps) == 0 or ps[0] < 0:
1070 pars = [None, None]
1073 pars = [None, None]
1071 elif len(ps) == 1:
1074 elif len(ps) == 1:
1072 pars = [nodeids[ps[0]], None]
1075 pars = [nodeids[ps[0]], None]
1073 else:
1076 else:
1074 pars = [nodeids[p] for p in ps]
1077 pars = [nodeids[p] for p in ps]
1075 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1078 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1076 date=(id, 0),
1079 date=(id, 0),
1077 user="debugbuilddag",
1080 user="debugbuilddag",
1078 extra={'branch': atbranch})
1081 extra={'branch': atbranch})
1079 nodeid = repo.commitctx(cx)
1082 nodeid = repo.commitctx(cx)
1080 nodeids.append(nodeid)
1083 nodeids.append(nodeid)
1081 at = id
1084 at = id
1082 elif type == 'l':
1085 elif type == 'l':
1083 id, name = data
1086 id, name = data
1084 ui.note('tag %s\n' % name)
1087 ui.note('tag %s\n' % name)
1085 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1088 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1086 elif type == 'a':
1089 elif type == 'a':
1087 ui.note('branch %s\n' % data)
1090 ui.note('branch %s\n' % data)
1088 atbranch = data
1091 atbranch = data
1089 tr.close()
1092 tr.close()
1090 finally:
1093 finally:
1091 tr.release()
1094 tr.release()
1092
1095
1093 if tags:
1096 if tags:
1094 tagsf = repo.opener("localtags", "w")
1097 tagsf = repo.opener("localtags", "w")
1095 try:
1098 try:
1096 tagsf.write("".join(tags))
1099 tagsf.write("".join(tags))
1097 finally:
1100 finally:
1098 tagsf.close()
1101 tagsf.close()
1099
1102
1100 def debugcommands(ui, cmd='', *args):
1103 def debugcommands(ui, cmd='', *args):
1101 """list all available commands and options"""
1104 """list all available commands and options"""
1102 for cmd, vals in sorted(table.iteritems()):
1105 for cmd, vals in sorted(table.iteritems()):
1103 cmd = cmd.split('|')[0].strip('^')
1106 cmd = cmd.split('|')[0].strip('^')
1104 opts = ', '.join([i[1] for i in vals[1]])
1107 opts = ', '.join([i[1] for i in vals[1]])
1105 ui.write('%s: %s\n' % (cmd, opts))
1108 ui.write('%s: %s\n' % (cmd, opts))
1106
1109
1107 def debugcomplete(ui, cmd='', **opts):
1110 def debugcomplete(ui, cmd='', **opts):
1108 """returns the completion list associated with the given command"""
1111 """returns the completion list associated with the given command"""
1109
1112
1110 if opts.get('options'):
1113 if opts.get('options'):
1111 options = []
1114 options = []
1112 otables = [globalopts]
1115 otables = [globalopts]
1113 if cmd:
1116 if cmd:
1114 aliases, entry = cmdutil.findcmd(cmd, table, False)
1117 aliases, entry = cmdutil.findcmd(cmd, table, False)
1115 otables.append(entry[1])
1118 otables.append(entry[1])
1116 for t in otables:
1119 for t in otables:
1117 for o in t:
1120 for o in t:
1118 if "(DEPRECATED)" in o[3]:
1121 if "(DEPRECATED)" in o[3]:
1119 continue
1122 continue
1120 if o[0]:
1123 if o[0]:
1121 options.append('-%s' % o[0])
1124 options.append('-%s' % o[0])
1122 options.append('--%s' % o[1])
1125 options.append('--%s' % o[1])
1123 ui.write("%s\n" % "\n".join(options))
1126 ui.write("%s\n" % "\n".join(options))
1124 return
1127 return
1125
1128
1126 cmdlist = cmdutil.findpossible(cmd, table)
1129 cmdlist = cmdutil.findpossible(cmd, table)
1127 if ui.verbose:
1130 if ui.verbose:
1128 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1131 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1129 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1132 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1130
1133
1131 def debugfsinfo(ui, path = "."):
1134 def debugfsinfo(ui, path = "."):
1132 """show information detected about current filesystem"""
1135 """show information detected about current filesystem"""
1133 util.writefile('.debugfsinfo', '')
1136 util.writefile('.debugfsinfo', '')
1134 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1137 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1135 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1138 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1136 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1139 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1137 and 'yes' or 'no'))
1140 and 'yes' or 'no'))
1138 os.unlink('.debugfsinfo')
1141 os.unlink('.debugfsinfo')
1139
1142
1140 def debugrebuildstate(ui, repo, rev="tip"):
1143 def debugrebuildstate(ui, repo, rev="tip"):
1141 """rebuild the dirstate as it would look like for the given revision"""
1144 """rebuild the dirstate as it would look like for the given revision"""
1142 ctx = cmdutil.revsingle(repo, rev)
1145 ctx = cmdutil.revsingle(repo, rev)
1143 wlock = repo.wlock()
1146 wlock = repo.wlock()
1144 try:
1147 try:
1145 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1148 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1146 finally:
1149 finally:
1147 wlock.release()
1150 wlock.release()
1148
1151
1149 def debugcheckstate(ui, repo):
1152 def debugcheckstate(ui, repo):
1150 """validate the correctness of the current dirstate"""
1153 """validate the correctness of the current dirstate"""
1151 parent1, parent2 = repo.dirstate.parents()
1154 parent1, parent2 = repo.dirstate.parents()
1152 m1 = repo[parent1].manifest()
1155 m1 = repo[parent1].manifest()
1153 m2 = repo[parent2].manifest()
1156 m2 = repo[parent2].manifest()
1154 errors = 0
1157 errors = 0
1155 for f in repo.dirstate:
1158 for f in repo.dirstate:
1156 state = repo.dirstate[f]
1159 state = repo.dirstate[f]
1157 if state in "nr" and f not in m1:
1160 if state in "nr" and f not in m1:
1158 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1161 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1159 errors += 1
1162 errors += 1
1160 if state in "a" and f in m1:
1163 if state in "a" and f in m1:
1161 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1164 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1162 errors += 1
1165 errors += 1
1163 if state in "m" and f not in m1 and f not in m2:
1166 if state in "m" and f not in m1 and f not in m2:
1164 ui.warn(_("%s in state %s, but not in either manifest\n") %
1167 ui.warn(_("%s in state %s, but not in either manifest\n") %
1165 (f, state))
1168 (f, state))
1166 errors += 1
1169 errors += 1
1167 for f in m1:
1170 for f in m1:
1168 state = repo.dirstate[f]
1171 state = repo.dirstate[f]
1169 if state not in "nrm":
1172 if state not in "nrm":
1170 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1173 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1171 errors += 1
1174 errors += 1
1172 if errors:
1175 if errors:
1173 error = _(".hg/dirstate inconsistent with current parent's manifest")
1176 error = _(".hg/dirstate inconsistent with current parent's manifest")
1174 raise util.Abort(error)
1177 raise util.Abort(error)
1175
1178
1176 def showconfig(ui, repo, *values, **opts):
1179 def showconfig(ui, repo, *values, **opts):
1177 """show combined config settings from all hgrc files
1180 """show combined config settings from all hgrc files
1178
1181
1179 With no arguments, print names and values of all config items.
1182 With no arguments, print names and values of all config items.
1180
1183
1181 With one argument of the form section.name, print just the value
1184 With one argument of the form section.name, print just the value
1182 of that config item.
1185 of that config item.
1183
1186
1184 With multiple arguments, print names and values of all config
1187 With multiple arguments, print names and values of all config
1185 items with matching section names.
1188 items with matching section names.
1186
1189
1187 With --debug, the source (filename and line number) is printed
1190 With --debug, the source (filename and line number) is printed
1188 for each config item.
1191 for each config item.
1189
1192
1190 Returns 0 on success.
1193 Returns 0 on success.
1191 """
1194 """
1192
1195
1193 for f in scmutil.rcpath():
1196 for f in scmutil.rcpath():
1194 ui.debug(_('read config from: %s\n') % f)
1197 ui.debug(_('read config from: %s\n') % f)
1195 untrusted = bool(opts.get('untrusted'))
1198 untrusted = bool(opts.get('untrusted'))
1196 if values:
1199 if values:
1197 sections = [v for v in values if '.' not in v]
1200 sections = [v for v in values if '.' not in v]
1198 items = [v for v in values if '.' in v]
1201 items = [v for v in values if '.' in v]
1199 if len(items) > 1 or items and sections:
1202 if len(items) > 1 or items and sections:
1200 raise util.Abort(_('only one config item permitted'))
1203 raise util.Abort(_('only one config item permitted'))
1201 for section, name, value in ui.walkconfig(untrusted=untrusted):
1204 for section, name, value in ui.walkconfig(untrusted=untrusted):
1202 value = str(value).replace('\n', '\\n')
1205 value = str(value).replace('\n', '\\n')
1203 sectname = section + '.' + name
1206 sectname = section + '.' + name
1204 if values:
1207 if values:
1205 for v in values:
1208 for v in values:
1206 if v == section:
1209 if v == section:
1207 ui.debug('%s: ' %
1210 ui.debug('%s: ' %
1208 ui.configsource(section, name, untrusted))
1211 ui.configsource(section, name, untrusted))
1209 ui.write('%s=%s\n' % (sectname, value))
1212 ui.write('%s=%s\n' % (sectname, value))
1210 elif v == sectname:
1213 elif v == sectname:
1211 ui.debug('%s: ' %
1214 ui.debug('%s: ' %
1212 ui.configsource(section, name, untrusted))
1215 ui.configsource(section, name, untrusted))
1213 ui.write(value, '\n')
1216 ui.write(value, '\n')
1214 else:
1217 else:
1215 ui.debug('%s: ' %
1218 ui.debug('%s: ' %
1216 ui.configsource(section, name, untrusted))
1219 ui.configsource(section, name, untrusted))
1217 ui.write('%s=%s\n' % (sectname, value))
1220 ui.write('%s=%s\n' % (sectname, value))
1218
1221
1219 def debugknown(ui, repopath, *ids, **opts):
1222 def debugknown(ui, repopath, *ids, **opts):
1220 """test whether node ids are known to a repo
1223 """test whether node ids are known to a repo
1221
1224
1222 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1225 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1223 indicating unknown/known.
1226 indicating unknown/known.
1224 """
1227 """
1225 repo = hg.repository(ui, repopath)
1228 repo = hg.repository(ui, repopath)
1226 if not repo.capable('known'):
1229 if not repo.capable('known'):
1227 raise util.Abort("known() not supported by target repository")
1230 raise util.Abort("known() not supported by target repository")
1228 flags = repo.known([bin(s) for s in ids])
1231 flags = repo.known([bin(s) for s in ids])
1229 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1232 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1230
1233
1231 def debugbundle(ui, bundlepath, all=None, **opts):
1234 def debugbundle(ui, bundlepath, all=None, **opts):
1232 """lists the contents of a bundle"""
1235 """lists the contents of a bundle"""
1233 f = url.open(ui, bundlepath)
1236 f = url.open(ui, bundlepath)
1234 try:
1237 try:
1235 gen = changegroup.readbundle(f, bundlepath)
1238 gen = changegroup.readbundle(f, bundlepath)
1236 if all:
1239 if all:
1237 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1240 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1238
1241
1239 def showchunks(named):
1242 def showchunks(named):
1240 ui.write("\n%s\n" % named)
1243 ui.write("\n%s\n" % named)
1241 chain = None
1244 chain = None
1242 while 1:
1245 while 1:
1243 chunkdata = gen.deltachunk(chain)
1246 chunkdata = gen.deltachunk(chain)
1244 if not chunkdata:
1247 if not chunkdata:
1245 break
1248 break
1246 node = chunkdata['node']
1249 node = chunkdata['node']
1247 p1 = chunkdata['p1']
1250 p1 = chunkdata['p1']
1248 p2 = chunkdata['p2']
1251 p2 = chunkdata['p2']
1249 cs = chunkdata['cs']
1252 cs = chunkdata['cs']
1250 deltabase = chunkdata['deltabase']
1253 deltabase = chunkdata['deltabase']
1251 delta = chunkdata['delta']
1254 delta = chunkdata['delta']
1252 ui.write("%s %s %s %s %s %s\n" %
1255 ui.write("%s %s %s %s %s %s\n" %
1253 (hex(node), hex(p1), hex(p2),
1256 (hex(node), hex(p1), hex(p2),
1254 hex(cs), hex(deltabase), len(delta)))
1257 hex(cs), hex(deltabase), len(delta)))
1255 chain = node
1258 chain = node
1256
1259
1257 chunkdata = gen.changelogheader()
1260 chunkdata = gen.changelogheader()
1258 showchunks("changelog")
1261 showchunks("changelog")
1259 chunkdata = gen.manifestheader()
1262 chunkdata = gen.manifestheader()
1260 showchunks("manifest")
1263 showchunks("manifest")
1261 while 1:
1264 while 1:
1262 chunkdata = gen.filelogheader()
1265 chunkdata = gen.filelogheader()
1263 if not chunkdata:
1266 if not chunkdata:
1264 break
1267 break
1265 fname = chunkdata['filename']
1268 fname = chunkdata['filename']
1266 showchunks(fname)
1269 showchunks(fname)
1267 else:
1270 else:
1268 chunkdata = gen.changelogheader()
1271 chunkdata = gen.changelogheader()
1269 chain = None
1272 chain = None
1270 while 1:
1273 while 1:
1271 chunkdata = gen.deltachunk(chain)
1274 chunkdata = gen.deltachunk(chain)
1272 if not chunkdata:
1275 if not chunkdata:
1273 break
1276 break
1274 node = chunkdata['node']
1277 node = chunkdata['node']
1275 ui.write("%s\n" % hex(node))
1278 ui.write("%s\n" % hex(node))
1276 chain = node
1279 chain = node
1277 finally:
1280 finally:
1278 f.close()
1281 f.close()
1279
1282
1280 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1283 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1281 """retrieves a bundle from a repo
1284 """retrieves a bundle from a repo
1282
1285
1283 Every ID must be a full-length hex node id string. Saves the bundle to the
1286 Every ID must be a full-length hex node id string. Saves the bundle to the
1284 given file.
1287 given file.
1285 """
1288 """
1286 repo = hg.repository(ui, repopath)
1289 repo = hg.repository(ui, repopath)
1287 if not repo.capable('getbundle'):
1290 if not repo.capable('getbundle'):
1288 raise util.Abort("getbundle() not supported by target repository")
1291 raise util.Abort("getbundle() not supported by target repository")
1289 args = {}
1292 args = {}
1290 if common:
1293 if common:
1291 args['common'] = [bin(s) for s in common]
1294 args['common'] = [bin(s) for s in common]
1292 if head:
1295 if head:
1293 args['heads'] = [bin(s) for s in head]
1296 args['heads'] = [bin(s) for s in head]
1294 bundle = repo.getbundle('debug', **args)
1297 bundle = repo.getbundle('debug', **args)
1295
1298
1296 bundletype = opts.get('type', 'bzip2').lower()
1299 bundletype = opts.get('type', 'bzip2').lower()
1297 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1300 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1298 bundletype = btypes.get(bundletype)
1301 bundletype = btypes.get(bundletype)
1299 if bundletype not in changegroup.bundletypes:
1302 if bundletype not in changegroup.bundletypes:
1300 raise util.Abort(_('unknown bundle type specified with --type'))
1303 raise util.Abort(_('unknown bundle type specified with --type'))
1301 changegroup.writebundle(bundle, bundlepath, bundletype)
1304 changegroup.writebundle(bundle, bundlepath, bundletype)
1302
1305
1303 def debugpushkey(ui, repopath, namespace, *keyinfo):
1306 def debugpushkey(ui, repopath, namespace, *keyinfo):
1304 '''access the pushkey key/value protocol
1307 '''access the pushkey key/value protocol
1305
1308
1306 With two args, list the keys in the given namespace.
1309 With two args, list the keys in the given namespace.
1307
1310
1308 With five args, set a key to new if it currently is set to old.
1311 With five args, set a key to new if it currently is set to old.
1309 Reports success or failure.
1312 Reports success or failure.
1310 '''
1313 '''
1311
1314
1312 target = hg.repository(ui, repopath)
1315 target = hg.repository(ui, repopath)
1313 if keyinfo:
1316 if keyinfo:
1314 key, old, new = keyinfo
1317 key, old, new = keyinfo
1315 r = target.pushkey(namespace, key, old, new)
1318 r = target.pushkey(namespace, key, old, new)
1316 ui.status(str(r) + '\n')
1319 ui.status(str(r) + '\n')
1317 return not r
1320 return not r
1318 else:
1321 else:
1319 for k, v in target.listkeys(namespace).iteritems():
1322 for k, v in target.listkeys(namespace).iteritems():
1320 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1323 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1321 v.encode('string-escape')))
1324 v.encode('string-escape')))
1322
1325
1323 def debugrevspec(ui, repo, expr):
1326 def debugrevspec(ui, repo, expr):
1324 '''parse and apply a revision specification'''
1327 '''parse and apply a revision specification'''
1325 if ui.verbose:
1328 if ui.verbose:
1326 tree = revset.parse(expr)[0]
1329 tree = revset.parse(expr)[0]
1327 ui.note(tree, "\n")
1330 ui.note(tree, "\n")
1328 newtree = revset.findaliases(ui, tree)
1331 newtree = revset.findaliases(ui, tree)
1329 if newtree != tree:
1332 if newtree != tree:
1330 ui.note(newtree, "\n")
1333 ui.note(newtree, "\n")
1331 func = revset.match(ui, expr)
1334 func = revset.match(ui, expr)
1332 for c in func(repo, range(len(repo))):
1335 for c in func(repo, range(len(repo))):
1333 ui.write("%s\n" % c)
1336 ui.write("%s\n" % c)
1334
1337
1335 def debugsetparents(ui, repo, rev1, rev2=None):
1338 def debugsetparents(ui, repo, rev1, rev2=None):
1336 """manually set the parents of the current working directory
1339 """manually set the parents of the current working directory
1337
1340
1338 This is useful for writing repository conversion tools, but should
1341 This is useful for writing repository conversion tools, but should
1339 be used with care.
1342 be used with care.
1340
1343
1341 Returns 0 on success.
1344 Returns 0 on success.
1342 """
1345 """
1343
1346
1344 r1 = cmdutil.revsingle(repo, rev1).node()
1347 r1 = cmdutil.revsingle(repo, rev1).node()
1345 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1348 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1346
1349
1347 wlock = repo.wlock()
1350 wlock = repo.wlock()
1348 try:
1351 try:
1349 repo.dirstate.setparents(r1, r2)
1352 repo.dirstate.setparents(r1, r2)
1350 finally:
1353 finally:
1351 wlock.release()
1354 wlock.release()
1352
1355
1353 def debugstate(ui, repo, nodates=None, datesort=None):
1356 def debugstate(ui, repo, nodates=None, datesort=None):
1354 """show the contents of the current dirstate"""
1357 """show the contents of the current dirstate"""
1355 timestr = ""
1358 timestr = ""
1356 showdate = not nodates
1359 showdate = not nodates
1357 if datesort:
1360 if datesort:
1358 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
1361 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
1359 else:
1362 else:
1360 keyfunc = None # sort by filename
1363 keyfunc = None # sort by filename
1361 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
1364 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
1362 if showdate:
1365 if showdate:
1363 if ent[3] == -1:
1366 if ent[3] == -1:
1364 # Pad or slice to locale representation
1367 # Pad or slice to locale representation
1365 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1368 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1366 time.localtime(0)))
1369 time.localtime(0)))
1367 timestr = 'unset'
1370 timestr = 'unset'
1368 timestr = (timestr[:locale_len] +
1371 timestr = (timestr[:locale_len] +
1369 ' ' * (locale_len - len(timestr)))
1372 ' ' * (locale_len - len(timestr)))
1370 else:
1373 else:
1371 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1374 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1372 time.localtime(ent[3]))
1375 time.localtime(ent[3]))
1373 if ent[1] & 020000:
1376 if ent[1] & 020000:
1374 mode = 'lnk'
1377 mode = 'lnk'
1375 else:
1378 else:
1376 mode = '%3o' % (ent[1] & 0777)
1379 mode = '%3o' % (ent[1] & 0777)
1377 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1380 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1378 for f in repo.dirstate.copies():
1381 for f in repo.dirstate.copies():
1379 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1382 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1380
1383
1381 def debugsub(ui, repo, rev=None):
1384 def debugsub(ui, repo, rev=None):
1382 ctx = cmdutil.revsingle(repo, rev, None)
1385 ctx = cmdutil.revsingle(repo, rev, None)
1383 for k, v in sorted(ctx.substate.items()):
1386 for k, v in sorted(ctx.substate.items()):
1384 ui.write('path %s\n' % k)
1387 ui.write('path %s\n' % k)
1385 ui.write(' source %s\n' % v[0])
1388 ui.write(' source %s\n' % v[0])
1386 ui.write(' revision %s\n' % v[1])
1389 ui.write(' revision %s\n' % v[1])
1387
1390
1388 def debugdag(ui, repo, file_=None, *revs, **opts):
1391 def debugdag(ui, repo, file_=None, *revs, **opts):
1389 """format the changelog or an index DAG as a concise textual description
1392 """format the changelog or an index DAG as a concise textual description
1390
1393
1391 If you pass a revlog index, the revlog's DAG is emitted. If you list
1394 If you pass a revlog index, the revlog's DAG is emitted. If you list
1392 revision numbers, they get labelled in the output as rN.
1395 revision numbers, they get labelled in the output as rN.
1393
1396
1394 Otherwise, the changelog DAG of the current repo is emitted.
1397 Otherwise, the changelog DAG of the current repo is emitted.
1395 """
1398 """
1396 spaces = opts.get('spaces')
1399 spaces = opts.get('spaces')
1397 dots = opts.get('dots')
1400 dots = opts.get('dots')
1398 if file_:
1401 if file_:
1399 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1402 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1400 revs = set((int(r) for r in revs))
1403 revs = set((int(r) for r in revs))
1401 def events():
1404 def events():
1402 for r in rlog:
1405 for r in rlog:
1403 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1406 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1404 if r in revs:
1407 if r in revs:
1405 yield 'l', (r, "r%i" % r)
1408 yield 'l', (r, "r%i" % r)
1406 elif repo:
1409 elif repo:
1407 cl = repo.changelog
1410 cl = repo.changelog
1408 tags = opts.get('tags')
1411 tags = opts.get('tags')
1409 branches = opts.get('branches')
1412 branches = opts.get('branches')
1410 if tags:
1413 if tags:
1411 labels = {}
1414 labels = {}
1412 for l, n in repo.tags().items():
1415 for l, n in repo.tags().items():
1413 labels.setdefault(cl.rev(n), []).append(l)
1416 labels.setdefault(cl.rev(n), []).append(l)
1414 def events():
1417 def events():
1415 b = "default"
1418 b = "default"
1416 for r in cl:
1419 for r in cl:
1417 if branches:
1420 if branches:
1418 newb = cl.read(cl.node(r))[5]['branch']
1421 newb = cl.read(cl.node(r))[5]['branch']
1419 if newb != b:
1422 if newb != b:
1420 yield 'a', newb
1423 yield 'a', newb
1421 b = newb
1424 b = newb
1422 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1425 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1423 if tags:
1426 if tags:
1424 ls = labels.get(r)
1427 ls = labels.get(r)
1425 if ls:
1428 if ls:
1426 for l in ls:
1429 for l in ls:
1427 yield 'l', (r, l)
1430 yield 'l', (r, l)
1428 else:
1431 else:
1429 raise util.Abort(_('need repo for changelog dag'))
1432 raise util.Abort(_('need repo for changelog dag'))
1430
1433
1431 for line in dagparser.dagtextlines(events(),
1434 for line in dagparser.dagtextlines(events(),
1432 addspaces=spaces,
1435 addspaces=spaces,
1433 wraplabels=True,
1436 wraplabels=True,
1434 wrapannotations=True,
1437 wrapannotations=True,
1435 wrapnonlinear=dots,
1438 wrapnonlinear=dots,
1436 usedots=dots,
1439 usedots=dots,
1437 maxlinewidth=70):
1440 maxlinewidth=70):
1438 ui.write(line)
1441 ui.write(line)
1439 ui.write("\n")
1442 ui.write("\n")
1440
1443
1441 def debugdata(ui, repo, file_, rev):
1444 def debugdata(ui, repo, file_, rev):
1442 """dump the contents of a data file revision"""
1445 """dump the contents of a data file revision"""
1443 r = None
1446 r = None
1444 if repo:
1447 if repo:
1445 filelog = repo.file(file_)
1448 filelog = repo.file(file_)
1446 if len(filelog):
1449 if len(filelog):
1447 r = filelog
1450 r = filelog
1448 if not r:
1451 if not r:
1449 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
1452 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
1450 file_[:-2] + ".i")
1453 file_[:-2] + ".i")
1451 try:
1454 try:
1452 ui.write(r.revision(r.lookup(rev)))
1455 ui.write(r.revision(r.lookup(rev)))
1453 except KeyError:
1456 except KeyError:
1454 raise util.Abort(_('invalid revision identifier %s') % rev)
1457 raise util.Abort(_('invalid revision identifier %s') % rev)
1455
1458
1456 def debugdate(ui, date, range=None, **opts):
1459 def debugdate(ui, date, range=None, **opts):
1457 """parse and display a date"""
1460 """parse and display a date"""
1458 if opts["extended"]:
1461 if opts["extended"]:
1459 d = util.parsedate(date, util.extendeddateformats)
1462 d = util.parsedate(date, util.extendeddateformats)
1460 else:
1463 else:
1461 d = util.parsedate(date)
1464 d = util.parsedate(date)
1462 ui.write("internal: %s %s\n" % d)
1465 ui.write("internal: %s %s\n" % d)
1463 ui.write("standard: %s\n" % util.datestr(d))
1466 ui.write("standard: %s\n" % util.datestr(d))
1464 if range:
1467 if range:
1465 m = util.matchdate(range)
1468 m = util.matchdate(range)
1466 ui.write("match: %s\n" % m(d[0]))
1469 ui.write("match: %s\n" % m(d[0]))
1467
1470
1468 def debugignore(ui, repo, *values, **opts):
1471 def debugignore(ui, repo, *values, **opts):
1469 """display the combined ignore pattern"""
1472 """display the combined ignore pattern"""
1470 ignore = repo.dirstate._ignore
1473 ignore = repo.dirstate._ignore
1471 if hasattr(ignore, 'includepat'):
1474 if hasattr(ignore, 'includepat'):
1472 ui.write("%s\n" % ignore.includepat)
1475 ui.write("%s\n" % ignore.includepat)
1473 else:
1476 else:
1474 raise util.Abort(_("no ignore patterns found"))
1477 raise util.Abort(_("no ignore patterns found"))
1475
1478
1476 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1479 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1477 """runs the changeset discovery protocol in isolation"""
1480 """runs the changeset discovery protocol in isolation"""
1478 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1481 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1479 remote = hg.repository(hg.remoteui(repo, opts), remoteurl)
1482 remote = hg.repository(hg.remoteui(repo, opts), remoteurl)
1480 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1483 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1481
1484
1482 # make sure tests are repeatable
1485 # make sure tests are repeatable
1483 random.seed(12323)
1486 random.seed(12323)
1484
1487
1485 def doit(localheads, remoteheads):
1488 def doit(localheads, remoteheads):
1486 if opts.get('old'):
1489 if opts.get('old'):
1487 if localheads:
1490 if localheads:
1488 raise util.Abort('cannot use localheads with old style discovery')
1491 raise util.Abort('cannot use localheads with old style discovery')
1489 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1492 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1490 force=True)
1493 force=True)
1491 common = set(common)
1494 common = set(common)
1492 if not opts.get('nonheads'):
1495 if not opts.get('nonheads'):
1493 ui.write("unpruned common: %s\n" % " ".join([short(n)
1496 ui.write("unpruned common: %s\n" % " ".join([short(n)
1494 for n in common]))
1497 for n in common]))
1495 dag = dagutil.revlogdag(repo.changelog)
1498 dag = dagutil.revlogdag(repo.changelog)
1496 all = dag.ancestorset(dag.internalizeall(common))
1499 all = dag.ancestorset(dag.internalizeall(common))
1497 common = dag.externalizeall(dag.headsetofconnecteds(all))
1500 common = dag.externalizeall(dag.headsetofconnecteds(all))
1498 else:
1501 else:
1499 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1502 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1500 common = set(common)
1503 common = set(common)
1501 rheads = set(hds)
1504 rheads = set(hds)
1502 lheads = set(repo.heads())
1505 lheads = set(repo.heads())
1503 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1506 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1504 if lheads <= common:
1507 if lheads <= common:
1505 ui.write("local is subset\n")
1508 ui.write("local is subset\n")
1506 elif rheads <= common:
1509 elif rheads <= common:
1507 ui.write("remote is subset\n")
1510 ui.write("remote is subset\n")
1508
1511
1509 serverlogs = opts.get('serverlog')
1512 serverlogs = opts.get('serverlog')
1510 if serverlogs:
1513 if serverlogs:
1511 for filename in serverlogs:
1514 for filename in serverlogs:
1512 logfile = open(filename, 'r')
1515 logfile = open(filename, 'r')
1513 try:
1516 try:
1514 line = logfile.readline()
1517 line = logfile.readline()
1515 while line:
1518 while line:
1516 parts = line.strip().split(';')
1519 parts = line.strip().split(';')
1517 op = parts[1]
1520 op = parts[1]
1518 if op == 'cg':
1521 if op == 'cg':
1519 pass
1522 pass
1520 elif op == 'cgss':
1523 elif op == 'cgss':
1521 doit(parts[2].split(' '), parts[3].split(' '))
1524 doit(parts[2].split(' '), parts[3].split(' '))
1522 elif op == 'unb':
1525 elif op == 'unb':
1523 doit(parts[3].split(' '), parts[2].split(' '))
1526 doit(parts[3].split(' '), parts[2].split(' '))
1524 line = logfile.readline()
1527 line = logfile.readline()
1525 finally:
1528 finally:
1526 logfile.close()
1529 logfile.close()
1527
1530
1528 else:
1531 else:
1529 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1532 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1530 opts.get('remote_head'))
1533 opts.get('remote_head'))
1531 localrevs = opts.get('local_head')
1534 localrevs = opts.get('local_head')
1532 doit(localrevs, remoterevs)
1535 doit(localrevs, remoterevs)
1533
1536
1534
1537
1535 def debugindex(ui, repo, file_, **opts):
1538 def debugindex(ui, repo, file_, **opts):
1536 """dump the contents of an index file"""
1539 """dump the contents of an index file"""
1537 r = None
1540 r = None
1538 if repo:
1541 if repo:
1539 filelog = repo.file(file_)
1542 filelog = repo.file(file_)
1540 if len(filelog):
1543 if len(filelog):
1541 r = filelog
1544 r = filelog
1542
1545
1543 format = opts.get('format', 0)
1546 format = opts.get('format', 0)
1544 if format not in (0, 1):
1547 if format not in (0, 1):
1545 raise util.Abort(_("unknown format %d") % format)
1548 raise util.Abort(_("unknown format %d") % format)
1546
1549
1547 if not r:
1550 if not r:
1548 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1551 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1549
1552
1550 if format == 0:
1553 if format == 0:
1551 ui.write(" rev offset length base linkrev"
1554 ui.write(" rev offset length base linkrev"
1552 " nodeid p1 p2\n")
1555 " nodeid p1 p2\n")
1553 elif format == 1:
1556 elif format == 1:
1554 ui.write(" rev flag offset length"
1557 ui.write(" rev flag offset length"
1555 " size base link p1 p2 nodeid\n")
1558 " size base link p1 p2 nodeid\n")
1556
1559
1557 for i in r:
1560 for i in r:
1558 node = r.node(i)
1561 node = r.node(i)
1559 if format == 0:
1562 if format == 0:
1560 try:
1563 try:
1561 pp = r.parents(node)
1564 pp = r.parents(node)
1562 except:
1565 except:
1563 pp = [nullid, nullid]
1566 pp = [nullid, nullid]
1564 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1567 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1565 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1568 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1566 short(node), short(pp[0]), short(pp[1])))
1569 short(node), short(pp[0]), short(pp[1])))
1567 elif format == 1:
1570 elif format == 1:
1568 pr = r.parentrevs(i)
1571 pr = r.parentrevs(i)
1569 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1572 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1570 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1573 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1571 r.base(i), r.linkrev(i), pr[0], pr[1], short(node)))
1574 r.base(i), r.linkrev(i), pr[0], pr[1], short(node)))
1572
1575
1573 def debugindexdot(ui, repo, file_):
1576 def debugindexdot(ui, repo, file_):
1574 """dump an index DAG as a graphviz dot file"""
1577 """dump an index DAG as a graphviz dot file"""
1575 r = None
1578 r = None
1576 if repo:
1579 if repo:
1577 filelog = repo.file(file_)
1580 filelog = repo.file(file_)
1578 if len(filelog):
1581 if len(filelog):
1579 r = filelog
1582 r = filelog
1580 if not r:
1583 if not r:
1581 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1584 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1582 ui.write("digraph G {\n")
1585 ui.write("digraph G {\n")
1583 for i in r:
1586 for i in r:
1584 node = r.node(i)
1587 node = r.node(i)
1585 pp = r.parents(node)
1588 pp = r.parents(node)
1586 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1589 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1587 if pp[1] != nullid:
1590 if pp[1] != nullid:
1588 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1591 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1589 ui.write("}\n")
1592 ui.write("}\n")
1590
1593
1591 def debuginstall(ui):
1594 def debuginstall(ui):
1592 '''test Mercurial installation
1595 '''test Mercurial installation
1593
1596
1594 Returns 0 on success.
1597 Returns 0 on success.
1595 '''
1598 '''
1596
1599
1597 def writetemp(contents):
1600 def writetemp(contents):
1598 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1601 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1599 f = os.fdopen(fd, "wb")
1602 f = os.fdopen(fd, "wb")
1600 f.write(contents)
1603 f.write(contents)
1601 f.close()
1604 f.close()
1602 return name
1605 return name
1603
1606
1604 problems = 0
1607 problems = 0
1605
1608
1606 # encoding
1609 # encoding
1607 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1610 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1608 try:
1611 try:
1609 encoding.fromlocal("test")
1612 encoding.fromlocal("test")
1610 except util.Abort, inst:
1613 except util.Abort, inst:
1611 ui.write(" %s\n" % inst)
1614 ui.write(" %s\n" % inst)
1612 ui.write(_(" (check that your locale is properly set)\n"))
1615 ui.write(_(" (check that your locale is properly set)\n"))
1613 problems += 1
1616 problems += 1
1614
1617
1615 # compiled modules
1618 # compiled modules
1616 ui.status(_("Checking installed modules (%s)...\n")
1619 ui.status(_("Checking installed modules (%s)...\n")
1617 % os.path.dirname(__file__))
1620 % os.path.dirname(__file__))
1618 try:
1621 try:
1619 import bdiff, mpatch, base85, osutil
1622 import bdiff, mpatch, base85, osutil
1620 except Exception, inst:
1623 except Exception, inst:
1621 ui.write(" %s\n" % inst)
1624 ui.write(" %s\n" % inst)
1622 ui.write(_(" One or more extensions could not be found"))
1625 ui.write(_(" One or more extensions could not be found"))
1623 ui.write(_(" (check that you compiled the extensions)\n"))
1626 ui.write(_(" (check that you compiled the extensions)\n"))
1624 problems += 1
1627 problems += 1
1625
1628
1626 # templates
1629 # templates
1627 ui.status(_("Checking templates...\n"))
1630 ui.status(_("Checking templates...\n"))
1628 try:
1631 try:
1629 import templater
1632 import templater
1630 templater.templater(templater.templatepath("map-cmdline.default"))
1633 templater.templater(templater.templatepath("map-cmdline.default"))
1631 except Exception, inst:
1634 except Exception, inst:
1632 ui.write(" %s\n" % inst)
1635 ui.write(" %s\n" % inst)
1633 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1636 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1634 problems += 1
1637 problems += 1
1635
1638
1636 # editor
1639 # editor
1637 ui.status(_("Checking commit editor...\n"))
1640 ui.status(_("Checking commit editor...\n"))
1638 editor = ui.geteditor()
1641 editor = ui.geteditor()
1639 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1642 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1640 if not cmdpath:
1643 if not cmdpath:
1641 if editor == 'vi':
1644 if editor == 'vi':
1642 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1645 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1643 ui.write(_(" (specify a commit editor in your configuration"
1646 ui.write(_(" (specify a commit editor in your configuration"
1644 " file)\n"))
1647 " file)\n"))
1645 else:
1648 else:
1646 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1649 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1647 ui.write(_(" (specify a commit editor in your configuration"
1650 ui.write(_(" (specify a commit editor in your configuration"
1648 " file)\n"))
1651 " file)\n"))
1649 problems += 1
1652 problems += 1
1650
1653
1651 # check username
1654 # check username
1652 ui.status(_("Checking username...\n"))
1655 ui.status(_("Checking username...\n"))
1653 try:
1656 try:
1654 ui.username()
1657 ui.username()
1655 except util.Abort, e:
1658 except util.Abort, e:
1656 ui.write(" %s\n" % e)
1659 ui.write(" %s\n" % e)
1657 ui.write(_(" (specify a username in your configuration file)\n"))
1660 ui.write(_(" (specify a username in your configuration file)\n"))
1658 problems += 1
1661 problems += 1
1659
1662
1660 if not problems:
1663 if not problems:
1661 ui.status(_("No problems detected\n"))
1664 ui.status(_("No problems detected\n"))
1662 else:
1665 else:
1663 ui.write(_("%s problems detected,"
1666 ui.write(_("%s problems detected,"
1664 " please check your install!\n") % problems)
1667 " please check your install!\n") % problems)
1665
1668
1666 return problems
1669 return problems
1667
1670
1668 def debugrename(ui, repo, file1, *pats, **opts):
1671 def debugrename(ui, repo, file1, *pats, **opts):
1669 """dump rename information"""
1672 """dump rename information"""
1670
1673
1671 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1674 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1672 m = cmdutil.match(repo, (file1,) + pats, opts)
1675 m = cmdutil.match(repo, (file1,) + pats, opts)
1673 for abs in ctx.walk(m):
1676 for abs in ctx.walk(m):
1674 fctx = ctx[abs]
1677 fctx = ctx[abs]
1675 o = fctx.filelog().renamed(fctx.filenode())
1678 o = fctx.filelog().renamed(fctx.filenode())
1676 rel = m.rel(abs)
1679 rel = m.rel(abs)
1677 if o:
1680 if o:
1678 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1681 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1679 else:
1682 else:
1680 ui.write(_("%s not renamed\n") % rel)
1683 ui.write(_("%s not renamed\n") % rel)
1681
1684
1682 def debugwalk(ui, repo, *pats, **opts):
1685 def debugwalk(ui, repo, *pats, **opts):
1683 """show how files match on given patterns"""
1686 """show how files match on given patterns"""
1684 m = cmdutil.match(repo, pats, opts)
1687 m = cmdutil.match(repo, pats, opts)
1685 items = list(repo.walk(m))
1688 items = list(repo.walk(m))
1686 if not items:
1689 if not items:
1687 return
1690 return
1688 fmt = 'f %%-%ds %%-%ds %%s' % (
1691 fmt = 'f %%-%ds %%-%ds %%s' % (
1689 max([len(abs) for abs in items]),
1692 max([len(abs) for abs in items]),
1690 max([len(m.rel(abs)) for abs in items]))
1693 max([len(m.rel(abs)) for abs in items]))
1691 for abs in items:
1694 for abs in items:
1692 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1695 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1693 ui.write("%s\n" % line.rstrip())
1696 ui.write("%s\n" % line.rstrip())
1694
1697
1695 def debugwireargs(ui, repopath, *vals, **opts):
1698 def debugwireargs(ui, repopath, *vals, **opts):
1696 repo = hg.repository(hg.remoteui(ui, opts), repopath)
1699 repo = hg.repository(hg.remoteui(ui, opts), repopath)
1697 for opt in remoteopts:
1700 for opt in remoteopts:
1698 del opts[opt[1]]
1701 del opts[opt[1]]
1699 args = {}
1702 args = {}
1700 for k, v in opts.iteritems():
1703 for k, v in opts.iteritems():
1701 if v:
1704 if v:
1702 args[k] = v
1705 args[k] = v
1703 # run twice to check that we don't mess up the stream for the next command
1706 # run twice to check that we don't mess up the stream for the next command
1704 res1 = repo.debugwireargs(*vals, **args)
1707 res1 = repo.debugwireargs(*vals, **args)
1705 res2 = repo.debugwireargs(*vals, **args)
1708 res2 = repo.debugwireargs(*vals, **args)
1706 ui.write("%s\n" % res1)
1709 ui.write("%s\n" % res1)
1707 if res1 != res2:
1710 if res1 != res2:
1708 ui.warn("%s\n" % res2)
1711 ui.warn("%s\n" % res2)
1709
1712
1710 def diff(ui, repo, *pats, **opts):
1713 def diff(ui, repo, *pats, **opts):
1711 """diff repository (or selected files)
1714 """diff repository (or selected files)
1712
1715
1713 Show differences between revisions for the specified files.
1716 Show differences between revisions for the specified files.
1714
1717
1715 Differences between files are shown using the unified diff format.
1718 Differences between files are shown using the unified diff format.
1716
1719
1717 .. note::
1720 .. note::
1718 diff may generate unexpected results for merges, as it will
1721 diff may generate unexpected results for merges, as it will
1719 default to comparing against the working directory's first
1722 default to comparing against the working directory's first
1720 parent changeset if no revisions are specified.
1723 parent changeset if no revisions are specified.
1721
1724
1722 When two revision arguments are given, then changes are shown
1725 When two revision arguments are given, then changes are shown
1723 between those revisions. If only one revision is specified then
1726 between those revisions. If only one revision is specified then
1724 that revision is compared to the working directory, and, when no
1727 that revision is compared to the working directory, and, when no
1725 revisions are specified, the working directory files are compared
1728 revisions are specified, the working directory files are compared
1726 to its parent.
1729 to its parent.
1727
1730
1728 Alternatively you can specify -c/--change with a revision to see
1731 Alternatively you can specify -c/--change with a revision to see
1729 the changes in that changeset relative to its first parent.
1732 the changes in that changeset relative to its first parent.
1730
1733
1731 Without the -a/--text option, diff will avoid generating diffs of
1734 Without the -a/--text option, diff will avoid generating diffs of
1732 files it detects as binary. With -a, diff will generate a diff
1735 files it detects as binary. With -a, diff will generate a diff
1733 anyway, probably with undesirable results.
1736 anyway, probably with undesirable results.
1734
1737
1735 Use the -g/--git option to generate diffs in the git extended diff
1738 Use the -g/--git option to generate diffs in the git extended diff
1736 format. For more information, read :hg:`help diffs`.
1739 format. For more information, read :hg:`help diffs`.
1737
1740
1738 Returns 0 on success.
1741 Returns 0 on success.
1739 """
1742 """
1740
1743
1741 revs = opts.get('rev')
1744 revs = opts.get('rev')
1742 change = opts.get('change')
1745 change = opts.get('change')
1743 stat = opts.get('stat')
1746 stat = opts.get('stat')
1744 reverse = opts.get('reverse')
1747 reverse = opts.get('reverse')
1745
1748
1746 if revs and change:
1749 if revs and change:
1747 msg = _('cannot specify --rev and --change at the same time')
1750 msg = _('cannot specify --rev and --change at the same time')
1748 raise util.Abort(msg)
1751 raise util.Abort(msg)
1749 elif change:
1752 elif change:
1750 node2 = cmdutil.revsingle(repo, change, None).node()
1753 node2 = cmdutil.revsingle(repo, change, None).node()
1751 node1 = repo[node2].p1().node()
1754 node1 = repo[node2].p1().node()
1752 else:
1755 else:
1753 node1, node2 = cmdutil.revpair(repo, revs)
1756 node1, node2 = cmdutil.revpair(repo, revs)
1754
1757
1755 if reverse:
1758 if reverse:
1756 node1, node2 = node2, node1
1759 node1, node2 = node2, node1
1757
1760
1758 diffopts = patch.diffopts(ui, opts)
1761 diffopts = patch.diffopts(ui, opts)
1759 m = cmdutil.match(repo, pats, opts)
1762 m = cmdutil.match(repo, pats, opts)
1760 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1763 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1761 listsubrepos=opts.get('subrepos'))
1764 listsubrepos=opts.get('subrepos'))
1762
1765
1763 def export(ui, repo, *changesets, **opts):
1766 def export(ui, repo, *changesets, **opts):
1764 """dump the header and diffs for one or more changesets
1767 """dump the header and diffs for one or more changesets
1765
1768
1766 Print the changeset header and diffs for one or more revisions.
1769 Print the changeset header and diffs for one or more revisions.
1767
1770
1768 The information shown in the changeset header is: author, date,
1771 The information shown in the changeset header is: author, date,
1769 branch name (if non-default), changeset hash, parent(s) and commit
1772 branch name (if non-default), changeset hash, parent(s) and commit
1770 comment.
1773 comment.
1771
1774
1772 .. note::
1775 .. note::
1773 export may generate unexpected diff output for merge
1776 export may generate unexpected diff output for merge
1774 changesets, as it will compare the merge changeset against its
1777 changesets, as it will compare the merge changeset against its
1775 first parent only.
1778 first parent only.
1776
1779
1777 Output may be to a file, in which case the name of the file is
1780 Output may be to a file, in which case the name of the file is
1778 given using a format string. The formatting rules are as follows:
1781 given using a format string. The formatting rules are as follows:
1779
1782
1780 :``%%``: literal "%" character
1783 :``%%``: literal "%" character
1781 :``%H``: changeset hash (40 hexadecimal digits)
1784 :``%H``: changeset hash (40 hexadecimal digits)
1782 :``%N``: number of patches being generated
1785 :``%N``: number of patches being generated
1783 :``%R``: changeset revision number
1786 :``%R``: changeset revision number
1784 :``%b``: basename of the exporting repository
1787 :``%b``: basename of the exporting repository
1785 :``%h``: short-form changeset hash (12 hexadecimal digits)
1788 :``%h``: short-form changeset hash (12 hexadecimal digits)
1786 :``%n``: zero-padded sequence number, starting at 1
1789 :``%n``: zero-padded sequence number, starting at 1
1787 :``%r``: zero-padded changeset revision number
1790 :``%r``: zero-padded changeset revision number
1788
1791
1789 Without the -a/--text option, export will avoid generating diffs
1792 Without the -a/--text option, export will avoid generating diffs
1790 of files it detects as binary. With -a, export will generate a
1793 of files it detects as binary. With -a, export will generate a
1791 diff anyway, probably with undesirable results.
1794 diff anyway, probably with undesirable results.
1792
1795
1793 Use the -g/--git option to generate diffs in the git extended diff
1796 Use the -g/--git option to generate diffs in the git extended diff
1794 format. See :hg:`help diffs` for more information.
1797 format. See :hg:`help diffs` for more information.
1795
1798
1796 With the --switch-parent option, the diff will be against the
1799 With the --switch-parent option, the diff will be against the
1797 second parent. It can be useful to review a merge.
1800 second parent. It can be useful to review a merge.
1798
1801
1799 Returns 0 on success.
1802 Returns 0 on success.
1800 """
1803 """
1801 changesets += tuple(opts.get('rev', []))
1804 changesets += tuple(opts.get('rev', []))
1802 if not changesets:
1805 if not changesets:
1803 raise util.Abort(_("export requires at least one changeset"))
1806 raise util.Abort(_("export requires at least one changeset"))
1804 revs = cmdutil.revrange(repo, changesets)
1807 revs = cmdutil.revrange(repo, changesets)
1805 if len(revs) > 1:
1808 if len(revs) > 1:
1806 ui.note(_('exporting patches:\n'))
1809 ui.note(_('exporting patches:\n'))
1807 else:
1810 else:
1808 ui.note(_('exporting patch:\n'))
1811 ui.note(_('exporting patch:\n'))
1809 cmdutil.export(repo, revs, template=opts.get('output'),
1812 cmdutil.export(repo, revs, template=opts.get('output'),
1810 switch_parent=opts.get('switch_parent'),
1813 switch_parent=opts.get('switch_parent'),
1811 opts=patch.diffopts(ui, opts))
1814 opts=patch.diffopts(ui, opts))
1812
1815
1813 def forget(ui, repo, *pats, **opts):
1816 def forget(ui, repo, *pats, **opts):
1814 """forget the specified files on the next commit
1817 """forget the specified files on the next commit
1815
1818
1816 Mark the specified files so they will no longer be tracked
1819 Mark the specified files so they will no longer be tracked
1817 after the next commit.
1820 after the next commit.
1818
1821
1819 This only removes files from the current branch, not from the
1822 This only removes files from the current branch, not from the
1820 entire project history, and it does not delete them from the
1823 entire project history, and it does not delete them from the
1821 working directory.
1824 working directory.
1822
1825
1823 To undo a forget before the next commit, see :hg:`add`.
1826 To undo a forget before the next commit, see :hg:`add`.
1824
1827
1825 Returns 0 on success.
1828 Returns 0 on success.
1826 """
1829 """
1827
1830
1828 if not pats:
1831 if not pats:
1829 raise util.Abort(_('no files specified'))
1832 raise util.Abort(_('no files specified'))
1830
1833
1831 m = cmdutil.match(repo, pats, opts)
1834 m = cmdutil.match(repo, pats, opts)
1832 s = repo.status(match=m, clean=True)
1835 s = repo.status(match=m, clean=True)
1833 forget = sorted(s[0] + s[1] + s[3] + s[6])
1836 forget = sorted(s[0] + s[1] + s[3] + s[6])
1834 errs = 0
1837 errs = 0
1835
1838
1836 for f in m.files():
1839 for f in m.files():
1837 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1840 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1838 ui.warn(_('not removing %s: file is already untracked\n')
1841 ui.warn(_('not removing %s: file is already untracked\n')
1839 % m.rel(f))
1842 % m.rel(f))
1840 errs = 1
1843 errs = 1
1841
1844
1842 for f in forget:
1845 for f in forget:
1843 if ui.verbose or not m.exact(f):
1846 if ui.verbose or not m.exact(f):
1844 ui.status(_('removing %s\n') % m.rel(f))
1847 ui.status(_('removing %s\n') % m.rel(f))
1845
1848
1846 repo[None].remove(forget, unlink=False)
1849 repo[None].remove(forget, unlink=False)
1847 return errs
1850 return errs
1848
1851
1849 def grep(ui, repo, pattern, *pats, **opts):
1852 def grep(ui, repo, pattern, *pats, **opts):
1850 """search for a pattern in specified files and revisions
1853 """search for a pattern in specified files and revisions
1851
1854
1852 Search revisions of files for a regular expression.
1855 Search revisions of files for a regular expression.
1853
1856
1854 This command behaves differently than Unix grep. It only accepts
1857 This command behaves differently than Unix grep. It only accepts
1855 Python/Perl regexps. It searches repository history, not the
1858 Python/Perl regexps. It searches repository history, not the
1856 working directory. It always prints the revision number in which a
1859 working directory. It always prints the revision number in which a
1857 match appears.
1860 match appears.
1858
1861
1859 By default, grep only prints output for the first revision of a
1862 By default, grep only prints output for the first revision of a
1860 file in which it finds a match. To get it to print every revision
1863 file in which it finds a match. To get it to print every revision
1861 that contains a change in match status ("-" for a match that
1864 that contains a change in match status ("-" for a match that
1862 becomes a non-match, or "+" for a non-match that becomes a match),
1865 becomes a non-match, or "+" for a non-match that becomes a match),
1863 use the --all flag.
1866 use the --all flag.
1864
1867
1865 Returns 0 if a match is found, 1 otherwise.
1868 Returns 0 if a match is found, 1 otherwise.
1866 """
1869 """
1867 reflags = 0
1870 reflags = 0
1868 if opts.get('ignore_case'):
1871 if opts.get('ignore_case'):
1869 reflags |= re.I
1872 reflags |= re.I
1870 try:
1873 try:
1871 regexp = re.compile(pattern, reflags)
1874 regexp = re.compile(pattern, reflags)
1872 except re.error, inst:
1875 except re.error, inst:
1873 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1876 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1874 return 1
1877 return 1
1875 sep, eol = ':', '\n'
1878 sep, eol = ':', '\n'
1876 if opts.get('print0'):
1879 if opts.get('print0'):
1877 sep = eol = '\0'
1880 sep = eol = '\0'
1878
1881
1879 getfile = util.lrucachefunc(repo.file)
1882 getfile = util.lrucachefunc(repo.file)
1880
1883
1881 def matchlines(body):
1884 def matchlines(body):
1882 begin = 0
1885 begin = 0
1883 linenum = 0
1886 linenum = 0
1884 while True:
1887 while True:
1885 match = regexp.search(body, begin)
1888 match = regexp.search(body, begin)
1886 if not match:
1889 if not match:
1887 break
1890 break
1888 mstart, mend = match.span()
1891 mstart, mend = match.span()
1889 linenum += body.count('\n', begin, mstart) + 1
1892 linenum += body.count('\n', begin, mstart) + 1
1890 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1893 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1891 begin = body.find('\n', mend) + 1 or len(body)
1894 begin = body.find('\n', mend) + 1 or len(body)
1892 lend = begin - 1
1895 lend = begin - 1
1893 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1896 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1894
1897
1895 class linestate(object):
1898 class linestate(object):
1896 def __init__(self, line, linenum, colstart, colend):
1899 def __init__(self, line, linenum, colstart, colend):
1897 self.line = line
1900 self.line = line
1898 self.linenum = linenum
1901 self.linenum = linenum
1899 self.colstart = colstart
1902 self.colstart = colstart
1900 self.colend = colend
1903 self.colend = colend
1901
1904
1902 def __hash__(self):
1905 def __hash__(self):
1903 return hash((self.linenum, self.line))
1906 return hash((self.linenum, self.line))
1904
1907
1905 def __eq__(self, other):
1908 def __eq__(self, other):
1906 return self.line == other.line
1909 return self.line == other.line
1907
1910
1908 matches = {}
1911 matches = {}
1909 copies = {}
1912 copies = {}
1910 def grepbody(fn, rev, body):
1913 def grepbody(fn, rev, body):
1911 matches[rev].setdefault(fn, [])
1914 matches[rev].setdefault(fn, [])
1912 m = matches[rev][fn]
1915 m = matches[rev][fn]
1913 for lnum, cstart, cend, line in matchlines(body):
1916 for lnum, cstart, cend, line in matchlines(body):
1914 s = linestate(line, lnum, cstart, cend)
1917 s = linestate(line, lnum, cstart, cend)
1915 m.append(s)
1918 m.append(s)
1916
1919
1917 def difflinestates(a, b):
1920 def difflinestates(a, b):
1918 sm = difflib.SequenceMatcher(None, a, b)
1921 sm = difflib.SequenceMatcher(None, a, b)
1919 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1922 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1920 if tag == 'insert':
1923 if tag == 'insert':
1921 for i in xrange(blo, bhi):
1924 for i in xrange(blo, bhi):
1922 yield ('+', b[i])
1925 yield ('+', b[i])
1923 elif tag == 'delete':
1926 elif tag == 'delete':
1924 for i in xrange(alo, ahi):
1927 for i in xrange(alo, ahi):
1925 yield ('-', a[i])
1928 yield ('-', a[i])
1926 elif tag == 'replace':
1929 elif tag == 'replace':
1927 for i in xrange(alo, ahi):
1930 for i in xrange(alo, ahi):
1928 yield ('-', a[i])
1931 yield ('-', a[i])
1929 for i in xrange(blo, bhi):
1932 for i in xrange(blo, bhi):
1930 yield ('+', b[i])
1933 yield ('+', b[i])
1931
1934
1932 def display(fn, ctx, pstates, states):
1935 def display(fn, ctx, pstates, states):
1933 rev = ctx.rev()
1936 rev = ctx.rev()
1934 datefunc = ui.quiet and util.shortdate or util.datestr
1937 datefunc = ui.quiet and util.shortdate or util.datestr
1935 found = False
1938 found = False
1936 filerevmatches = {}
1939 filerevmatches = {}
1937 def binary():
1940 def binary():
1938 flog = getfile(fn)
1941 flog = getfile(fn)
1939 return util.binary(flog.read(ctx.filenode(fn)))
1942 return util.binary(flog.read(ctx.filenode(fn)))
1940
1943
1941 if opts.get('all'):
1944 if opts.get('all'):
1942 iter = difflinestates(pstates, states)
1945 iter = difflinestates(pstates, states)
1943 else:
1946 else:
1944 iter = [('', l) for l in states]
1947 iter = [('', l) for l in states]
1945 for change, l in iter:
1948 for change, l in iter:
1946 cols = [fn, str(rev)]
1949 cols = [fn, str(rev)]
1947 before, match, after = None, None, None
1950 before, match, after = None, None, None
1948 if opts.get('line_number'):
1951 if opts.get('line_number'):
1949 cols.append(str(l.linenum))
1952 cols.append(str(l.linenum))
1950 if opts.get('all'):
1953 if opts.get('all'):
1951 cols.append(change)
1954 cols.append(change)
1952 if opts.get('user'):
1955 if opts.get('user'):
1953 cols.append(ui.shortuser(ctx.user()))
1956 cols.append(ui.shortuser(ctx.user()))
1954 if opts.get('date'):
1957 if opts.get('date'):
1955 cols.append(datefunc(ctx.date()))
1958 cols.append(datefunc(ctx.date()))
1956 if opts.get('files_with_matches'):
1959 if opts.get('files_with_matches'):
1957 c = (fn, rev)
1960 c = (fn, rev)
1958 if c in filerevmatches:
1961 if c in filerevmatches:
1959 continue
1962 continue
1960 filerevmatches[c] = 1
1963 filerevmatches[c] = 1
1961 else:
1964 else:
1962 before = l.line[:l.colstart]
1965 before = l.line[:l.colstart]
1963 match = l.line[l.colstart:l.colend]
1966 match = l.line[l.colstart:l.colend]
1964 after = l.line[l.colend:]
1967 after = l.line[l.colend:]
1965 ui.write(sep.join(cols))
1968 ui.write(sep.join(cols))
1966 if before is not None:
1969 if before is not None:
1967 if not opts.get('text') and binary():
1970 if not opts.get('text') and binary():
1968 ui.write(sep + " Binary file matches")
1971 ui.write(sep + " Binary file matches")
1969 else:
1972 else:
1970 ui.write(sep + before)
1973 ui.write(sep + before)
1971 ui.write(match, label='grep.match')
1974 ui.write(match, label='grep.match')
1972 ui.write(after)
1975 ui.write(after)
1973 ui.write(eol)
1976 ui.write(eol)
1974 found = True
1977 found = True
1975 return found
1978 return found
1976
1979
1977 skip = {}
1980 skip = {}
1978 revfiles = {}
1981 revfiles = {}
1979 matchfn = cmdutil.match(repo, pats, opts)
1982 matchfn = cmdutil.match(repo, pats, opts)
1980 found = False
1983 found = False
1981 follow = opts.get('follow')
1984 follow = opts.get('follow')
1982
1985
1983 def prep(ctx, fns):
1986 def prep(ctx, fns):
1984 rev = ctx.rev()
1987 rev = ctx.rev()
1985 pctx = ctx.p1()
1988 pctx = ctx.p1()
1986 parent = pctx.rev()
1989 parent = pctx.rev()
1987 matches.setdefault(rev, {})
1990 matches.setdefault(rev, {})
1988 matches.setdefault(parent, {})
1991 matches.setdefault(parent, {})
1989 files = revfiles.setdefault(rev, [])
1992 files = revfiles.setdefault(rev, [])
1990 for fn in fns:
1993 for fn in fns:
1991 flog = getfile(fn)
1994 flog = getfile(fn)
1992 try:
1995 try:
1993 fnode = ctx.filenode(fn)
1996 fnode = ctx.filenode(fn)
1994 except error.LookupError:
1997 except error.LookupError:
1995 continue
1998 continue
1996
1999
1997 copied = flog.renamed(fnode)
2000 copied = flog.renamed(fnode)
1998 copy = follow and copied and copied[0]
2001 copy = follow and copied and copied[0]
1999 if copy:
2002 if copy:
2000 copies.setdefault(rev, {})[fn] = copy
2003 copies.setdefault(rev, {})[fn] = copy
2001 if fn in skip:
2004 if fn in skip:
2002 if copy:
2005 if copy:
2003 skip[copy] = True
2006 skip[copy] = True
2004 continue
2007 continue
2005 files.append(fn)
2008 files.append(fn)
2006
2009
2007 if fn not in matches[rev]:
2010 if fn not in matches[rev]:
2008 grepbody(fn, rev, flog.read(fnode))
2011 grepbody(fn, rev, flog.read(fnode))
2009
2012
2010 pfn = copy or fn
2013 pfn = copy or fn
2011 if pfn not in matches[parent]:
2014 if pfn not in matches[parent]:
2012 try:
2015 try:
2013 fnode = pctx.filenode(pfn)
2016 fnode = pctx.filenode(pfn)
2014 grepbody(pfn, parent, flog.read(fnode))
2017 grepbody(pfn, parent, flog.read(fnode))
2015 except error.LookupError:
2018 except error.LookupError:
2016 pass
2019 pass
2017
2020
2018 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2021 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2019 rev = ctx.rev()
2022 rev = ctx.rev()
2020 parent = ctx.p1().rev()
2023 parent = ctx.p1().rev()
2021 for fn in sorted(revfiles.get(rev, [])):
2024 for fn in sorted(revfiles.get(rev, [])):
2022 states = matches[rev][fn]
2025 states = matches[rev][fn]
2023 copy = copies.get(rev, {}).get(fn)
2026 copy = copies.get(rev, {}).get(fn)
2024 if fn in skip:
2027 if fn in skip:
2025 if copy:
2028 if copy:
2026 skip[copy] = True
2029 skip[copy] = True
2027 continue
2030 continue
2028 pstates = matches.get(parent, {}).get(copy or fn, [])
2031 pstates = matches.get(parent, {}).get(copy or fn, [])
2029 if pstates or states:
2032 if pstates or states:
2030 r = display(fn, ctx, pstates, states)
2033 r = display(fn, ctx, pstates, states)
2031 found = found or r
2034 found = found or r
2032 if r and not opts.get('all'):
2035 if r and not opts.get('all'):
2033 skip[fn] = True
2036 skip[fn] = True
2034 if copy:
2037 if copy:
2035 skip[copy] = True
2038 skip[copy] = True
2036 del matches[rev]
2039 del matches[rev]
2037 del revfiles[rev]
2040 del revfiles[rev]
2038
2041
2039 return not found
2042 return not found
2040
2043
2041 def heads(ui, repo, *branchrevs, **opts):
2044 def heads(ui, repo, *branchrevs, **opts):
2042 """show current repository heads or show branch heads
2045 """show current repository heads or show branch heads
2043
2046
2044 With no arguments, show all repository branch heads.
2047 With no arguments, show all repository branch heads.
2045
2048
2046 Repository "heads" are changesets with no child changesets. They are
2049 Repository "heads" are changesets with no child changesets. They are
2047 where development generally takes place and are the usual targets
2050 where development generally takes place and are the usual targets
2048 for update and merge operations. Branch heads are changesets that have
2051 for update and merge operations. Branch heads are changesets that have
2049 no child changeset on the same branch.
2052 no child changeset on the same branch.
2050
2053
2051 If one or more REVs are given, only branch heads on the branches
2054 If one or more REVs are given, only branch heads on the branches
2052 associated with the specified changesets are shown.
2055 associated with the specified changesets are shown.
2053
2056
2054 If -c/--closed is specified, also show branch heads marked closed
2057 If -c/--closed is specified, also show branch heads marked closed
2055 (see :hg:`commit --close-branch`).
2058 (see :hg:`commit --close-branch`).
2056
2059
2057 If STARTREV is specified, only those heads that are descendants of
2060 If STARTREV is specified, only those heads that are descendants of
2058 STARTREV will be displayed.
2061 STARTREV will be displayed.
2059
2062
2060 If -t/--topo is specified, named branch mechanics will be ignored and only
2063 If -t/--topo is specified, named branch mechanics will be ignored and only
2061 changesets without children will be shown.
2064 changesets without children will be shown.
2062
2065
2063 Returns 0 if matching heads are found, 1 if not.
2066 Returns 0 if matching heads are found, 1 if not.
2064 """
2067 """
2065
2068
2066 start = None
2069 start = None
2067 if 'rev' in opts:
2070 if 'rev' in opts:
2068 start = cmdutil.revsingle(repo, opts['rev'], None).node()
2071 start = cmdutil.revsingle(repo, opts['rev'], None).node()
2069
2072
2070 if opts.get('topo'):
2073 if opts.get('topo'):
2071 heads = [repo[h] for h in repo.heads(start)]
2074 heads = [repo[h] for h in repo.heads(start)]
2072 else:
2075 else:
2073 heads = []
2076 heads = []
2074 for b, ls in repo.branchmap().iteritems():
2077 for b, ls in repo.branchmap().iteritems():
2075 if start is None:
2078 if start is None:
2076 heads += [repo[h] for h in ls]
2079 heads += [repo[h] for h in ls]
2077 continue
2080 continue
2078 startrev = repo.changelog.rev(start)
2081 startrev = repo.changelog.rev(start)
2079 descendants = set(repo.changelog.descendants(startrev))
2082 descendants = set(repo.changelog.descendants(startrev))
2080 descendants.add(startrev)
2083 descendants.add(startrev)
2081 rev = repo.changelog.rev
2084 rev = repo.changelog.rev
2082 heads += [repo[h] for h in ls if rev(h) in descendants]
2085 heads += [repo[h] for h in ls if rev(h) in descendants]
2083
2086
2084 if branchrevs:
2087 if branchrevs:
2085 branches = set(repo[br].branch() for br in branchrevs)
2088 branches = set(repo[br].branch() for br in branchrevs)
2086 heads = [h for h in heads if h.branch() in branches]
2089 heads = [h for h in heads if h.branch() in branches]
2087
2090
2088 if not opts.get('closed'):
2091 if not opts.get('closed'):
2089 heads = [h for h in heads if not h.extra().get('close')]
2092 heads = [h for h in heads if not h.extra().get('close')]
2090
2093
2091 if opts.get('active') and branchrevs:
2094 if opts.get('active') and branchrevs:
2092 dagheads = repo.heads(start)
2095 dagheads = repo.heads(start)
2093 heads = [h for h in heads if h.node() in dagheads]
2096 heads = [h for h in heads if h.node() in dagheads]
2094
2097
2095 if branchrevs:
2098 if branchrevs:
2096 haveheads = set(h.branch() for h in heads)
2099 haveheads = set(h.branch() for h in heads)
2097 if branches - haveheads:
2100 if branches - haveheads:
2098 headless = ', '.join(b for b in branches - haveheads)
2101 headless = ', '.join(b for b in branches - haveheads)
2099 msg = _('no open branch heads found on branches %s')
2102 msg = _('no open branch heads found on branches %s')
2100 if opts.get('rev'):
2103 if opts.get('rev'):
2101 msg += _(' (started at %s)' % opts['rev'])
2104 msg += _(' (started at %s)' % opts['rev'])
2102 ui.warn((msg + '\n') % headless)
2105 ui.warn((msg + '\n') % headless)
2103
2106
2104 if not heads:
2107 if not heads:
2105 return 1
2108 return 1
2106
2109
2107 heads = sorted(heads, key=lambda x: -x.rev())
2110 heads = sorted(heads, key=lambda x: -x.rev())
2108 displayer = cmdutil.show_changeset(ui, repo, opts)
2111 displayer = cmdutil.show_changeset(ui, repo, opts)
2109 for ctx in heads:
2112 for ctx in heads:
2110 displayer.show(ctx)
2113 displayer.show(ctx)
2111 displayer.close()
2114 displayer.close()
2112
2115
2113 def help_(ui, name=None, with_version=False, unknowncmd=False, full=True):
2116 def help_(ui, name=None, with_version=False, unknowncmd=False, full=True):
2114 """show help for a given topic or a help overview
2117 """show help for a given topic or a help overview
2115
2118
2116 With no arguments, print a list of commands with short help messages.
2119 With no arguments, print a list of commands with short help messages.
2117
2120
2118 Given a topic, extension, or command name, print help for that
2121 Given a topic, extension, or command name, print help for that
2119 topic.
2122 topic.
2120
2123
2121 Returns 0 if successful.
2124 Returns 0 if successful.
2122 """
2125 """
2123 option_lists = []
2126 option_lists = []
2124 textwidth = min(ui.termwidth(), 80) - 2
2127 textwidth = min(ui.termwidth(), 80) - 2
2125
2128
2126 def addglobalopts(aliases):
2129 def addglobalopts(aliases):
2127 if ui.verbose:
2130 if ui.verbose:
2128 option_lists.append((_("global options:"), globalopts))
2131 option_lists.append((_("global options:"), globalopts))
2129 if name == 'shortlist':
2132 if name == 'shortlist':
2130 option_lists.append((_('use "hg help" for the full list '
2133 option_lists.append((_('use "hg help" for the full list '
2131 'of commands'), ()))
2134 'of commands'), ()))
2132 else:
2135 else:
2133 if name == 'shortlist':
2136 if name == 'shortlist':
2134 msg = _('use "hg help" for the full list of commands '
2137 msg = _('use "hg help" for the full list of commands '
2135 'or "hg -v" for details')
2138 'or "hg -v" for details')
2136 elif name and not full:
2139 elif name and not full:
2137 msg = _('use "hg help %s" to show the full help text' % name)
2140 msg = _('use "hg help %s" to show the full help text' % name)
2138 elif aliases:
2141 elif aliases:
2139 msg = _('use "hg -v help%s" to show builtin aliases and '
2142 msg = _('use "hg -v help%s" to show builtin aliases and '
2140 'global options') % (name and " " + name or "")
2143 'global options') % (name and " " + name or "")
2141 else:
2144 else:
2142 msg = _('use "hg -v help %s" to show global options') % name
2145 msg = _('use "hg -v help %s" to show global options') % name
2143 option_lists.append((msg, ()))
2146 option_lists.append((msg, ()))
2144
2147
2145 def helpcmd(name):
2148 def helpcmd(name):
2146 if with_version:
2149 if with_version:
2147 version_(ui)
2150 version_(ui)
2148 ui.write('\n')
2151 ui.write('\n')
2149
2152
2150 try:
2153 try:
2151 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
2154 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
2152 except error.AmbiguousCommand, inst:
2155 except error.AmbiguousCommand, inst:
2153 # py3k fix: except vars can't be used outside the scope of the
2156 # py3k fix: except vars can't be used outside the scope of the
2154 # except block, nor can be used inside a lambda. python issue4617
2157 # except block, nor can be used inside a lambda. python issue4617
2155 prefix = inst.args[0]
2158 prefix = inst.args[0]
2156 select = lambda c: c.lstrip('^').startswith(prefix)
2159 select = lambda c: c.lstrip('^').startswith(prefix)
2157 helplist(_('list of commands:\n\n'), select)
2160 helplist(_('list of commands:\n\n'), select)
2158 return
2161 return
2159
2162
2160 # check if it's an invalid alias and display its error if it is
2163 # check if it's an invalid alias and display its error if it is
2161 if getattr(entry[0], 'badalias', False):
2164 if getattr(entry[0], 'badalias', False):
2162 if not unknowncmd:
2165 if not unknowncmd:
2163 entry[0](ui)
2166 entry[0](ui)
2164 return
2167 return
2165
2168
2166 # synopsis
2169 # synopsis
2167 if len(entry) > 2:
2170 if len(entry) > 2:
2168 if entry[2].startswith('hg'):
2171 if entry[2].startswith('hg'):
2169 ui.write("%s\n" % entry[2])
2172 ui.write("%s\n" % entry[2])
2170 else:
2173 else:
2171 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2174 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2172 else:
2175 else:
2173 ui.write('hg %s\n' % aliases[0])
2176 ui.write('hg %s\n' % aliases[0])
2174
2177
2175 # aliases
2178 # aliases
2176 if full and not ui.quiet and len(aliases) > 1:
2179 if full and not ui.quiet and len(aliases) > 1:
2177 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2180 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2178
2181
2179 # description
2182 # description
2180 doc = gettext(entry[0].__doc__)
2183 doc = gettext(entry[0].__doc__)
2181 if not doc:
2184 if not doc:
2182 doc = _("(no help text available)")
2185 doc = _("(no help text available)")
2183 if hasattr(entry[0], 'definition'): # aliased command
2186 if hasattr(entry[0], 'definition'): # aliased command
2184 if entry[0].definition.startswith('!'): # shell alias
2187 if entry[0].definition.startswith('!'): # shell alias
2185 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2188 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2186 else:
2189 else:
2187 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
2190 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
2188 if ui.quiet or not full:
2191 if ui.quiet or not full:
2189 doc = doc.splitlines()[0]
2192 doc = doc.splitlines()[0]
2190 keep = ui.verbose and ['verbose'] or []
2193 keep = ui.verbose and ['verbose'] or []
2191 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2194 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2192 ui.write("\n%s\n" % formatted)
2195 ui.write("\n%s\n" % formatted)
2193 if pruned:
2196 if pruned:
2194 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
2197 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
2195
2198
2196 if not ui.quiet:
2199 if not ui.quiet:
2197 # options
2200 # options
2198 if entry[1]:
2201 if entry[1]:
2199 option_lists.append((_("options:\n"), entry[1]))
2202 option_lists.append((_("options:\n"), entry[1]))
2200
2203
2201 addglobalopts(False)
2204 addglobalopts(False)
2202
2205
2203 def helplist(header, select=None):
2206 def helplist(header, select=None):
2204 h = {}
2207 h = {}
2205 cmds = {}
2208 cmds = {}
2206 for c, e in table.iteritems():
2209 for c, e in table.iteritems():
2207 f = c.split("|", 1)[0]
2210 f = c.split("|", 1)[0]
2208 if select and not select(f):
2211 if select and not select(f):
2209 continue
2212 continue
2210 if (not select and name != 'shortlist' and
2213 if (not select and name != 'shortlist' and
2211 e[0].__module__ != __name__):
2214 e[0].__module__ != __name__):
2212 continue
2215 continue
2213 if name == "shortlist" and not f.startswith("^"):
2216 if name == "shortlist" and not f.startswith("^"):
2214 continue
2217 continue
2215 f = f.lstrip("^")
2218 f = f.lstrip("^")
2216 if not ui.debugflag and f.startswith("debug"):
2219 if not ui.debugflag and f.startswith("debug"):
2217 continue
2220 continue
2218 doc = e[0].__doc__
2221 doc = e[0].__doc__
2219 if doc and 'DEPRECATED' in doc and not ui.verbose:
2222 if doc and 'DEPRECATED' in doc and not ui.verbose:
2220 continue
2223 continue
2221 doc = gettext(doc)
2224 doc = gettext(doc)
2222 if not doc:
2225 if not doc:
2223 doc = _("(no help text available)")
2226 doc = _("(no help text available)")
2224 h[f] = doc.splitlines()[0].rstrip()
2227 h[f] = doc.splitlines()[0].rstrip()
2225 cmds[f] = c.lstrip("^")
2228 cmds[f] = c.lstrip("^")
2226
2229
2227 if not h:
2230 if not h:
2228 ui.status(_('no commands defined\n'))
2231 ui.status(_('no commands defined\n'))
2229 return
2232 return
2230
2233
2231 ui.status(header)
2234 ui.status(header)
2232 fns = sorted(h)
2235 fns = sorted(h)
2233 m = max(map(len, fns))
2236 m = max(map(len, fns))
2234 for f in fns:
2237 for f in fns:
2235 if ui.verbose:
2238 if ui.verbose:
2236 commands = cmds[f].replace("|",", ")
2239 commands = cmds[f].replace("|",", ")
2237 ui.write(" %s:\n %s\n"%(commands, h[f]))
2240 ui.write(" %s:\n %s\n"%(commands, h[f]))
2238 else:
2241 else:
2239 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2242 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2240 initindent=' %-*s ' % (m, f),
2243 initindent=' %-*s ' % (m, f),
2241 hangindent=' ' * (m + 4))))
2244 hangindent=' ' * (m + 4))))
2242
2245
2243 if not ui.quiet:
2246 if not ui.quiet:
2244 addglobalopts(True)
2247 addglobalopts(True)
2245
2248
2246 def helptopic(name):
2249 def helptopic(name):
2247 for names, header, doc in help.helptable:
2250 for names, header, doc in help.helptable:
2248 if name in names:
2251 if name in names:
2249 break
2252 break
2250 else:
2253 else:
2251 raise error.UnknownCommand(name)
2254 raise error.UnknownCommand(name)
2252
2255
2253 # description
2256 # description
2254 if not doc:
2257 if not doc:
2255 doc = _("(no help text available)")
2258 doc = _("(no help text available)")
2256 if hasattr(doc, '__call__'):
2259 if hasattr(doc, '__call__'):
2257 doc = doc()
2260 doc = doc()
2258
2261
2259 ui.write("%s\n\n" % header)
2262 ui.write("%s\n\n" % header)
2260 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2263 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2261
2264
2262 def helpext(name):
2265 def helpext(name):
2263 try:
2266 try:
2264 mod = extensions.find(name)
2267 mod = extensions.find(name)
2265 doc = gettext(mod.__doc__) or _('no help text available')
2268 doc = gettext(mod.__doc__) or _('no help text available')
2266 except KeyError:
2269 except KeyError:
2267 mod = None
2270 mod = None
2268 doc = extensions.disabledext(name)
2271 doc = extensions.disabledext(name)
2269 if not doc:
2272 if not doc:
2270 raise error.UnknownCommand(name)
2273 raise error.UnknownCommand(name)
2271
2274
2272 if '\n' not in doc:
2275 if '\n' not in doc:
2273 head, tail = doc, ""
2276 head, tail = doc, ""
2274 else:
2277 else:
2275 head, tail = doc.split('\n', 1)
2278 head, tail = doc.split('\n', 1)
2276 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2279 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2277 if tail:
2280 if tail:
2278 ui.write(minirst.format(tail, textwidth))
2281 ui.write(minirst.format(tail, textwidth))
2279 ui.status('\n\n')
2282 ui.status('\n\n')
2280
2283
2281 if mod:
2284 if mod:
2282 try:
2285 try:
2283 ct = mod.cmdtable
2286 ct = mod.cmdtable
2284 except AttributeError:
2287 except AttributeError:
2285 ct = {}
2288 ct = {}
2286 modcmds = set([c.split('|', 1)[0] for c in ct])
2289 modcmds = set([c.split('|', 1)[0] for c in ct])
2287 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2290 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2288 else:
2291 else:
2289 ui.write(_('use "hg help extensions" for information on enabling '
2292 ui.write(_('use "hg help extensions" for information on enabling '
2290 'extensions\n'))
2293 'extensions\n'))
2291
2294
2292 def helpextcmd(name):
2295 def helpextcmd(name):
2293 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2296 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2294 doc = gettext(mod.__doc__).splitlines()[0]
2297 doc = gettext(mod.__doc__).splitlines()[0]
2295
2298
2296 msg = help.listexts(_("'%s' is provided by the following "
2299 msg = help.listexts(_("'%s' is provided by the following "
2297 "extension:") % cmd, {ext: doc}, len(ext),
2300 "extension:") % cmd, {ext: doc}, len(ext),
2298 indent=4)
2301 indent=4)
2299 ui.write(minirst.format(msg, textwidth))
2302 ui.write(minirst.format(msg, textwidth))
2300 ui.write('\n\n')
2303 ui.write('\n\n')
2301 ui.write(_('use "hg help extensions" for information on enabling '
2304 ui.write(_('use "hg help extensions" for information on enabling '
2302 'extensions\n'))
2305 'extensions\n'))
2303
2306
2304 help.addtopichook('revsets', revset.makedoc)
2307 help.addtopichook('revsets', revset.makedoc)
2305 help.addtopichook('templates', templatekw.makedoc)
2308 help.addtopichook('templates', templatekw.makedoc)
2306 help.addtopichook('templates', templatefilters.makedoc)
2309 help.addtopichook('templates', templatefilters.makedoc)
2307
2310
2308 if name and name != 'shortlist':
2311 if name and name != 'shortlist':
2309 i = None
2312 i = None
2310 if unknowncmd:
2313 if unknowncmd:
2311 queries = (helpextcmd,)
2314 queries = (helpextcmd,)
2312 else:
2315 else:
2313 queries = (helptopic, helpcmd, helpext, helpextcmd)
2316 queries = (helptopic, helpcmd, helpext, helpextcmd)
2314 for f in queries:
2317 for f in queries:
2315 try:
2318 try:
2316 f(name)
2319 f(name)
2317 i = None
2320 i = None
2318 break
2321 break
2319 except error.UnknownCommand, inst:
2322 except error.UnknownCommand, inst:
2320 i = inst
2323 i = inst
2321 if i:
2324 if i:
2322 raise i
2325 raise i
2323
2326
2324 else:
2327 else:
2325 # program name
2328 # program name
2326 if ui.verbose or with_version:
2329 if ui.verbose or with_version:
2327 version_(ui)
2330 version_(ui)
2328 else:
2331 else:
2329 ui.status(_("Mercurial Distributed SCM\n"))
2332 ui.status(_("Mercurial Distributed SCM\n"))
2330 ui.status('\n')
2333 ui.status('\n')
2331
2334
2332 # list of commands
2335 # list of commands
2333 if name == "shortlist":
2336 if name == "shortlist":
2334 header = _('basic commands:\n\n')
2337 header = _('basic commands:\n\n')
2335 else:
2338 else:
2336 header = _('list of commands:\n\n')
2339 header = _('list of commands:\n\n')
2337
2340
2338 helplist(header)
2341 helplist(header)
2339 if name != 'shortlist':
2342 if name != 'shortlist':
2340 exts, maxlength = extensions.enabled()
2343 exts, maxlength = extensions.enabled()
2341 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2344 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2342 if text:
2345 if text:
2343 ui.write("\n%s\n" % minirst.format(text, textwidth))
2346 ui.write("\n%s\n" % minirst.format(text, textwidth))
2344
2347
2345 # list all option lists
2348 # list all option lists
2346 opt_output = []
2349 opt_output = []
2347 multioccur = False
2350 multioccur = False
2348 for title, options in option_lists:
2351 for title, options in option_lists:
2349 opt_output.append(("\n%s" % title, None))
2352 opt_output.append(("\n%s" % title, None))
2350 for option in options:
2353 for option in options:
2351 if len(option) == 5:
2354 if len(option) == 5:
2352 shortopt, longopt, default, desc, optlabel = option
2355 shortopt, longopt, default, desc, optlabel = option
2353 else:
2356 else:
2354 shortopt, longopt, default, desc = option
2357 shortopt, longopt, default, desc = option
2355 optlabel = _("VALUE") # default label
2358 optlabel = _("VALUE") # default label
2356
2359
2357 if _("DEPRECATED") in desc and not ui.verbose:
2360 if _("DEPRECATED") in desc and not ui.verbose:
2358 continue
2361 continue
2359 if isinstance(default, list):
2362 if isinstance(default, list):
2360 numqualifier = " %s [+]" % optlabel
2363 numqualifier = " %s [+]" % optlabel
2361 multioccur = True
2364 multioccur = True
2362 elif (default is not None) and not isinstance(default, bool):
2365 elif (default is not None) and not isinstance(default, bool):
2363 numqualifier = " %s" % optlabel
2366 numqualifier = " %s" % optlabel
2364 else:
2367 else:
2365 numqualifier = ""
2368 numqualifier = ""
2366 opt_output.append(("%2s%s" %
2369 opt_output.append(("%2s%s" %
2367 (shortopt and "-%s" % shortopt,
2370 (shortopt and "-%s" % shortopt,
2368 longopt and " --%s%s" %
2371 longopt and " --%s%s" %
2369 (longopt, numqualifier)),
2372 (longopt, numqualifier)),
2370 "%s%s" % (desc,
2373 "%s%s" % (desc,
2371 default
2374 default
2372 and _(" (default: %s)") % default
2375 and _(" (default: %s)") % default
2373 or "")))
2376 or "")))
2374 if multioccur:
2377 if multioccur:
2375 msg = _("\n[+] marked option can be specified multiple times")
2378 msg = _("\n[+] marked option can be specified multiple times")
2376 if ui.verbose and name != 'shortlist':
2379 if ui.verbose and name != 'shortlist':
2377 opt_output.append((msg, None))
2380 opt_output.append((msg, None))
2378 else:
2381 else:
2379 opt_output.insert(-1, (msg, None))
2382 opt_output.insert(-1, (msg, None))
2380
2383
2381 if not name:
2384 if not name:
2382 ui.write(_("\nadditional help topics:\n\n"))
2385 ui.write(_("\nadditional help topics:\n\n"))
2383 topics = []
2386 topics = []
2384 for names, header, doc in help.helptable:
2387 for names, header, doc in help.helptable:
2385 topics.append((sorted(names, key=len, reverse=True)[0], header))
2388 topics.append((sorted(names, key=len, reverse=True)[0], header))
2386 topics_len = max([len(s[0]) for s in topics])
2389 topics_len = max([len(s[0]) for s in topics])
2387 for t, desc in topics:
2390 for t, desc in topics:
2388 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2391 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2389
2392
2390 if opt_output:
2393 if opt_output:
2391 colwidth = encoding.colwidth
2394 colwidth = encoding.colwidth
2392 # normalize: (opt or message, desc or None, width of opt)
2395 # normalize: (opt or message, desc or None, width of opt)
2393 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2396 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2394 for opt, desc in opt_output]
2397 for opt, desc in opt_output]
2395 hanging = max([e[2] for e in entries])
2398 hanging = max([e[2] for e in entries])
2396 for opt, desc, width in entries:
2399 for opt, desc, width in entries:
2397 if desc:
2400 if desc:
2398 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2401 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2399 hangindent = ' ' * (hanging + 3)
2402 hangindent = ' ' * (hanging + 3)
2400 ui.write('%s\n' % (util.wrap(desc, textwidth,
2403 ui.write('%s\n' % (util.wrap(desc, textwidth,
2401 initindent=initindent,
2404 initindent=initindent,
2402 hangindent=hangindent)))
2405 hangindent=hangindent)))
2403 else:
2406 else:
2404 ui.write("%s\n" % opt)
2407 ui.write("%s\n" % opt)
2405
2408
2406 def identify(ui, repo, source=None, rev=None,
2409 def identify(ui, repo, source=None, rev=None,
2407 num=None, id=None, branch=None, tags=None, bookmarks=None):
2410 num=None, id=None, branch=None, tags=None, bookmarks=None):
2408 """identify the working copy or specified revision
2411 """identify the working copy or specified revision
2409
2412
2410 Print a summary identifying the repository state at REV using one or
2413 Print a summary identifying the repository state at REV using one or
2411 two parent hash identifiers, followed by a "+" if the working
2414 two parent hash identifiers, followed by a "+" if the working
2412 directory has uncommitted changes, the branch name (if not default),
2415 directory has uncommitted changes, the branch name (if not default),
2413 a list of tags, and a list of bookmarks.
2416 a list of tags, and a list of bookmarks.
2414
2417
2415 When REV is not given, print a summary of the current state of the
2418 When REV is not given, print a summary of the current state of the
2416 repository.
2419 repository.
2417
2420
2418 Specifying a path to a repository root or Mercurial bundle will
2421 Specifying a path to a repository root or Mercurial bundle will
2419 cause lookup to operate on that repository/bundle.
2422 cause lookup to operate on that repository/bundle.
2420
2423
2421 Returns 0 if successful.
2424 Returns 0 if successful.
2422 """
2425 """
2423
2426
2424 if not repo and not source:
2427 if not repo and not source:
2425 raise util.Abort(_("there is no Mercurial repository here "
2428 raise util.Abort(_("there is no Mercurial repository here "
2426 "(.hg not found)"))
2429 "(.hg not found)"))
2427
2430
2428 hexfunc = ui.debugflag and hex or short
2431 hexfunc = ui.debugflag and hex or short
2429 default = not (num or id or branch or tags or bookmarks)
2432 default = not (num or id or branch or tags or bookmarks)
2430 output = []
2433 output = []
2431 revs = []
2434 revs = []
2432
2435
2433 if source:
2436 if source:
2434 source, branches = hg.parseurl(ui.expandpath(source))
2437 source, branches = hg.parseurl(ui.expandpath(source))
2435 repo = hg.repository(ui, source)
2438 repo = hg.repository(ui, source)
2436 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2439 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2437
2440
2438 if not repo.local():
2441 if not repo.local():
2439 if num or branch or tags:
2442 if num or branch or tags:
2440 raise util.Abort(
2443 raise util.Abort(
2441 _("can't query remote revision number, branch, or tags"))
2444 _("can't query remote revision number, branch, or tags"))
2442 if not rev and revs:
2445 if not rev and revs:
2443 rev = revs[0]
2446 rev = revs[0]
2444 if not rev:
2447 if not rev:
2445 rev = "tip"
2448 rev = "tip"
2446
2449
2447 remoterev = repo.lookup(rev)
2450 remoterev = repo.lookup(rev)
2448 if default or id:
2451 if default or id:
2449 output = [hexfunc(remoterev)]
2452 output = [hexfunc(remoterev)]
2450
2453
2451 def getbms():
2454 def getbms():
2452 bms = []
2455 bms = []
2453
2456
2454 if 'bookmarks' in repo.listkeys('namespaces'):
2457 if 'bookmarks' in repo.listkeys('namespaces'):
2455 hexremoterev = hex(remoterev)
2458 hexremoterev = hex(remoterev)
2456 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
2459 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
2457 if bmr == hexremoterev]
2460 if bmr == hexremoterev]
2458
2461
2459 return bms
2462 return bms
2460
2463
2461 if bookmarks:
2464 if bookmarks:
2462 output.extend(getbms())
2465 output.extend(getbms())
2463 elif default and not ui.quiet:
2466 elif default and not ui.quiet:
2464 # multiple bookmarks for a single parent separated by '/'
2467 # multiple bookmarks for a single parent separated by '/'
2465 bm = '/'.join(getbms())
2468 bm = '/'.join(getbms())
2466 if bm:
2469 if bm:
2467 output.append(bm)
2470 output.append(bm)
2468 else:
2471 else:
2469 if not rev:
2472 if not rev:
2470 ctx = repo[None]
2473 ctx = repo[None]
2471 parents = ctx.parents()
2474 parents = ctx.parents()
2472 changed = ""
2475 changed = ""
2473 if default or id or num:
2476 if default or id or num:
2474 changed = util.any(repo.status()) and "+" or ""
2477 changed = util.any(repo.status()) and "+" or ""
2475 if default or id:
2478 if default or id:
2476 output = ["%s%s" %
2479 output = ["%s%s" %
2477 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
2480 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
2478 if num:
2481 if num:
2479 output.append("%s%s" %
2482 output.append("%s%s" %
2480 ('+'.join([str(p.rev()) for p in parents]), changed))
2483 ('+'.join([str(p.rev()) for p in parents]), changed))
2481 else:
2484 else:
2482 ctx = cmdutil.revsingle(repo, rev)
2485 ctx = cmdutil.revsingle(repo, rev)
2483 if default or id:
2486 if default or id:
2484 output = [hexfunc(ctx.node())]
2487 output = [hexfunc(ctx.node())]
2485 if num:
2488 if num:
2486 output.append(str(ctx.rev()))
2489 output.append(str(ctx.rev()))
2487
2490
2488 if default and not ui.quiet:
2491 if default and not ui.quiet:
2489 b = ctx.branch()
2492 b = ctx.branch()
2490 if b != 'default':
2493 if b != 'default':
2491 output.append("(%s)" % b)
2494 output.append("(%s)" % b)
2492
2495
2493 # multiple tags for a single parent separated by '/'
2496 # multiple tags for a single parent separated by '/'
2494 t = '/'.join(ctx.tags())
2497 t = '/'.join(ctx.tags())
2495 if t:
2498 if t:
2496 output.append(t)
2499 output.append(t)
2497
2500
2498 # multiple bookmarks for a single parent separated by '/'
2501 # multiple bookmarks for a single parent separated by '/'
2499 bm = '/'.join(ctx.bookmarks())
2502 bm = '/'.join(ctx.bookmarks())
2500 if bm:
2503 if bm:
2501 output.append(bm)
2504 output.append(bm)
2502 else:
2505 else:
2503 if branch:
2506 if branch:
2504 output.append(ctx.branch())
2507 output.append(ctx.branch())
2505
2508
2506 if tags:
2509 if tags:
2507 output.extend(ctx.tags())
2510 output.extend(ctx.tags())
2508
2511
2509 if bookmarks:
2512 if bookmarks:
2510 output.extend(ctx.bookmarks())
2513 output.extend(ctx.bookmarks())
2511
2514
2512 ui.write("%s\n" % ' '.join(output))
2515 ui.write("%s\n" % ' '.join(output))
2513
2516
2514 def import_(ui, repo, patch1, *patches, **opts):
2517 def import_(ui, repo, patch1, *patches, **opts):
2515 """import an ordered set of patches
2518 """import an ordered set of patches
2516
2519
2517 Import a list of patches and commit them individually (unless
2520 Import a list of patches and commit them individually (unless
2518 --no-commit is specified).
2521 --no-commit is specified).
2519
2522
2520 If there are outstanding changes in the working directory, import
2523 If there are outstanding changes in the working directory, import
2521 will abort unless given the -f/--force flag.
2524 will abort unless given the -f/--force flag.
2522
2525
2523 You can import a patch straight from a mail message. Even patches
2526 You can import a patch straight from a mail message. Even patches
2524 as attachments work (to use the body part, it must have type
2527 as attachments work (to use the body part, it must have type
2525 text/plain or text/x-patch). From and Subject headers of email
2528 text/plain or text/x-patch). From and Subject headers of email
2526 message are used as default committer and commit message. All
2529 message are used as default committer and commit message. All
2527 text/plain body parts before first diff are added to commit
2530 text/plain body parts before first diff are added to commit
2528 message.
2531 message.
2529
2532
2530 If the imported patch was generated by :hg:`export`, user and
2533 If the imported patch was generated by :hg:`export`, user and
2531 description from patch override values from message headers and
2534 description from patch override values from message headers and
2532 body. Values given on command line with -m/--message and -u/--user
2535 body. Values given on command line with -m/--message and -u/--user
2533 override these.
2536 override these.
2534
2537
2535 If --exact is specified, import will set the working directory to
2538 If --exact is specified, import will set the working directory to
2536 the parent of each patch before applying it, and will abort if the
2539 the parent of each patch before applying it, and will abort if the
2537 resulting changeset has a different ID than the one recorded in
2540 resulting changeset has a different ID than the one recorded in
2538 the patch. This may happen due to character set problems or other
2541 the patch. This may happen due to character set problems or other
2539 deficiencies in the text patch format.
2542 deficiencies in the text patch format.
2540
2543
2541 With -s/--similarity, hg will attempt to discover renames and
2544 With -s/--similarity, hg will attempt to discover renames and
2542 copies in the patch in the same way as 'addremove'.
2545 copies in the patch in the same way as 'addremove'.
2543
2546
2544 To read a patch from standard input, use "-" as the patch name. If
2547 To read a patch from standard input, use "-" as the patch name. If
2545 a URL is specified, the patch will be downloaded from it.
2548 a URL is specified, the patch will be downloaded from it.
2546 See :hg:`help dates` for a list of formats valid for -d/--date.
2549 See :hg:`help dates` for a list of formats valid for -d/--date.
2547
2550
2548 Returns 0 on success.
2551 Returns 0 on success.
2549 """
2552 """
2550 patches = (patch1,) + patches
2553 patches = (patch1,) + patches
2551
2554
2552 date = opts.get('date')
2555 date = opts.get('date')
2553 if date:
2556 if date:
2554 opts['date'] = util.parsedate(date)
2557 opts['date'] = util.parsedate(date)
2555
2558
2556 try:
2559 try:
2557 sim = float(opts.get('similarity') or 0)
2560 sim = float(opts.get('similarity') or 0)
2558 except ValueError:
2561 except ValueError:
2559 raise util.Abort(_('similarity must be a number'))
2562 raise util.Abort(_('similarity must be a number'))
2560 if sim < 0 or sim > 100:
2563 if sim < 0 or sim > 100:
2561 raise util.Abort(_('similarity must be between 0 and 100'))
2564 raise util.Abort(_('similarity must be between 0 and 100'))
2562
2565
2563 if opts.get('exact') or not opts.get('force'):
2566 if opts.get('exact') or not opts.get('force'):
2564 cmdutil.bail_if_changed(repo)
2567 cmdutil.bail_if_changed(repo)
2565
2568
2566 d = opts["base"]
2569 d = opts["base"]
2567 strip = opts["strip"]
2570 strip = opts["strip"]
2568 wlock = lock = None
2571 wlock = lock = None
2569 msgs = []
2572 msgs = []
2570
2573
2571 def tryone(ui, hunk):
2574 def tryone(ui, hunk):
2572 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2575 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2573 patch.extract(ui, hunk)
2576 patch.extract(ui, hunk)
2574
2577
2575 if not tmpname:
2578 if not tmpname:
2576 return None
2579 return None
2577 commitid = _('to working directory')
2580 commitid = _('to working directory')
2578
2581
2579 try:
2582 try:
2580 cmdline_message = cmdutil.logmessage(opts)
2583 cmdline_message = cmdutil.logmessage(opts)
2581 if cmdline_message:
2584 if cmdline_message:
2582 # pickup the cmdline msg
2585 # pickup the cmdline msg
2583 message = cmdline_message
2586 message = cmdline_message
2584 elif message:
2587 elif message:
2585 # pickup the patch msg
2588 # pickup the patch msg
2586 message = message.strip()
2589 message = message.strip()
2587 else:
2590 else:
2588 # launch the editor
2591 # launch the editor
2589 message = None
2592 message = None
2590 ui.debug('message:\n%s\n' % message)
2593 ui.debug('message:\n%s\n' % message)
2591
2594
2592 wp = repo.parents()
2595 wp = repo.parents()
2593 if opts.get('exact'):
2596 if opts.get('exact'):
2594 if not nodeid or not p1:
2597 if not nodeid or not p1:
2595 raise util.Abort(_('not a Mercurial patch'))
2598 raise util.Abort(_('not a Mercurial patch'))
2596 p1 = repo.lookup(p1)
2599 p1 = repo.lookup(p1)
2597 p2 = repo.lookup(p2 or hex(nullid))
2600 p2 = repo.lookup(p2 or hex(nullid))
2598
2601
2599 if p1 != wp[0].node():
2602 if p1 != wp[0].node():
2600 hg.clean(repo, p1)
2603 hg.clean(repo, p1)
2601 repo.dirstate.setparents(p1, p2)
2604 repo.dirstate.setparents(p1, p2)
2602 elif p2:
2605 elif p2:
2603 try:
2606 try:
2604 p1 = repo.lookup(p1)
2607 p1 = repo.lookup(p1)
2605 p2 = repo.lookup(p2)
2608 p2 = repo.lookup(p2)
2606 if p1 == wp[0].node():
2609 if p1 == wp[0].node():
2607 repo.dirstate.setparents(p1, p2)
2610 repo.dirstate.setparents(p1, p2)
2608 except error.RepoError:
2611 except error.RepoError:
2609 pass
2612 pass
2610 if opts.get('exact') or opts.get('import_branch'):
2613 if opts.get('exact') or opts.get('import_branch'):
2611 repo.dirstate.setbranch(branch or 'default')
2614 repo.dirstate.setbranch(branch or 'default')
2612
2615
2613 files = {}
2616 files = {}
2614 try:
2617 try:
2615 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2618 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2616 files=files, eolmode=None)
2619 files=files, eolmode=None)
2617 finally:
2620 finally:
2618 files = cmdutil.updatedir(ui, repo, files,
2621 files = cmdutil.updatedir(ui, repo, files,
2619 similarity=sim / 100.0)
2622 similarity=sim / 100.0)
2620 if opts.get('no_commit'):
2623 if opts.get('no_commit'):
2621 if message:
2624 if message:
2622 msgs.append(message)
2625 msgs.append(message)
2623 else:
2626 else:
2624 if opts.get('exact'):
2627 if opts.get('exact'):
2625 m = None
2628 m = None
2626 else:
2629 else:
2627 m = cmdutil.matchfiles(repo, files or [])
2630 m = cmdutil.matchfiles(repo, files or [])
2628 n = repo.commit(message, opts.get('user') or user,
2631 n = repo.commit(message, opts.get('user') or user,
2629 opts.get('date') or date, match=m,
2632 opts.get('date') or date, match=m,
2630 editor=cmdutil.commiteditor)
2633 editor=cmdutil.commiteditor)
2631 if opts.get('exact'):
2634 if opts.get('exact'):
2632 if hex(n) != nodeid:
2635 if hex(n) != nodeid:
2633 repo.rollback()
2636 repo.rollback()
2634 raise util.Abort(_('patch is damaged'
2637 raise util.Abort(_('patch is damaged'
2635 ' or loses information'))
2638 ' or loses information'))
2636 # Force a dirstate write so that the next transaction
2639 # Force a dirstate write so that the next transaction
2637 # backups an up-do-date file.
2640 # backups an up-do-date file.
2638 repo.dirstate.write()
2641 repo.dirstate.write()
2639 if n:
2642 if n:
2640 commitid = short(n)
2643 commitid = short(n)
2641
2644
2642 return commitid
2645 return commitid
2643 finally:
2646 finally:
2644 os.unlink(tmpname)
2647 os.unlink(tmpname)
2645
2648
2646 try:
2649 try:
2647 wlock = repo.wlock()
2650 wlock = repo.wlock()
2648 lock = repo.lock()
2651 lock = repo.lock()
2649 lastcommit = None
2652 lastcommit = None
2650 for p in patches:
2653 for p in patches:
2651 pf = os.path.join(d, p)
2654 pf = os.path.join(d, p)
2652
2655
2653 if pf == '-':
2656 if pf == '-':
2654 ui.status(_("applying patch from stdin\n"))
2657 ui.status(_("applying patch from stdin\n"))
2655 pf = sys.stdin
2658 pf = sys.stdin
2656 else:
2659 else:
2657 ui.status(_("applying %s\n") % p)
2660 ui.status(_("applying %s\n") % p)
2658 pf = url.open(ui, pf)
2661 pf = url.open(ui, pf)
2659
2662
2660 haspatch = False
2663 haspatch = False
2661 for hunk in patch.split(pf):
2664 for hunk in patch.split(pf):
2662 commitid = tryone(ui, hunk)
2665 commitid = tryone(ui, hunk)
2663 if commitid:
2666 if commitid:
2664 haspatch = True
2667 haspatch = True
2665 if lastcommit:
2668 if lastcommit:
2666 ui.status(_('applied %s\n') % lastcommit)
2669 ui.status(_('applied %s\n') % lastcommit)
2667 lastcommit = commitid
2670 lastcommit = commitid
2668
2671
2669 if not haspatch:
2672 if not haspatch:
2670 raise util.Abort(_('no diffs found'))
2673 raise util.Abort(_('no diffs found'))
2671
2674
2672 if msgs:
2675 if msgs:
2673 repo.opener.write('last-message.txt', '\n* * *\n'.join(msgs))
2676 repo.opener.write('last-message.txt', '\n* * *\n'.join(msgs))
2674 finally:
2677 finally:
2675 release(lock, wlock)
2678 release(lock, wlock)
2676
2679
2677 def incoming(ui, repo, source="default", **opts):
2680 def incoming(ui, repo, source="default", **opts):
2678 """show new changesets found in source
2681 """show new changesets found in source
2679
2682
2680 Show new changesets found in the specified path/URL or the default
2683 Show new changesets found in the specified path/URL or the default
2681 pull location. These are the changesets that would have been pulled
2684 pull location. These are the changesets that would have been pulled
2682 if a pull at the time you issued this command.
2685 if a pull at the time you issued this command.
2683
2686
2684 For remote repository, using --bundle avoids downloading the
2687 For remote repository, using --bundle avoids downloading the
2685 changesets twice if the incoming is followed by a pull.
2688 changesets twice if the incoming is followed by a pull.
2686
2689
2687 See pull for valid source format details.
2690 See pull for valid source format details.
2688
2691
2689 Returns 0 if there are incoming changes, 1 otherwise.
2692 Returns 0 if there are incoming changes, 1 otherwise.
2690 """
2693 """
2691 if opts.get('bundle') and opts.get('subrepos'):
2694 if opts.get('bundle') and opts.get('subrepos'):
2692 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2695 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2693
2696
2694 if opts.get('bookmarks'):
2697 if opts.get('bookmarks'):
2695 source, branches = hg.parseurl(ui.expandpath(source),
2698 source, branches = hg.parseurl(ui.expandpath(source),
2696 opts.get('branch'))
2699 opts.get('branch'))
2697 other = hg.repository(hg.remoteui(repo, opts), source)
2700 other = hg.repository(hg.remoteui(repo, opts), source)
2698 if 'bookmarks' not in other.listkeys('namespaces'):
2701 if 'bookmarks' not in other.listkeys('namespaces'):
2699 ui.warn(_("remote doesn't support bookmarks\n"))
2702 ui.warn(_("remote doesn't support bookmarks\n"))
2700 return 0
2703 return 0
2701 ui.status(_('comparing with %s\n') % util.hidepassword(source))
2704 ui.status(_('comparing with %s\n') % util.hidepassword(source))
2702 return bookmarks.diff(ui, repo, other)
2705 return bookmarks.diff(ui, repo, other)
2703
2706
2704 ret = hg.incoming(ui, repo, source, opts)
2707 ret = hg.incoming(ui, repo, source, opts)
2705 return ret
2708 return ret
2706
2709
2707 def init(ui, dest=".", **opts):
2710 def init(ui, dest=".", **opts):
2708 """create a new repository in the given directory
2711 """create a new repository in the given directory
2709
2712
2710 Initialize a new repository in the given directory. If the given
2713 Initialize a new repository in the given directory. If the given
2711 directory does not exist, it will be created.
2714 directory does not exist, it will be created.
2712
2715
2713 If no directory is given, the current directory is used.
2716 If no directory is given, the current directory is used.
2714
2717
2715 It is possible to specify an ``ssh://`` URL as the destination.
2718 It is possible to specify an ``ssh://`` URL as the destination.
2716 See :hg:`help urls` for more information.
2719 See :hg:`help urls` for more information.
2717
2720
2718 Returns 0 on success.
2721 Returns 0 on success.
2719 """
2722 """
2720 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2723 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2721
2724
2722 def locate(ui, repo, *pats, **opts):
2725 def locate(ui, repo, *pats, **opts):
2723 """locate files matching specific patterns
2726 """locate files matching specific patterns
2724
2727
2725 Print files under Mercurial control in the working directory whose
2728 Print files under Mercurial control in the working directory whose
2726 names match the given patterns.
2729 names match the given patterns.
2727
2730
2728 By default, this command searches all directories in the working
2731 By default, this command searches all directories in the working
2729 directory. To search just the current directory and its
2732 directory. To search just the current directory and its
2730 subdirectories, use "--include .".
2733 subdirectories, use "--include .".
2731
2734
2732 If no patterns are given to match, this command prints the names
2735 If no patterns are given to match, this command prints the names
2733 of all files under Mercurial control in the working directory.
2736 of all files under Mercurial control in the working directory.
2734
2737
2735 If you want to feed the output of this command into the "xargs"
2738 If you want to feed the output of this command into the "xargs"
2736 command, use the -0 option to both this command and "xargs". This
2739 command, use the -0 option to both this command and "xargs". This
2737 will avoid the problem of "xargs" treating single filenames that
2740 will avoid the problem of "xargs" treating single filenames that
2738 contain whitespace as multiple filenames.
2741 contain whitespace as multiple filenames.
2739
2742
2740 Returns 0 if a match is found, 1 otherwise.
2743 Returns 0 if a match is found, 1 otherwise.
2741 """
2744 """
2742 end = opts.get('print0') and '\0' or '\n'
2745 end = opts.get('print0') and '\0' or '\n'
2743 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2746 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2744
2747
2745 ret = 1
2748 ret = 1
2746 m = cmdutil.match(repo, pats, opts, default='relglob')
2749 m = cmdutil.match(repo, pats, opts, default='relglob')
2747 m.bad = lambda x, y: False
2750 m.bad = lambda x, y: False
2748 for abs in repo[rev].walk(m):
2751 for abs in repo[rev].walk(m):
2749 if not rev and abs not in repo.dirstate:
2752 if not rev and abs not in repo.dirstate:
2750 continue
2753 continue
2751 if opts.get('fullpath'):
2754 if opts.get('fullpath'):
2752 ui.write(repo.wjoin(abs), end)
2755 ui.write(repo.wjoin(abs), end)
2753 else:
2756 else:
2754 ui.write(((pats and m.rel(abs)) or abs), end)
2757 ui.write(((pats and m.rel(abs)) or abs), end)
2755 ret = 0
2758 ret = 0
2756
2759
2757 return ret
2760 return ret
2758
2761
2759 def log(ui, repo, *pats, **opts):
2762 def log(ui, repo, *pats, **opts):
2760 """show revision history of entire repository or files
2763 """show revision history of entire repository or files
2761
2764
2762 Print the revision history of the specified files or the entire
2765 Print the revision history of the specified files or the entire
2763 project.
2766 project.
2764
2767
2765 File history is shown without following rename or copy history of
2768 File history is shown without following rename or copy history of
2766 files. Use -f/--follow with a filename to follow history across
2769 files. Use -f/--follow with a filename to follow history across
2767 renames and copies. --follow without a filename will only show
2770 renames and copies. --follow without a filename will only show
2768 ancestors or descendants of the starting revision. --follow-first
2771 ancestors or descendants of the starting revision. --follow-first
2769 only follows the first parent of merge revisions.
2772 only follows the first parent of merge revisions.
2770
2773
2771 If no revision range is specified, the default is ``tip:0`` unless
2774 If no revision range is specified, the default is ``tip:0`` unless
2772 --follow is set, in which case the working directory parent is
2775 --follow is set, in which case the working directory parent is
2773 used as the starting revision. You can specify a revision set for
2776 used as the starting revision. You can specify a revision set for
2774 log, see :hg:`help revsets` for more information.
2777 log, see :hg:`help revsets` for more information.
2775
2778
2776 See :hg:`help dates` for a list of formats valid for -d/--date.
2779 See :hg:`help dates` for a list of formats valid for -d/--date.
2777
2780
2778 By default this command prints revision number and changeset id,
2781 By default this command prints revision number and changeset id,
2779 tags, non-trivial parents, user, date and time, and a summary for
2782 tags, non-trivial parents, user, date and time, and a summary for
2780 each commit. When the -v/--verbose switch is used, the list of
2783 each commit. When the -v/--verbose switch is used, the list of
2781 changed files and full commit message are shown.
2784 changed files and full commit message are shown.
2782
2785
2783 .. note::
2786 .. note::
2784 log -p/--patch may generate unexpected diff output for merge
2787 log -p/--patch may generate unexpected diff output for merge
2785 changesets, as it will only compare the merge changeset against
2788 changesets, as it will only compare the merge changeset against
2786 its first parent. Also, only files different from BOTH parents
2789 its first parent. Also, only files different from BOTH parents
2787 will appear in files:.
2790 will appear in files:.
2788
2791
2789 Returns 0 on success.
2792 Returns 0 on success.
2790 """
2793 """
2791
2794
2792 matchfn = cmdutil.match(repo, pats, opts)
2795 matchfn = cmdutil.match(repo, pats, opts)
2793 limit = cmdutil.loglimit(opts)
2796 limit = cmdutil.loglimit(opts)
2794 count = 0
2797 count = 0
2795
2798
2796 endrev = None
2799 endrev = None
2797 if opts.get('copies') and opts.get('rev'):
2800 if opts.get('copies') and opts.get('rev'):
2798 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2801 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2799
2802
2800 df = False
2803 df = False
2801 if opts["date"]:
2804 if opts["date"]:
2802 df = util.matchdate(opts["date"])
2805 df = util.matchdate(opts["date"])
2803
2806
2804 branches = opts.get('branch', []) + opts.get('only_branch', [])
2807 branches = opts.get('branch', []) + opts.get('only_branch', [])
2805 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2808 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2806
2809
2807 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2810 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2808 def prep(ctx, fns):
2811 def prep(ctx, fns):
2809 rev = ctx.rev()
2812 rev = ctx.rev()
2810 parents = [p for p in repo.changelog.parentrevs(rev)
2813 parents = [p for p in repo.changelog.parentrevs(rev)
2811 if p != nullrev]
2814 if p != nullrev]
2812 if opts.get('no_merges') and len(parents) == 2:
2815 if opts.get('no_merges') and len(parents) == 2:
2813 return
2816 return
2814 if opts.get('only_merges') and len(parents) != 2:
2817 if opts.get('only_merges') and len(parents) != 2:
2815 return
2818 return
2816 if opts.get('branch') and ctx.branch() not in opts['branch']:
2819 if opts.get('branch') and ctx.branch() not in opts['branch']:
2817 return
2820 return
2818 if df and not df(ctx.date()[0]):
2821 if df and not df(ctx.date()[0]):
2819 return
2822 return
2820 if opts['user'] and not [k for k in opts['user']
2823 if opts['user'] and not [k for k in opts['user']
2821 if k.lower() in ctx.user().lower()]:
2824 if k.lower() in ctx.user().lower()]:
2822 return
2825 return
2823 if opts.get('keyword'):
2826 if opts.get('keyword'):
2824 for k in [kw.lower() for kw in opts['keyword']]:
2827 for k in [kw.lower() for kw in opts['keyword']]:
2825 if (k in ctx.user().lower() or
2828 if (k in ctx.user().lower() or
2826 k in ctx.description().lower() or
2829 k in ctx.description().lower() or
2827 k in " ".join(ctx.files()).lower()):
2830 k in " ".join(ctx.files()).lower()):
2828 break
2831 break
2829 else:
2832 else:
2830 return
2833 return
2831
2834
2832 copies = None
2835 copies = None
2833 if opts.get('copies') and rev:
2836 if opts.get('copies') and rev:
2834 copies = []
2837 copies = []
2835 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2838 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2836 for fn in ctx.files():
2839 for fn in ctx.files():
2837 rename = getrenamed(fn, rev)
2840 rename = getrenamed(fn, rev)
2838 if rename:
2841 if rename:
2839 copies.append((fn, rename[0]))
2842 copies.append((fn, rename[0]))
2840
2843
2841 revmatchfn = None
2844 revmatchfn = None
2842 if opts.get('patch') or opts.get('stat'):
2845 if opts.get('patch') or opts.get('stat'):
2843 if opts.get('follow') or opts.get('follow_first'):
2846 if opts.get('follow') or opts.get('follow_first'):
2844 # note: this might be wrong when following through merges
2847 # note: this might be wrong when following through merges
2845 revmatchfn = cmdutil.match(repo, fns, default='path')
2848 revmatchfn = cmdutil.match(repo, fns, default='path')
2846 else:
2849 else:
2847 revmatchfn = matchfn
2850 revmatchfn = matchfn
2848
2851
2849 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2852 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2850
2853
2851 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2854 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2852 if count == limit:
2855 if count == limit:
2853 break
2856 break
2854 if displayer.flush(ctx.rev()):
2857 if displayer.flush(ctx.rev()):
2855 count += 1
2858 count += 1
2856 displayer.close()
2859 displayer.close()
2857
2860
2858 def manifest(ui, repo, node=None, rev=None):
2861 def manifest(ui, repo, node=None, rev=None):
2859 """output the current or given revision of the project manifest
2862 """output the current or given revision of the project manifest
2860
2863
2861 Print a list of version controlled files for the given revision.
2864 Print a list of version controlled files for the given revision.
2862 If no revision is given, the first parent of the working directory
2865 If no revision is given, the first parent of the working directory
2863 is used, or the null revision if no revision is checked out.
2866 is used, or the null revision if no revision is checked out.
2864
2867
2865 With -v, print file permissions, symlink and executable bits.
2868 With -v, print file permissions, symlink and executable bits.
2866 With --debug, print file revision hashes.
2869 With --debug, print file revision hashes.
2867
2870
2868 Returns 0 on success.
2871 Returns 0 on success.
2869 """
2872 """
2870
2873
2871 if rev and node:
2874 if rev and node:
2872 raise util.Abort(_("please specify just one revision"))
2875 raise util.Abort(_("please specify just one revision"))
2873
2876
2874 if not node:
2877 if not node:
2875 node = rev
2878 node = rev
2876
2879
2877 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2880 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2878 ctx = cmdutil.revsingle(repo, node)
2881 ctx = cmdutil.revsingle(repo, node)
2879 for f in ctx:
2882 for f in ctx:
2880 if ui.debugflag:
2883 if ui.debugflag:
2881 ui.write("%40s " % hex(ctx.manifest()[f]))
2884 ui.write("%40s " % hex(ctx.manifest()[f]))
2882 if ui.verbose:
2885 if ui.verbose:
2883 ui.write(decor[ctx.flags(f)])
2886 ui.write(decor[ctx.flags(f)])
2884 ui.write("%s\n" % f)
2887 ui.write("%s\n" % f)
2885
2888
2886 def merge(ui, repo, node=None, **opts):
2889 def merge(ui, repo, node=None, **opts):
2887 """merge working directory with another revision
2890 """merge working directory with another revision
2888
2891
2889 The current working directory is updated with all changes made in
2892 The current working directory is updated with all changes made in
2890 the requested revision since the last common predecessor revision.
2893 the requested revision since the last common predecessor revision.
2891
2894
2892 Files that changed between either parent are marked as changed for
2895 Files that changed between either parent are marked as changed for
2893 the next commit and a commit must be performed before any further
2896 the next commit and a commit must be performed before any further
2894 updates to the repository are allowed. The next commit will have
2897 updates to the repository are allowed. The next commit will have
2895 two parents.
2898 two parents.
2896
2899
2897 ``--tool`` can be used to specify the merge tool used for file
2900 ``--tool`` can be used to specify the merge tool used for file
2898 merges. It overrides the HGMERGE environment variable and your
2901 merges. It overrides the HGMERGE environment variable and your
2899 configuration files. See :hg:`help merge-tools` for options.
2902 configuration files. See :hg:`help merge-tools` for options.
2900
2903
2901 If no revision is specified, the working directory's parent is a
2904 If no revision is specified, the working directory's parent is a
2902 head revision, and the current branch contains exactly one other
2905 head revision, and the current branch contains exactly one other
2903 head, the other head is merged with by default. Otherwise, an
2906 head, the other head is merged with by default. Otherwise, an
2904 explicit revision with which to merge with must be provided.
2907 explicit revision with which to merge with must be provided.
2905
2908
2906 :hg:`resolve` must be used to resolve unresolved files.
2909 :hg:`resolve` must be used to resolve unresolved files.
2907
2910
2908 To undo an uncommitted merge, use :hg:`update --clean .` which
2911 To undo an uncommitted merge, use :hg:`update --clean .` which
2909 will check out a clean copy of the original merge parent, losing
2912 will check out a clean copy of the original merge parent, losing
2910 all changes.
2913 all changes.
2911
2914
2912 Returns 0 on success, 1 if there are unresolved files.
2915 Returns 0 on success, 1 if there are unresolved files.
2913 """
2916 """
2914
2917
2915 if opts.get('rev') and node:
2918 if opts.get('rev') and node:
2916 raise util.Abort(_("please specify just one revision"))
2919 raise util.Abort(_("please specify just one revision"))
2917 if not node:
2920 if not node:
2918 node = opts.get('rev')
2921 node = opts.get('rev')
2919
2922
2920 if not node:
2923 if not node:
2921 branch = repo[None].branch()
2924 branch = repo[None].branch()
2922 bheads = repo.branchheads(branch)
2925 bheads = repo.branchheads(branch)
2923 if len(bheads) > 2:
2926 if len(bheads) > 2:
2924 raise util.Abort(_(
2927 raise util.Abort(_(
2925 'branch \'%s\' has %d heads - '
2928 'branch \'%s\' has %d heads - '
2926 'please merge with an explicit rev\n'
2929 'please merge with an explicit rev\n'
2927 '(run \'hg heads .\' to see heads)')
2930 '(run \'hg heads .\' to see heads)')
2928 % (branch, len(bheads)))
2931 % (branch, len(bheads)))
2929
2932
2930 parent = repo.dirstate.p1()
2933 parent = repo.dirstate.p1()
2931 if len(bheads) == 1:
2934 if len(bheads) == 1:
2932 if len(repo.heads()) > 1:
2935 if len(repo.heads()) > 1:
2933 raise util.Abort(_(
2936 raise util.Abort(_(
2934 'branch \'%s\' has one head - '
2937 'branch \'%s\' has one head - '
2935 'please merge with an explicit rev\n'
2938 'please merge with an explicit rev\n'
2936 '(run \'hg heads\' to see all heads)')
2939 '(run \'hg heads\' to see all heads)')
2937 % branch)
2940 % branch)
2938 msg = _('there is nothing to merge')
2941 msg = _('there is nothing to merge')
2939 if parent != repo.lookup(repo[None].branch()):
2942 if parent != repo.lookup(repo[None].branch()):
2940 msg = _('%s - use "hg update" instead') % msg
2943 msg = _('%s - use "hg update" instead') % msg
2941 raise util.Abort(msg)
2944 raise util.Abort(msg)
2942
2945
2943 if parent not in bheads:
2946 if parent not in bheads:
2944 raise util.Abort(_('working dir not at a head rev - '
2947 raise util.Abort(_('working dir not at a head rev - '
2945 'use "hg update" or merge with an explicit rev'))
2948 'use "hg update" or merge with an explicit rev'))
2946 node = parent == bheads[0] and bheads[-1] or bheads[0]
2949 node = parent == bheads[0] and bheads[-1] or bheads[0]
2947 else:
2950 else:
2948 node = cmdutil.revsingle(repo, node).node()
2951 node = cmdutil.revsingle(repo, node).node()
2949
2952
2950 if opts.get('preview'):
2953 if opts.get('preview'):
2951 # find nodes that are ancestors of p2 but not of p1
2954 # find nodes that are ancestors of p2 but not of p1
2952 p1 = repo.lookup('.')
2955 p1 = repo.lookup('.')
2953 p2 = repo.lookup(node)
2956 p2 = repo.lookup(node)
2954 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2957 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2955
2958
2956 displayer = cmdutil.show_changeset(ui, repo, opts)
2959 displayer = cmdutil.show_changeset(ui, repo, opts)
2957 for node in nodes:
2960 for node in nodes:
2958 displayer.show(repo[node])
2961 displayer.show(repo[node])
2959 displayer.close()
2962 displayer.close()
2960 return 0
2963 return 0
2961
2964
2962 try:
2965 try:
2963 # ui.forcemerge is an internal variable, do not document
2966 # ui.forcemerge is an internal variable, do not document
2964 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2967 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2965 return hg.merge(repo, node, force=opts.get('force'))
2968 return hg.merge(repo, node, force=opts.get('force'))
2966 finally:
2969 finally:
2967 ui.setconfig('ui', 'forcemerge', '')
2970 ui.setconfig('ui', 'forcemerge', '')
2968
2971
2969 def outgoing(ui, repo, dest=None, **opts):
2972 def outgoing(ui, repo, dest=None, **opts):
2970 """show changesets not found in the destination
2973 """show changesets not found in the destination
2971
2974
2972 Show changesets not found in the specified destination repository
2975 Show changesets not found in the specified destination repository
2973 or the default push location. These are the changesets that would
2976 or the default push location. These are the changesets that would
2974 be pushed if a push was requested.
2977 be pushed if a push was requested.
2975
2978
2976 See pull for details of valid destination formats.
2979 See pull for details of valid destination formats.
2977
2980
2978 Returns 0 if there are outgoing changes, 1 otherwise.
2981 Returns 0 if there are outgoing changes, 1 otherwise.
2979 """
2982 """
2980
2983
2981 if opts.get('bookmarks'):
2984 if opts.get('bookmarks'):
2982 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2985 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2983 dest, branches = hg.parseurl(dest, opts.get('branch'))
2986 dest, branches = hg.parseurl(dest, opts.get('branch'))
2984 other = hg.repository(hg.remoteui(repo, opts), dest)
2987 other = hg.repository(hg.remoteui(repo, opts), dest)
2985 if 'bookmarks' not in other.listkeys('namespaces'):
2988 if 'bookmarks' not in other.listkeys('namespaces'):
2986 ui.warn(_("remote doesn't support bookmarks\n"))
2989 ui.warn(_("remote doesn't support bookmarks\n"))
2987 return 0
2990 return 0
2988 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
2991 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
2989 return bookmarks.diff(ui, other, repo)
2992 return bookmarks.diff(ui, other, repo)
2990
2993
2991 ret = hg.outgoing(ui, repo, dest, opts)
2994 ret = hg.outgoing(ui, repo, dest, opts)
2992 return ret
2995 return ret
2993
2996
2994 def parents(ui, repo, file_=None, **opts):
2997 def parents(ui, repo, file_=None, **opts):
2995 """show the parents of the working directory or revision
2998 """show the parents of the working directory or revision
2996
2999
2997 Print the working directory's parent revisions. If a revision is
3000 Print the working directory's parent revisions. If a revision is
2998 given via -r/--rev, the parent of that revision will be printed.
3001 given via -r/--rev, the parent of that revision will be printed.
2999 If a file argument is given, the revision in which the file was
3002 If a file argument is given, the revision in which the file was
3000 last changed (before the working directory revision or the
3003 last changed (before the working directory revision or the
3001 argument to --rev if given) is printed.
3004 argument to --rev if given) is printed.
3002
3005
3003 Returns 0 on success.
3006 Returns 0 on success.
3004 """
3007 """
3005
3008
3006 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
3009 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
3007
3010
3008 if file_:
3011 if file_:
3009 m = cmdutil.match(repo, (file_,), opts)
3012 m = cmdutil.match(repo, (file_,), opts)
3010 if m.anypats() or len(m.files()) != 1:
3013 if m.anypats() or len(m.files()) != 1:
3011 raise util.Abort(_('can only specify an explicit filename'))
3014 raise util.Abort(_('can only specify an explicit filename'))
3012 file_ = m.files()[0]
3015 file_ = m.files()[0]
3013 filenodes = []
3016 filenodes = []
3014 for cp in ctx.parents():
3017 for cp in ctx.parents():
3015 if not cp:
3018 if not cp:
3016 continue
3019 continue
3017 try:
3020 try:
3018 filenodes.append(cp.filenode(file_))
3021 filenodes.append(cp.filenode(file_))
3019 except error.LookupError:
3022 except error.LookupError:
3020 pass
3023 pass
3021 if not filenodes:
3024 if not filenodes:
3022 raise util.Abort(_("'%s' not found in manifest!") % file_)
3025 raise util.Abort(_("'%s' not found in manifest!") % file_)
3023 fl = repo.file(file_)
3026 fl = repo.file(file_)
3024 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
3027 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
3025 else:
3028 else:
3026 p = [cp.node() for cp in ctx.parents()]
3029 p = [cp.node() for cp in ctx.parents()]
3027
3030
3028 displayer = cmdutil.show_changeset(ui, repo, opts)
3031 displayer = cmdutil.show_changeset(ui, repo, opts)
3029 for n in p:
3032 for n in p:
3030 if n != nullid:
3033 if n != nullid:
3031 displayer.show(repo[n])
3034 displayer.show(repo[n])
3032 displayer.close()
3035 displayer.close()
3033
3036
3034 def paths(ui, repo, search=None):
3037 def paths(ui, repo, search=None):
3035 """show aliases for remote repositories
3038 """show aliases for remote repositories
3036
3039
3037 Show definition of symbolic path name NAME. If no name is given,
3040 Show definition of symbolic path name NAME. If no name is given,
3038 show definition of all available names.
3041 show definition of all available names.
3039
3042
3040 Path names are defined in the [paths] section of your
3043 Path names are defined in the [paths] section of your
3041 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
3044 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
3042 repository, ``.hg/hgrc`` is used, too.
3045 repository, ``.hg/hgrc`` is used, too.
3043
3046
3044 The path names ``default`` and ``default-push`` have a special
3047 The path names ``default`` and ``default-push`` have a special
3045 meaning. When performing a push or pull operation, they are used
3048 meaning. When performing a push or pull operation, they are used
3046 as fallbacks if no location is specified on the command-line.
3049 as fallbacks if no location is specified on the command-line.
3047 When ``default-push`` is set, it will be used for push and
3050 When ``default-push`` is set, it will be used for push and
3048 ``default`` will be used for pull; otherwise ``default`` is used
3051 ``default`` will be used for pull; otherwise ``default`` is used
3049 as the fallback for both. When cloning a repository, the clone
3052 as the fallback for both. When cloning a repository, the clone
3050 source is written as ``default`` in ``.hg/hgrc``. Note that
3053 source is written as ``default`` in ``.hg/hgrc``. Note that
3051 ``default`` and ``default-push`` apply to all inbound (e.g.
3054 ``default`` and ``default-push`` apply to all inbound (e.g.
3052 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
3055 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
3053 :hg:`bundle`) operations.
3056 :hg:`bundle`) operations.
3054
3057
3055 See :hg:`help urls` for more information.
3058 See :hg:`help urls` for more information.
3056
3059
3057 Returns 0 on success.
3060 Returns 0 on success.
3058 """
3061 """
3059 if search:
3062 if search:
3060 for name, path in ui.configitems("paths"):
3063 for name, path in ui.configitems("paths"):
3061 if name == search:
3064 if name == search:
3062 ui.write("%s\n" % util.hidepassword(path))
3065 ui.write("%s\n" % util.hidepassword(path))
3063 return
3066 return
3064 ui.warn(_("not found!\n"))
3067 ui.warn(_("not found!\n"))
3065 return 1
3068 return 1
3066 else:
3069 else:
3067 for name, path in ui.configitems("paths"):
3070 for name, path in ui.configitems("paths"):
3068 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
3071 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
3069
3072
3070 def postincoming(ui, repo, modheads, optupdate, checkout):
3073 def postincoming(ui, repo, modheads, optupdate, checkout):
3071 if modheads == 0:
3074 if modheads == 0:
3072 return
3075 return
3073 if optupdate:
3076 if optupdate:
3074 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
3077 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
3075 return hg.update(repo, checkout)
3078 return hg.update(repo, checkout)
3076 else:
3079 else:
3077 ui.status(_("not updating, since new heads added\n"))
3080 ui.status(_("not updating, since new heads added\n"))
3078 if modheads > 1:
3081 if modheads > 1:
3079 currentbranchheads = len(repo.branchheads())
3082 currentbranchheads = len(repo.branchheads())
3080 if currentbranchheads == modheads:
3083 if currentbranchheads == modheads:
3081 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3084 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3082 elif currentbranchheads > 1:
3085 elif currentbranchheads > 1:
3083 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
3086 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
3084 else:
3087 else:
3085 ui.status(_("(run 'hg heads' to see heads)\n"))
3088 ui.status(_("(run 'hg heads' to see heads)\n"))
3086 else:
3089 else:
3087 ui.status(_("(run 'hg update' to get a working copy)\n"))
3090 ui.status(_("(run 'hg update' to get a working copy)\n"))
3088
3091
3089 def pull(ui, repo, source="default", **opts):
3092 def pull(ui, repo, source="default", **opts):
3090 """pull changes from the specified source
3093 """pull changes from the specified source
3091
3094
3092 Pull changes from a remote repository to a local one.
3095 Pull changes from a remote repository to a local one.
3093
3096
3094 This finds all changes from the repository at the specified path
3097 This finds all changes from the repository at the specified path
3095 or URL and adds them to a local repository (the current one unless
3098 or URL and adds them to a local repository (the current one unless
3096 -R is specified). By default, this does not update the copy of the
3099 -R is specified). By default, this does not update the copy of the
3097 project in the working directory.
3100 project in the working directory.
3098
3101
3099 Use :hg:`incoming` if you want to see what would have been added
3102 Use :hg:`incoming` if you want to see what would have been added
3100 by a pull at the time you issued this command. If you then decide
3103 by a pull at the time you issued this command. If you then decide
3101 to add those changes to the repository, you should use :hg:`pull
3104 to add those changes to the repository, you should use :hg:`pull
3102 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3105 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3103
3106
3104 If SOURCE is omitted, the 'default' path will be used.
3107 If SOURCE is omitted, the 'default' path will be used.
3105 See :hg:`help urls` for more information.
3108 See :hg:`help urls` for more information.
3106
3109
3107 Returns 0 on success, 1 if an update had unresolved files.
3110 Returns 0 on success, 1 if an update had unresolved files.
3108 """
3111 """
3109 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3112 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3110 other = hg.repository(hg.remoteui(repo, opts), source)
3113 other = hg.repository(hg.remoteui(repo, opts), source)
3111 ui.status(_('pulling from %s\n') % util.hidepassword(source))
3114 ui.status(_('pulling from %s\n') % util.hidepassword(source))
3112 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3115 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3113
3116
3114 if opts.get('bookmark'):
3117 if opts.get('bookmark'):
3115 if not revs:
3118 if not revs:
3116 revs = []
3119 revs = []
3117 rb = other.listkeys('bookmarks')
3120 rb = other.listkeys('bookmarks')
3118 for b in opts['bookmark']:
3121 for b in opts['bookmark']:
3119 if b not in rb:
3122 if b not in rb:
3120 raise util.Abort(_('remote bookmark %s not found!') % b)
3123 raise util.Abort(_('remote bookmark %s not found!') % b)
3121 revs.append(rb[b])
3124 revs.append(rb[b])
3122
3125
3123 if revs:
3126 if revs:
3124 try:
3127 try:
3125 revs = [other.lookup(rev) for rev in revs]
3128 revs = [other.lookup(rev) for rev in revs]
3126 except error.CapabilityError:
3129 except error.CapabilityError:
3127 err = _("other repository doesn't support revision lookup, "
3130 err = _("other repository doesn't support revision lookup, "
3128 "so a rev cannot be specified.")
3131 "so a rev cannot be specified.")
3129 raise util.Abort(err)
3132 raise util.Abort(err)
3130
3133
3131 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
3134 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
3132 bookmarks.updatefromremote(ui, repo, other)
3135 bookmarks.updatefromremote(ui, repo, other)
3133 if checkout:
3136 if checkout:
3134 checkout = str(repo.changelog.rev(other.lookup(checkout)))
3137 checkout = str(repo.changelog.rev(other.lookup(checkout)))
3135 repo._subtoppath = source
3138 repo._subtoppath = source
3136 try:
3139 try:
3137 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
3140 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
3138
3141
3139 finally:
3142 finally:
3140 del repo._subtoppath
3143 del repo._subtoppath
3141
3144
3142 # update specified bookmarks
3145 # update specified bookmarks
3143 if opts.get('bookmark'):
3146 if opts.get('bookmark'):
3144 for b in opts['bookmark']:
3147 for b in opts['bookmark']:
3145 # explicit pull overrides local bookmark if any
3148 # explicit pull overrides local bookmark if any
3146 ui.status(_("importing bookmark %s\n") % b)
3149 ui.status(_("importing bookmark %s\n") % b)
3147 repo._bookmarks[b] = repo[rb[b]].node()
3150 repo._bookmarks[b] = repo[rb[b]].node()
3148 bookmarks.write(repo)
3151 bookmarks.write(repo)
3149
3152
3150 return ret
3153 return ret
3151
3154
3152 def push(ui, repo, dest=None, **opts):
3155 def push(ui, repo, dest=None, **opts):
3153 """push changes to the specified destination
3156 """push changes to the specified destination
3154
3157
3155 Push changesets from the local repository to the specified
3158 Push changesets from the local repository to the specified
3156 destination.
3159 destination.
3157
3160
3158 This operation is symmetrical to pull: it is identical to a pull
3161 This operation is symmetrical to pull: it is identical to a pull
3159 in the destination repository from the current one.
3162 in the destination repository from the current one.
3160
3163
3161 By default, push will not allow creation of new heads at the
3164 By default, push will not allow creation of new heads at the
3162 destination, since multiple heads would make it unclear which head
3165 destination, since multiple heads would make it unclear which head
3163 to use. In this situation, it is recommended to pull and merge
3166 to use. In this situation, it is recommended to pull and merge
3164 before pushing.
3167 before pushing.
3165
3168
3166 Use --new-branch if you want to allow push to create a new named
3169 Use --new-branch if you want to allow push to create a new named
3167 branch that is not present at the destination. This allows you to
3170 branch that is not present at the destination. This allows you to
3168 only create a new branch without forcing other changes.
3171 only create a new branch without forcing other changes.
3169
3172
3170 Use -f/--force to override the default behavior and push all
3173 Use -f/--force to override the default behavior and push all
3171 changesets on all branches.
3174 changesets on all branches.
3172
3175
3173 If -r/--rev is used, the specified revision and all its ancestors
3176 If -r/--rev is used, the specified revision and all its ancestors
3174 will be pushed to the remote repository.
3177 will be pushed to the remote repository.
3175
3178
3176 Please see :hg:`help urls` for important details about ``ssh://``
3179 Please see :hg:`help urls` for important details about ``ssh://``
3177 URLs. If DESTINATION is omitted, a default path will be used.
3180 URLs. If DESTINATION is omitted, a default path will be used.
3178
3181
3179 Returns 0 if push was successful, 1 if nothing to push.
3182 Returns 0 if push was successful, 1 if nothing to push.
3180 """
3183 """
3181
3184
3182 if opts.get('bookmark'):
3185 if opts.get('bookmark'):
3183 for b in opts['bookmark']:
3186 for b in opts['bookmark']:
3184 # translate -B options to -r so changesets get pushed
3187 # translate -B options to -r so changesets get pushed
3185 if b in repo._bookmarks:
3188 if b in repo._bookmarks:
3186 opts.setdefault('rev', []).append(b)
3189 opts.setdefault('rev', []).append(b)
3187 else:
3190 else:
3188 # if we try to push a deleted bookmark, translate it to null
3191 # if we try to push a deleted bookmark, translate it to null
3189 # this lets simultaneous -r, -b options continue working
3192 # this lets simultaneous -r, -b options continue working
3190 opts.setdefault('rev', []).append("null")
3193 opts.setdefault('rev', []).append("null")
3191
3194
3192 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3195 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3193 dest, branches = hg.parseurl(dest, opts.get('branch'))
3196 dest, branches = hg.parseurl(dest, opts.get('branch'))
3194 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
3197 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
3195 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
3198 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
3196 other = hg.repository(hg.remoteui(repo, opts), dest)
3199 other = hg.repository(hg.remoteui(repo, opts), dest)
3197 if revs:
3200 if revs:
3198 revs = [repo.lookup(rev) for rev in revs]
3201 revs = [repo.lookup(rev) for rev in revs]
3199
3202
3200 repo._subtoppath = dest
3203 repo._subtoppath = dest
3201 try:
3204 try:
3202 # push subrepos depth-first for coherent ordering
3205 # push subrepos depth-first for coherent ordering
3203 c = repo['']
3206 c = repo['']
3204 subs = c.substate # only repos that are committed
3207 subs = c.substate # only repos that are committed
3205 for s in sorted(subs):
3208 for s in sorted(subs):
3206 if not c.sub(s).push(opts.get('force')):
3209 if not c.sub(s).push(opts.get('force')):
3207 return False
3210 return False
3208 finally:
3211 finally:
3209 del repo._subtoppath
3212 del repo._subtoppath
3210 result = repo.push(other, opts.get('force'), revs=revs,
3213 result = repo.push(other, opts.get('force'), revs=revs,
3211 newbranch=opts.get('new_branch'))
3214 newbranch=opts.get('new_branch'))
3212
3215
3213 result = (result == 0)
3216 result = (result == 0)
3214
3217
3215 if opts.get('bookmark'):
3218 if opts.get('bookmark'):
3216 rb = other.listkeys('bookmarks')
3219 rb = other.listkeys('bookmarks')
3217 for b in opts['bookmark']:
3220 for b in opts['bookmark']:
3218 # explicit push overrides remote bookmark if any
3221 # explicit push overrides remote bookmark if any
3219 if b in repo._bookmarks:
3222 if b in repo._bookmarks:
3220 ui.status(_("exporting bookmark %s\n") % b)
3223 ui.status(_("exporting bookmark %s\n") % b)
3221 new = repo[b].hex()
3224 new = repo[b].hex()
3222 elif b in rb:
3225 elif b in rb:
3223 ui.status(_("deleting remote bookmark %s\n") % b)
3226 ui.status(_("deleting remote bookmark %s\n") % b)
3224 new = '' # delete
3227 new = '' # delete
3225 else:
3228 else:
3226 ui.warn(_('bookmark %s does not exist on the local '
3229 ui.warn(_('bookmark %s does not exist on the local '
3227 'or remote repository!\n') % b)
3230 'or remote repository!\n') % b)
3228 return 2
3231 return 2
3229 old = rb.get(b, '')
3232 old = rb.get(b, '')
3230 r = other.pushkey('bookmarks', b, old, new)
3233 r = other.pushkey('bookmarks', b, old, new)
3231 if not r:
3234 if not r:
3232 ui.warn(_('updating bookmark %s failed!\n') % b)
3235 ui.warn(_('updating bookmark %s failed!\n') % b)
3233 if not result:
3236 if not result:
3234 result = 2
3237 result = 2
3235
3238
3236 return result
3239 return result
3237
3240
3238 def recover(ui, repo):
3241 def recover(ui, repo):
3239 """roll back an interrupted transaction
3242 """roll back an interrupted transaction
3240
3243
3241 Recover from an interrupted commit or pull.
3244 Recover from an interrupted commit or pull.
3242
3245
3243 This command tries to fix the repository status after an
3246 This command tries to fix the repository status after an
3244 interrupted operation. It should only be necessary when Mercurial
3247 interrupted operation. It should only be necessary when Mercurial
3245 suggests it.
3248 suggests it.
3246
3249
3247 Returns 0 if successful, 1 if nothing to recover or verify fails.
3250 Returns 0 if successful, 1 if nothing to recover or verify fails.
3248 """
3251 """
3249 if repo.recover():
3252 if repo.recover():
3250 return hg.verify(repo)
3253 return hg.verify(repo)
3251 return 1
3254 return 1
3252
3255
3253 def remove(ui, repo, *pats, **opts):
3256 def remove(ui, repo, *pats, **opts):
3254 """remove the specified files on the next commit
3257 """remove the specified files on the next commit
3255
3258
3256 Schedule the indicated files for removal from the repository.
3259 Schedule the indicated files for removal from the repository.
3257
3260
3258 This only removes files from the current branch, not from the
3261 This only removes files from the current branch, not from the
3259 entire project history. -A/--after can be used to remove only
3262 entire project history. -A/--after can be used to remove only
3260 files that have already been deleted, -f/--force can be used to
3263 files that have already been deleted, -f/--force can be used to
3261 force deletion, and -Af can be used to remove files from the next
3264 force deletion, and -Af can be used to remove files from the next
3262 revision without deleting them from the working directory.
3265 revision without deleting them from the working directory.
3263
3266
3264 The following table details the behavior of remove for different
3267 The following table details the behavior of remove for different
3265 file states (columns) and option combinations (rows). The file
3268 file states (columns) and option combinations (rows). The file
3266 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3269 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3267 reported by :hg:`status`). The actions are Warn, Remove (from
3270 reported by :hg:`status`). The actions are Warn, Remove (from
3268 branch) and Delete (from disk)::
3271 branch) and Delete (from disk)::
3269
3272
3270 A C M !
3273 A C M !
3271 none W RD W R
3274 none W RD W R
3272 -f R RD RD R
3275 -f R RD RD R
3273 -A W W W R
3276 -A W W W R
3274 -Af R R R R
3277 -Af R R R R
3275
3278
3276 This command schedules the files to be removed at the next commit.
3279 This command schedules the files to be removed at the next commit.
3277 To undo a remove before that, see :hg:`revert`.
3280 To undo a remove before that, see :hg:`revert`.
3278
3281
3279 Returns 0 on success, 1 if any warnings encountered.
3282 Returns 0 on success, 1 if any warnings encountered.
3280 """
3283 """
3281
3284
3282 ret = 0
3285 ret = 0
3283 after, force = opts.get('after'), opts.get('force')
3286 after, force = opts.get('after'), opts.get('force')
3284 if not pats and not after:
3287 if not pats and not after:
3285 raise util.Abort(_('no files specified'))
3288 raise util.Abort(_('no files specified'))
3286
3289
3287 m = cmdutil.match(repo, pats, opts)
3290 m = cmdutil.match(repo, pats, opts)
3288 s = repo.status(match=m, clean=True)
3291 s = repo.status(match=m, clean=True)
3289 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3292 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3290
3293
3291 for f in m.files():
3294 for f in m.files():
3292 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3295 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3293 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3296 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3294 ret = 1
3297 ret = 1
3295
3298
3296 if force:
3299 if force:
3297 remove, forget = modified + deleted + clean, added
3300 remove, forget = modified + deleted + clean, added
3298 elif after:
3301 elif after:
3299 remove, forget = deleted, []
3302 remove, forget = deleted, []
3300 for f in modified + added + clean:
3303 for f in modified + added + clean:
3301 ui.warn(_('not removing %s: file still exists (use -f'
3304 ui.warn(_('not removing %s: file still exists (use -f'
3302 ' to force removal)\n') % m.rel(f))
3305 ' to force removal)\n') % m.rel(f))
3303 ret = 1
3306 ret = 1
3304 else:
3307 else:
3305 remove, forget = deleted + clean, []
3308 remove, forget = deleted + clean, []
3306 for f in modified:
3309 for f in modified:
3307 ui.warn(_('not removing %s: file is modified (use -f'
3310 ui.warn(_('not removing %s: file is modified (use -f'
3308 ' to force removal)\n') % m.rel(f))
3311 ' to force removal)\n') % m.rel(f))
3309 ret = 1
3312 ret = 1
3310 for f in added:
3313 for f in added:
3311 ui.warn(_('not removing %s: file has been marked for add (use -f'
3314 ui.warn(_('not removing %s: file has been marked for add (use -f'
3312 ' to force removal)\n') % m.rel(f))
3315 ' to force removal)\n') % m.rel(f))
3313 ret = 1
3316 ret = 1
3314
3317
3315 for f in sorted(remove + forget):
3318 for f in sorted(remove + forget):
3316 if ui.verbose or not m.exact(f):
3319 if ui.verbose or not m.exact(f):
3317 ui.status(_('removing %s\n') % m.rel(f))
3320 ui.status(_('removing %s\n') % m.rel(f))
3318
3321
3319 repo[None].forget(forget)
3322 repo[None].forget(forget)
3320 repo[None].remove(remove, unlink=not after)
3323 repo[None].remove(remove, unlink=not after)
3321 return ret
3324 return ret
3322
3325
3323 def rename(ui, repo, *pats, **opts):
3326 def rename(ui, repo, *pats, **opts):
3324 """rename files; equivalent of copy + remove
3327 """rename files; equivalent of copy + remove
3325
3328
3326 Mark dest as copies of sources; mark sources for deletion. If dest
3329 Mark dest as copies of sources; mark sources for deletion. If dest
3327 is a directory, copies are put in that directory. If dest is a
3330 is a directory, copies are put in that directory. If dest is a
3328 file, there can only be one source.
3331 file, there can only be one source.
3329
3332
3330 By default, this command copies the contents of files as they
3333 By default, this command copies the contents of files as they
3331 exist in the working directory. If invoked with -A/--after, the
3334 exist in the working directory. If invoked with -A/--after, the
3332 operation is recorded, but no copying is performed.
3335 operation is recorded, but no copying is performed.
3333
3336
3334 This command takes effect at the next commit. To undo a rename
3337 This command takes effect at the next commit. To undo a rename
3335 before that, see :hg:`revert`.
3338 before that, see :hg:`revert`.
3336
3339
3337 Returns 0 on success, 1 if errors are encountered.
3340 Returns 0 on success, 1 if errors are encountered.
3338 """
3341 """
3339 wlock = repo.wlock(False)
3342 wlock = repo.wlock(False)
3340 try:
3343 try:
3341 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3344 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3342 finally:
3345 finally:
3343 wlock.release()
3346 wlock.release()
3344
3347
3345 def resolve(ui, repo, *pats, **opts):
3348 def resolve(ui, repo, *pats, **opts):
3346 """redo merges or set/view the merge status of files
3349 """redo merges or set/view the merge status of files
3347
3350
3348 Merges with unresolved conflicts are often the result of
3351 Merges with unresolved conflicts are often the result of
3349 non-interactive merging using the ``internal:merge`` configuration
3352 non-interactive merging using the ``internal:merge`` configuration
3350 setting, or a command-line merge tool like ``diff3``. The resolve
3353 setting, or a command-line merge tool like ``diff3``. The resolve
3351 command is used to manage the files involved in a merge, after
3354 command is used to manage the files involved in a merge, after
3352 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3355 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3353 working directory must have two parents).
3356 working directory must have two parents).
3354
3357
3355 The resolve command can be used in the following ways:
3358 The resolve command can be used in the following ways:
3356
3359
3357 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3360 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3358 files, discarding any previous merge attempts. Re-merging is not
3361 files, discarding any previous merge attempts. Re-merging is not
3359 performed for files already marked as resolved. Use ``--all/-a``
3362 performed for files already marked as resolved. Use ``--all/-a``
3360 to selects all unresolved files. ``--tool`` can be used to specify
3363 to selects all unresolved files. ``--tool`` can be used to specify
3361 the merge tool used for the given files. It overrides the HGMERGE
3364 the merge tool used for the given files. It overrides the HGMERGE
3362 environment variable and your configuration files.
3365 environment variable and your configuration files.
3363
3366
3364 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3367 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3365 (e.g. after having manually fixed-up the files). The default is
3368 (e.g. after having manually fixed-up the files). The default is
3366 to mark all unresolved files.
3369 to mark all unresolved files.
3367
3370
3368 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3371 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3369 default is to mark all resolved files.
3372 default is to mark all resolved files.
3370
3373
3371 - :hg:`resolve -l`: list files which had or still have conflicts.
3374 - :hg:`resolve -l`: list files which had or still have conflicts.
3372 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3375 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3373
3376
3374 Note that Mercurial will not let you commit files with unresolved
3377 Note that Mercurial will not let you commit files with unresolved
3375 merge conflicts. You must use :hg:`resolve -m ...` before you can
3378 merge conflicts. You must use :hg:`resolve -m ...` before you can
3376 commit after a conflicting merge.
3379 commit after a conflicting merge.
3377
3380
3378 Returns 0 on success, 1 if any files fail a resolve attempt.
3381 Returns 0 on success, 1 if any files fail a resolve attempt.
3379 """
3382 """
3380
3383
3381 all, mark, unmark, show, nostatus = \
3384 all, mark, unmark, show, nostatus = \
3382 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3385 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3383
3386
3384 if (show and (mark or unmark)) or (mark and unmark):
3387 if (show and (mark or unmark)) or (mark and unmark):
3385 raise util.Abort(_("too many options specified"))
3388 raise util.Abort(_("too many options specified"))
3386 if pats and all:
3389 if pats and all:
3387 raise util.Abort(_("can't specify --all and patterns"))
3390 raise util.Abort(_("can't specify --all and patterns"))
3388 if not (all or pats or show or mark or unmark):
3391 if not (all or pats or show or mark or unmark):
3389 raise util.Abort(_('no files or directories specified; '
3392 raise util.Abort(_('no files or directories specified; '
3390 'use --all to remerge all files'))
3393 'use --all to remerge all files'))
3391
3394
3392 ms = mergemod.mergestate(repo)
3395 ms = mergemod.mergestate(repo)
3393 m = cmdutil.match(repo, pats, opts)
3396 m = cmdutil.match(repo, pats, opts)
3394 ret = 0
3397 ret = 0
3395
3398
3396 for f in ms:
3399 for f in ms:
3397 if m(f):
3400 if m(f):
3398 if show:
3401 if show:
3399 if nostatus:
3402 if nostatus:
3400 ui.write("%s\n" % f)
3403 ui.write("%s\n" % f)
3401 else:
3404 else:
3402 ui.write("%s %s\n" % (ms[f].upper(), f),
3405 ui.write("%s %s\n" % (ms[f].upper(), f),
3403 label='resolve.' +
3406 label='resolve.' +
3404 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3407 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3405 elif mark:
3408 elif mark:
3406 ms.mark(f, "r")
3409 ms.mark(f, "r")
3407 elif unmark:
3410 elif unmark:
3408 ms.mark(f, "u")
3411 ms.mark(f, "u")
3409 else:
3412 else:
3410 wctx = repo[None]
3413 wctx = repo[None]
3411 mctx = wctx.parents()[-1]
3414 mctx = wctx.parents()[-1]
3412
3415
3413 # backup pre-resolve (merge uses .orig for its own purposes)
3416 # backup pre-resolve (merge uses .orig for its own purposes)
3414 a = repo.wjoin(f)
3417 a = repo.wjoin(f)
3415 util.copyfile(a, a + ".resolve")
3418 util.copyfile(a, a + ".resolve")
3416
3419
3417 try:
3420 try:
3418 # resolve file
3421 # resolve file
3419 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3422 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3420 if ms.resolve(f, wctx, mctx):
3423 if ms.resolve(f, wctx, mctx):
3421 ret = 1
3424 ret = 1
3422 finally:
3425 finally:
3423 ui.setconfig('ui', 'forcemerge', '')
3426 ui.setconfig('ui', 'forcemerge', '')
3424
3427
3425 # replace filemerge's .orig file with our resolve file
3428 # replace filemerge's .orig file with our resolve file
3426 util.rename(a + ".resolve", a + ".orig")
3429 util.rename(a + ".resolve", a + ".orig")
3427
3430
3428 ms.commit()
3431 ms.commit()
3429 return ret
3432 return ret
3430
3433
3431 def revert(ui, repo, *pats, **opts):
3434 def revert(ui, repo, *pats, **opts):
3432 """restore individual files or directories to an earlier state
3435 """restore individual files or directories to an earlier state
3433
3436
3434 .. note::
3437 .. note::
3435 This command is most likely not what you are looking for.
3438 This command is most likely not what you are looking for.
3436 Revert will partially overwrite content in the working
3439 Revert will partially overwrite content in the working
3437 directory without changing the working directory parents. Use
3440 directory without changing the working directory parents. Use
3438 :hg:`update -r rev` to check out earlier revisions, or
3441 :hg:`update -r rev` to check out earlier revisions, or
3439 :hg:`update --clean .` to undo a merge which has added another
3442 :hg:`update --clean .` to undo a merge which has added another
3440 parent.
3443 parent.
3441
3444
3442 With no revision specified, revert the named files or directories
3445 With no revision specified, revert the named files or directories
3443 to the contents they had in the parent of the working directory.
3446 to the contents they had in the parent of the working directory.
3444 This restores the contents of the affected files to an unmodified
3447 This restores the contents of the affected files to an unmodified
3445 state and unschedules adds, removes, copies, and renames. If the
3448 state and unschedules adds, removes, copies, and renames. If the
3446 working directory has two parents, you must explicitly specify a
3449 working directory has two parents, you must explicitly specify a
3447 revision.
3450 revision.
3448
3451
3449 Using the -r/--rev option, revert the given files or directories
3452 Using the -r/--rev option, revert the given files or directories
3450 to their contents as of a specific revision. This can be helpful
3453 to their contents as of a specific revision. This can be helpful
3451 to "roll back" some or all of an earlier change. See :hg:`help
3454 to "roll back" some or all of an earlier change. See :hg:`help
3452 dates` for a list of formats valid for -d/--date.
3455 dates` for a list of formats valid for -d/--date.
3453
3456
3454 Revert modifies the working directory. It does not commit any
3457 Revert modifies the working directory. It does not commit any
3455 changes, or change the parent of the working directory. If you
3458 changes, or change the parent of the working directory. If you
3456 revert to a revision other than the parent of the working
3459 revert to a revision other than the parent of the working
3457 directory, the reverted files will thus appear modified
3460 directory, the reverted files will thus appear modified
3458 afterwards.
3461 afterwards.
3459
3462
3460 If a file has been deleted, it is restored. Files scheduled for
3463 If a file has been deleted, it is restored. Files scheduled for
3461 addition are just unscheduled and left as they are. If the
3464 addition are just unscheduled and left as they are. If the
3462 executable mode of a file was changed, it is reset.
3465 executable mode of a file was changed, it is reset.
3463
3466
3464 If names are given, all files matching the names are reverted.
3467 If names are given, all files matching the names are reverted.
3465 If no arguments are given, no files are reverted.
3468 If no arguments are given, no files are reverted.
3466
3469
3467 Modified files are saved with a .orig suffix before reverting.
3470 Modified files are saved with a .orig suffix before reverting.
3468 To disable these backups, use --no-backup.
3471 To disable these backups, use --no-backup.
3469
3472
3470 Returns 0 on success.
3473 Returns 0 on success.
3471 """
3474 """
3472
3475
3473 if opts.get("date"):
3476 if opts.get("date"):
3474 if opts.get("rev"):
3477 if opts.get("rev"):
3475 raise util.Abort(_("you can't specify a revision and a date"))
3478 raise util.Abort(_("you can't specify a revision and a date"))
3476 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3479 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3477
3480
3478 parent, p2 = repo.dirstate.parents()
3481 parent, p2 = repo.dirstate.parents()
3479 if not opts.get('rev') and p2 != nullid:
3482 if not opts.get('rev') and p2 != nullid:
3480 raise util.Abort(_('uncommitted merge - '
3483 raise util.Abort(_('uncommitted merge - '
3481 'use "hg update", see "hg help revert"'))
3484 'use "hg update", see "hg help revert"'))
3482
3485
3483 if not pats and not opts.get('all'):
3486 if not pats and not opts.get('all'):
3484 raise util.Abort(_('no files or directories specified; '
3487 raise util.Abort(_('no files or directories specified; '
3485 'use --all to revert the whole repo'))
3488 'use --all to revert the whole repo'))
3486
3489
3487 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3490 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3488 node = ctx.node()
3491 node = ctx.node()
3489 mf = ctx.manifest()
3492 mf = ctx.manifest()
3490 if node == parent:
3493 if node == parent:
3491 pmf = mf
3494 pmf = mf
3492 else:
3495 else:
3493 pmf = None
3496 pmf = None
3494
3497
3495 # need all matching names in dirstate and manifest of target rev,
3498 # need all matching names in dirstate and manifest of target rev,
3496 # so have to walk both. do not print errors if files exist in one
3499 # so have to walk both. do not print errors if files exist in one
3497 # but not other.
3500 # but not other.
3498
3501
3499 names = {}
3502 names = {}
3500
3503
3501 wlock = repo.wlock()
3504 wlock = repo.wlock()
3502 try:
3505 try:
3503 # walk dirstate.
3506 # walk dirstate.
3504
3507
3505 m = cmdutil.match(repo, pats, opts)
3508 m = cmdutil.match(repo, pats, opts)
3506 m.bad = lambda x, y: False
3509 m.bad = lambda x, y: False
3507 for abs in repo.walk(m):
3510 for abs in repo.walk(m):
3508 names[abs] = m.rel(abs), m.exact(abs)
3511 names[abs] = m.rel(abs), m.exact(abs)
3509
3512
3510 # walk target manifest.
3513 # walk target manifest.
3511
3514
3512 def badfn(path, msg):
3515 def badfn(path, msg):
3513 if path in names:
3516 if path in names:
3514 return
3517 return
3515 path_ = path + '/'
3518 path_ = path + '/'
3516 for f in names:
3519 for f in names:
3517 if f.startswith(path_):
3520 if f.startswith(path_):
3518 return
3521 return
3519 ui.warn("%s: %s\n" % (m.rel(path), msg))
3522 ui.warn("%s: %s\n" % (m.rel(path), msg))
3520
3523
3521 m = cmdutil.match(repo, pats, opts)
3524 m = cmdutil.match(repo, pats, opts)
3522 m.bad = badfn
3525 m.bad = badfn
3523 for abs in repo[node].walk(m):
3526 for abs in repo[node].walk(m):
3524 if abs not in names:
3527 if abs not in names:
3525 names[abs] = m.rel(abs), m.exact(abs)
3528 names[abs] = m.rel(abs), m.exact(abs)
3526
3529
3527 m = cmdutil.matchfiles(repo, names)
3530 m = cmdutil.matchfiles(repo, names)
3528 changes = repo.status(match=m)[:4]
3531 changes = repo.status(match=m)[:4]
3529 modified, added, removed, deleted = map(set, changes)
3532 modified, added, removed, deleted = map(set, changes)
3530
3533
3531 # if f is a rename, also revert the source
3534 # if f is a rename, also revert the source
3532 cwd = repo.getcwd()
3535 cwd = repo.getcwd()
3533 for f in added:
3536 for f in added:
3534 src = repo.dirstate.copied(f)
3537 src = repo.dirstate.copied(f)
3535 if src and src not in names and repo.dirstate[src] == 'r':
3538 if src and src not in names and repo.dirstate[src] == 'r':
3536 removed.add(src)
3539 removed.add(src)
3537 names[src] = (repo.pathto(src, cwd), True)
3540 names[src] = (repo.pathto(src, cwd), True)
3538
3541
3539 def removeforget(abs):
3542 def removeforget(abs):
3540 if repo.dirstate[abs] == 'a':
3543 if repo.dirstate[abs] == 'a':
3541 return _('forgetting %s\n')
3544 return _('forgetting %s\n')
3542 return _('removing %s\n')
3545 return _('removing %s\n')
3543
3546
3544 revert = ([], _('reverting %s\n'))
3547 revert = ([], _('reverting %s\n'))
3545 add = ([], _('adding %s\n'))
3548 add = ([], _('adding %s\n'))
3546 remove = ([], removeforget)
3549 remove = ([], removeforget)
3547 undelete = ([], _('undeleting %s\n'))
3550 undelete = ([], _('undeleting %s\n'))
3548
3551
3549 disptable = (
3552 disptable = (
3550 # dispatch table:
3553 # dispatch table:
3551 # file state
3554 # file state
3552 # action if in target manifest
3555 # action if in target manifest
3553 # action if not in target manifest
3556 # action if not in target manifest
3554 # make backup if in target manifest
3557 # make backup if in target manifest
3555 # make backup if not in target manifest
3558 # make backup if not in target manifest
3556 (modified, revert, remove, True, True),
3559 (modified, revert, remove, True, True),
3557 (added, revert, remove, True, False),
3560 (added, revert, remove, True, False),
3558 (removed, undelete, None, False, False),
3561 (removed, undelete, None, False, False),
3559 (deleted, revert, remove, False, False),
3562 (deleted, revert, remove, False, False),
3560 )
3563 )
3561
3564
3562 for abs, (rel, exact) in sorted(names.items()):
3565 for abs, (rel, exact) in sorted(names.items()):
3563 mfentry = mf.get(abs)
3566 mfentry = mf.get(abs)
3564 target = repo.wjoin(abs)
3567 target = repo.wjoin(abs)
3565 def handle(xlist, dobackup):
3568 def handle(xlist, dobackup):
3566 xlist[0].append(abs)
3569 xlist[0].append(abs)
3567 if (dobackup and not opts.get('no_backup') and
3570 if (dobackup and not opts.get('no_backup') and
3568 os.path.lexists(target)):
3571 os.path.lexists(target)):
3569 bakname = "%s.orig" % rel
3572 bakname = "%s.orig" % rel
3570 ui.note(_('saving current version of %s as %s\n') %
3573 ui.note(_('saving current version of %s as %s\n') %
3571 (rel, bakname))
3574 (rel, bakname))
3572 if not opts.get('dry_run'):
3575 if not opts.get('dry_run'):
3573 util.rename(target, bakname)
3576 util.rename(target, bakname)
3574 if ui.verbose or not exact:
3577 if ui.verbose or not exact:
3575 msg = xlist[1]
3578 msg = xlist[1]
3576 if not isinstance(msg, basestring):
3579 if not isinstance(msg, basestring):
3577 msg = msg(abs)
3580 msg = msg(abs)
3578 ui.status(msg % rel)
3581 ui.status(msg % rel)
3579 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3582 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3580 if abs not in table:
3583 if abs not in table:
3581 continue
3584 continue
3582 # file has changed in dirstate
3585 # file has changed in dirstate
3583 if mfentry:
3586 if mfentry:
3584 handle(hitlist, backuphit)
3587 handle(hitlist, backuphit)
3585 elif misslist is not None:
3588 elif misslist is not None:
3586 handle(misslist, backupmiss)
3589 handle(misslist, backupmiss)
3587 break
3590 break
3588 else:
3591 else:
3589 if abs not in repo.dirstate:
3592 if abs not in repo.dirstate:
3590 if mfentry:
3593 if mfentry:
3591 handle(add, True)
3594 handle(add, True)
3592 elif exact:
3595 elif exact:
3593 ui.warn(_('file not managed: %s\n') % rel)
3596 ui.warn(_('file not managed: %s\n') % rel)
3594 continue
3597 continue
3595 # file has not changed in dirstate
3598 # file has not changed in dirstate
3596 if node == parent:
3599 if node == parent:
3597 if exact:
3600 if exact:
3598 ui.warn(_('no changes needed to %s\n') % rel)
3601 ui.warn(_('no changes needed to %s\n') % rel)
3599 continue
3602 continue
3600 if pmf is None:
3603 if pmf is None:
3601 # only need parent manifest in this unlikely case,
3604 # only need parent manifest in this unlikely case,
3602 # so do not read by default
3605 # so do not read by default
3603 pmf = repo[parent].manifest()
3606 pmf = repo[parent].manifest()
3604 if abs in pmf:
3607 if abs in pmf:
3605 if mfentry:
3608 if mfentry:
3606 # if version of file is same in parent and target
3609 # if version of file is same in parent and target
3607 # manifests, do nothing
3610 # manifests, do nothing
3608 if (pmf[abs] != mfentry or
3611 if (pmf[abs] != mfentry or
3609 pmf.flags(abs) != mf.flags(abs)):
3612 pmf.flags(abs) != mf.flags(abs)):
3610 handle(revert, False)
3613 handle(revert, False)
3611 else:
3614 else:
3612 handle(remove, False)
3615 handle(remove, False)
3613
3616
3614 if not opts.get('dry_run'):
3617 if not opts.get('dry_run'):
3615 def checkout(f):
3618 def checkout(f):
3616 fc = ctx[f]
3619 fc = ctx[f]
3617 repo.wwrite(f, fc.data(), fc.flags())
3620 repo.wwrite(f, fc.data(), fc.flags())
3618
3621
3619 audit_path = scmutil.path_auditor(repo.root)
3622 audit_path = scmutil.path_auditor(repo.root)
3620 for f in remove[0]:
3623 for f in remove[0]:
3621 if repo.dirstate[f] == 'a':
3624 if repo.dirstate[f] == 'a':
3622 repo.dirstate.forget(f)
3625 repo.dirstate.forget(f)
3623 continue
3626 continue
3624 audit_path(f)
3627 audit_path(f)
3625 try:
3628 try:
3626 util.unlinkpath(repo.wjoin(f))
3629 util.unlinkpath(repo.wjoin(f))
3627 except OSError:
3630 except OSError:
3628 pass
3631 pass
3629 repo.dirstate.remove(f)
3632 repo.dirstate.remove(f)
3630
3633
3631 normal = None
3634 normal = None
3632 if node == parent:
3635 if node == parent:
3633 # We're reverting to our parent. If possible, we'd like status
3636 # We're reverting to our parent. If possible, we'd like status
3634 # to report the file as clean. We have to use normallookup for
3637 # to report the file as clean. We have to use normallookup for
3635 # merges to avoid losing information about merged/dirty files.
3638 # merges to avoid losing information about merged/dirty files.
3636 if p2 != nullid:
3639 if p2 != nullid:
3637 normal = repo.dirstate.normallookup
3640 normal = repo.dirstate.normallookup
3638 else:
3641 else:
3639 normal = repo.dirstate.normal
3642 normal = repo.dirstate.normal
3640 for f in revert[0]:
3643 for f in revert[0]:
3641 checkout(f)
3644 checkout(f)
3642 if normal:
3645 if normal:
3643 normal(f)
3646 normal(f)
3644
3647
3645 for f in add[0]:
3648 for f in add[0]:
3646 checkout(f)
3649 checkout(f)
3647 repo.dirstate.add(f)
3650 repo.dirstate.add(f)
3648
3651
3649 normal = repo.dirstate.normallookup
3652 normal = repo.dirstate.normallookup
3650 if node == parent and p2 == nullid:
3653 if node == parent and p2 == nullid:
3651 normal = repo.dirstate.normal
3654 normal = repo.dirstate.normal
3652 for f in undelete[0]:
3655 for f in undelete[0]:
3653 checkout(f)
3656 checkout(f)
3654 normal(f)
3657 normal(f)
3655
3658
3656 finally:
3659 finally:
3657 wlock.release()
3660 wlock.release()
3658
3661
3659 def rollback(ui, repo, **opts):
3662 def rollback(ui, repo, **opts):
3660 """roll back the last transaction (dangerous)
3663 """roll back the last transaction (dangerous)
3661
3664
3662 This command should be used with care. There is only one level of
3665 This command should be used with care. There is only one level of
3663 rollback, and there is no way to undo a rollback. It will also
3666 rollback, and there is no way to undo a rollback. It will also
3664 restore the dirstate at the time of the last transaction, losing
3667 restore the dirstate at the time of the last transaction, losing
3665 any dirstate changes since that time. This command does not alter
3668 any dirstate changes since that time. This command does not alter
3666 the working directory.
3669 the working directory.
3667
3670
3668 Transactions are used to encapsulate the effects of all commands
3671 Transactions are used to encapsulate the effects of all commands
3669 that create new changesets or propagate existing changesets into a
3672 that create new changesets or propagate existing changesets into a
3670 repository. For example, the following commands are transactional,
3673 repository. For example, the following commands are transactional,
3671 and their effects can be rolled back:
3674 and their effects can be rolled back:
3672
3675
3673 - commit
3676 - commit
3674 - import
3677 - import
3675 - pull
3678 - pull
3676 - push (with this repository as the destination)
3679 - push (with this repository as the destination)
3677 - unbundle
3680 - unbundle
3678
3681
3679 This command is not intended for use on public repositories. Once
3682 This command is not intended for use on public repositories. Once
3680 changes are visible for pull by other users, rolling a transaction
3683 changes are visible for pull by other users, rolling a transaction
3681 back locally is ineffective (someone else may already have pulled
3684 back locally is ineffective (someone else may already have pulled
3682 the changes). Furthermore, a race is possible with readers of the
3685 the changes). Furthermore, a race is possible with readers of the
3683 repository; for example an in-progress pull from the repository
3686 repository; for example an in-progress pull from the repository
3684 may fail if a rollback is performed.
3687 may fail if a rollback is performed.
3685
3688
3686 Returns 0 on success, 1 if no rollback data is available.
3689 Returns 0 on success, 1 if no rollback data is available.
3687 """
3690 """
3688 return repo.rollback(opts.get('dry_run'))
3691 return repo.rollback(opts.get('dry_run'))
3689
3692
3690 def root(ui, repo):
3693 def root(ui, repo):
3691 """print the root (top) of the current working directory
3694 """print the root (top) of the current working directory
3692
3695
3693 Print the root directory of the current repository.
3696 Print the root directory of the current repository.
3694
3697
3695 Returns 0 on success.
3698 Returns 0 on success.
3696 """
3699 """
3697 ui.write(repo.root + "\n")
3700 ui.write(repo.root + "\n")
3698
3701
3699 def serve(ui, repo, **opts):
3702 def serve(ui, repo, **opts):
3700 """start stand-alone webserver
3703 """start stand-alone webserver
3701
3704
3702 Start a local HTTP repository browser and pull server. You can use
3705 Start a local HTTP repository browser and pull server. You can use
3703 this for ad-hoc sharing and browsing of repositories. It is
3706 this for ad-hoc sharing and browsing of repositories. It is
3704 recommended to use a real web server to serve a repository for
3707 recommended to use a real web server to serve a repository for
3705 longer periods of time.
3708 longer periods of time.
3706
3709
3707 Please note that the server does not implement access control.
3710 Please note that the server does not implement access control.
3708 This means that, by default, anybody can read from the server and
3711 This means that, by default, anybody can read from the server and
3709 nobody can write to it by default. Set the ``web.allow_push``
3712 nobody can write to it by default. Set the ``web.allow_push``
3710 option to ``*`` to allow everybody to push to the server. You
3713 option to ``*`` to allow everybody to push to the server. You
3711 should use a real web server if you need to authenticate users.
3714 should use a real web server if you need to authenticate users.
3712
3715
3713 By default, the server logs accesses to stdout and errors to
3716 By default, the server logs accesses to stdout and errors to
3714 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3717 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3715 files.
3718 files.
3716
3719
3717 To have the server choose a free port number to listen on, specify
3720 To have the server choose a free port number to listen on, specify
3718 a port number of 0; in this case, the server will print the port
3721 a port number of 0; in this case, the server will print the port
3719 number it uses.
3722 number it uses.
3720
3723
3721 Returns 0 on success.
3724 Returns 0 on success.
3722 """
3725 """
3723
3726
3724 if opts["stdio"]:
3727 if opts["stdio"]:
3725 if repo is None:
3728 if repo is None:
3726 raise error.RepoError(_("There is no Mercurial repository here"
3729 raise error.RepoError(_("There is no Mercurial repository here"
3727 " (.hg not found)"))
3730 " (.hg not found)"))
3728 s = sshserver.sshserver(ui, repo)
3731 s = sshserver.sshserver(ui, repo)
3729 s.serve_forever()
3732 s.serve_forever()
3730
3733
3731 # this way we can check if something was given in the command-line
3734 # this way we can check if something was given in the command-line
3732 if opts.get('port'):
3735 if opts.get('port'):
3733 opts['port'] = util.getport(opts.get('port'))
3736 opts['port'] = util.getport(opts.get('port'))
3734
3737
3735 baseui = repo and repo.baseui or ui
3738 baseui = repo and repo.baseui or ui
3736 optlist = ("name templates style address port prefix ipv6"
3739 optlist = ("name templates style address port prefix ipv6"
3737 " accesslog errorlog certificate encoding")
3740 " accesslog errorlog certificate encoding")
3738 for o in optlist.split():
3741 for o in optlist.split():
3739 val = opts.get(o, '')
3742 val = opts.get(o, '')
3740 if val in (None, ''): # should check against default options instead
3743 if val in (None, ''): # should check against default options instead
3741 continue
3744 continue
3742 baseui.setconfig("web", o, val)
3745 baseui.setconfig("web", o, val)
3743 if repo and repo.ui != baseui:
3746 if repo and repo.ui != baseui:
3744 repo.ui.setconfig("web", o, val)
3747 repo.ui.setconfig("web", o, val)
3745
3748
3746 o = opts.get('web_conf') or opts.get('webdir_conf')
3749 o = opts.get('web_conf') or opts.get('webdir_conf')
3747 if not o:
3750 if not o:
3748 if not repo:
3751 if not repo:
3749 raise error.RepoError(_("There is no Mercurial repository"
3752 raise error.RepoError(_("There is no Mercurial repository"
3750 " here (.hg not found)"))
3753 " here (.hg not found)"))
3751 o = repo.root
3754 o = repo.root
3752
3755
3753 app = hgweb.hgweb(o, baseui=ui)
3756 app = hgweb.hgweb(o, baseui=ui)
3754
3757
3755 class service(object):
3758 class service(object):
3756 def init(self):
3759 def init(self):
3757 util.set_signal_handler()
3760 util.set_signal_handler()
3758 self.httpd = hgweb.server.create_server(ui, app)
3761 self.httpd = hgweb.server.create_server(ui, app)
3759
3762
3760 if opts['port'] and not ui.verbose:
3763 if opts['port'] and not ui.verbose:
3761 return
3764 return
3762
3765
3763 if self.httpd.prefix:
3766 if self.httpd.prefix:
3764 prefix = self.httpd.prefix.strip('/') + '/'
3767 prefix = self.httpd.prefix.strip('/') + '/'
3765 else:
3768 else:
3766 prefix = ''
3769 prefix = ''
3767
3770
3768 port = ':%d' % self.httpd.port
3771 port = ':%d' % self.httpd.port
3769 if port == ':80':
3772 if port == ':80':
3770 port = ''
3773 port = ''
3771
3774
3772 bindaddr = self.httpd.addr
3775 bindaddr = self.httpd.addr
3773 if bindaddr == '0.0.0.0':
3776 if bindaddr == '0.0.0.0':
3774 bindaddr = '*'
3777 bindaddr = '*'
3775 elif ':' in bindaddr: # IPv6
3778 elif ':' in bindaddr: # IPv6
3776 bindaddr = '[%s]' % bindaddr
3779 bindaddr = '[%s]' % bindaddr
3777
3780
3778 fqaddr = self.httpd.fqaddr
3781 fqaddr = self.httpd.fqaddr
3779 if ':' in fqaddr:
3782 if ':' in fqaddr:
3780 fqaddr = '[%s]' % fqaddr
3783 fqaddr = '[%s]' % fqaddr
3781 if opts['port']:
3784 if opts['port']:
3782 write = ui.status
3785 write = ui.status
3783 else:
3786 else:
3784 write = ui.write
3787 write = ui.write
3785 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3788 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3786 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3789 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3787
3790
3788 def run(self):
3791 def run(self):
3789 self.httpd.serve_forever()
3792 self.httpd.serve_forever()
3790
3793
3791 service = service()
3794 service = service()
3792
3795
3793 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3796 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3794
3797
3795 def status(ui, repo, *pats, **opts):
3798 def status(ui, repo, *pats, **opts):
3796 """show changed files in the working directory
3799 """show changed files in the working directory
3797
3800
3798 Show status of files in the repository. If names are given, only
3801 Show status of files in the repository. If names are given, only
3799 files that match are shown. Files that are clean or ignored or
3802 files that match are shown. Files that are clean or ignored or
3800 the source of a copy/move operation, are not listed unless
3803 the source of a copy/move operation, are not listed unless
3801 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3804 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3802 Unless options described with "show only ..." are given, the
3805 Unless options described with "show only ..." are given, the
3803 options -mardu are used.
3806 options -mardu are used.
3804
3807
3805 Option -q/--quiet hides untracked (unknown and ignored) files
3808 Option -q/--quiet hides untracked (unknown and ignored) files
3806 unless explicitly requested with -u/--unknown or -i/--ignored.
3809 unless explicitly requested with -u/--unknown or -i/--ignored.
3807
3810
3808 .. note::
3811 .. note::
3809 status may appear to disagree with diff if permissions have
3812 status may appear to disagree with diff if permissions have
3810 changed or a merge has occurred. The standard diff format does
3813 changed or a merge has occurred. The standard diff format does
3811 not report permission changes and diff only reports changes
3814 not report permission changes and diff only reports changes
3812 relative to one merge parent.
3815 relative to one merge parent.
3813
3816
3814 If one revision is given, it is used as the base revision.
3817 If one revision is given, it is used as the base revision.
3815 If two revisions are given, the differences between them are
3818 If two revisions are given, the differences between them are
3816 shown. The --change option can also be used as a shortcut to list
3819 shown. The --change option can also be used as a shortcut to list
3817 the changed files of a revision from its first parent.
3820 the changed files of a revision from its first parent.
3818
3821
3819 The codes used to show the status of files are::
3822 The codes used to show the status of files are::
3820
3823
3821 M = modified
3824 M = modified
3822 A = added
3825 A = added
3823 R = removed
3826 R = removed
3824 C = clean
3827 C = clean
3825 ! = missing (deleted by non-hg command, but still tracked)
3828 ! = missing (deleted by non-hg command, but still tracked)
3826 ? = not tracked
3829 ? = not tracked
3827 I = ignored
3830 I = ignored
3828 = origin of the previous file listed as A (added)
3831 = origin of the previous file listed as A (added)
3829
3832
3830 Returns 0 on success.
3833 Returns 0 on success.
3831 """
3834 """
3832
3835
3833 revs = opts.get('rev')
3836 revs = opts.get('rev')
3834 change = opts.get('change')
3837 change = opts.get('change')
3835
3838
3836 if revs and change:
3839 if revs and change:
3837 msg = _('cannot specify --rev and --change at the same time')
3840 msg = _('cannot specify --rev and --change at the same time')
3838 raise util.Abort(msg)
3841 raise util.Abort(msg)
3839 elif change:
3842 elif change:
3840 node2 = repo.lookup(change)
3843 node2 = repo.lookup(change)
3841 node1 = repo[node2].p1().node()
3844 node1 = repo[node2].p1().node()
3842 else:
3845 else:
3843 node1, node2 = cmdutil.revpair(repo, revs)
3846 node1, node2 = cmdutil.revpair(repo, revs)
3844
3847
3845 cwd = (pats and repo.getcwd()) or ''
3848 cwd = (pats and repo.getcwd()) or ''
3846 end = opts.get('print0') and '\0' or '\n'
3849 end = opts.get('print0') and '\0' or '\n'
3847 copy = {}
3850 copy = {}
3848 states = 'modified added removed deleted unknown ignored clean'.split()
3851 states = 'modified added removed deleted unknown ignored clean'.split()
3849 show = [k for k in states if opts.get(k)]
3852 show = [k for k in states if opts.get(k)]
3850 if opts.get('all'):
3853 if opts.get('all'):
3851 show += ui.quiet and (states[:4] + ['clean']) or states
3854 show += ui.quiet and (states[:4] + ['clean']) or states
3852 if not show:
3855 if not show:
3853 show = ui.quiet and states[:4] or states[:5]
3856 show = ui.quiet and states[:4] or states[:5]
3854
3857
3855 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3858 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3856 'ignored' in show, 'clean' in show, 'unknown' in show,
3859 'ignored' in show, 'clean' in show, 'unknown' in show,
3857 opts.get('subrepos'))
3860 opts.get('subrepos'))
3858 changestates = zip(states, 'MAR!?IC', stat)
3861 changestates = zip(states, 'MAR!?IC', stat)
3859
3862
3860 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3863 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3861 ctxn = repo[nullid]
3864 ctxn = repo[nullid]
3862 ctx1 = repo[node1]
3865 ctx1 = repo[node1]
3863 ctx2 = repo[node2]
3866 ctx2 = repo[node2]
3864 added = stat[1]
3867 added = stat[1]
3865 if node2 is None:
3868 if node2 is None:
3866 added = stat[0] + stat[1] # merged?
3869 added = stat[0] + stat[1] # merged?
3867
3870
3868 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3871 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3869 if k in added:
3872 if k in added:
3870 copy[k] = v
3873 copy[k] = v
3871 elif v in added:
3874 elif v in added:
3872 copy[v] = k
3875 copy[v] = k
3873
3876
3874 for state, char, files in changestates:
3877 for state, char, files in changestates:
3875 if state in show:
3878 if state in show:
3876 format = "%s %%s%s" % (char, end)
3879 format = "%s %%s%s" % (char, end)
3877 if opts.get('no_status'):
3880 if opts.get('no_status'):
3878 format = "%%s%s" % end
3881 format = "%%s%s" % end
3879
3882
3880 for f in files:
3883 for f in files:
3881 ui.write(format % repo.pathto(f, cwd),
3884 ui.write(format % repo.pathto(f, cwd),
3882 label='status.' + state)
3885 label='status.' + state)
3883 if f in copy:
3886 if f in copy:
3884 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3887 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3885 label='status.copied')
3888 label='status.copied')
3886
3889
3887 def summary(ui, repo, **opts):
3890 def summary(ui, repo, **opts):
3888 """summarize working directory state
3891 """summarize working directory state
3889
3892
3890 This generates a brief summary of the working directory state,
3893 This generates a brief summary of the working directory state,
3891 including parents, branch, commit status, and available updates.
3894 including parents, branch, commit status, and available updates.
3892
3895
3893 With the --remote option, this will check the default paths for
3896 With the --remote option, this will check the default paths for
3894 incoming and outgoing changes. This can be time-consuming.
3897 incoming and outgoing changes. This can be time-consuming.
3895
3898
3896 Returns 0 on success.
3899 Returns 0 on success.
3897 """
3900 """
3898
3901
3899 ctx = repo[None]
3902 ctx = repo[None]
3900 parents = ctx.parents()
3903 parents = ctx.parents()
3901 pnode = parents[0].node()
3904 pnode = parents[0].node()
3902
3905
3903 for p in parents:
3906 for p in parents:
3904 # label with log.changeset (instead of log.parent) since this
3907 # label with log.changeset (instead of log.parent) since this
3905 # shows a working directory parent *changeset*:
3908 # shows a working directory parent *changeset*:
3906 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3909 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3907 label='log.changeset')
3910 label='log.changeset')
3908 ui.write(' '.join(p.tags()), label='log.tag')
3911 ui.write(' '.join(p.tags()), label='log.tag')
3909 if p.bookmarks():
3912 if p.bookmarks():
3910 ui.write(' ' + ' '.join(p.bookmarks()), label='log.bookmark')
3913 ui.write(' ' + ' '.join(p.bookmarks()), label='log.bookmark')
3911 if p.rev() == -1:
3914 if p.rev() == -1:
3912 if not len(repo):
3915 if not len(repo):
3913 ui.write(_(' (empty repository)'))
3916 ui.write(_(' (empty repository)'))
3914 else:
3917 else:
3915 ui.write(_(' (no revision checked out)'))
3918 ui.write(_(' (no revision checked out)'))
3916 ui.write('\n')
3919 ui.write('\n')
3917 if p.description():
3920 if p.description():
3918 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3921 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3919 label='log.summary')
3922 label='log.summary')
3920
3923
3921 branch = ctx.branch()
3924 branch = ctx.branch()
3922 bheads = repo.branchheads(branch)
3925 bheads = repo.branchheads(branch)
3923 m = _('branch: %s\n') % branch
3926 m = _('branch: %s\n') % branch
3924 if branch != 'default':
3927 if branch != 'default':
3925 ui.write(m, label='log.branch')
3928 ui.write(m, label='log.branch')
3926 else:
3929 else:
3927 ui.status(m, label='log.branch')
3930 ui.status(m, label='log.branch')
3928
3931
3929 st = list(repo.status(unknown=True))[:6]
3932 st = list(repo.status(unknown=True))[:6]
3930
3933
3931 c = repo.dirstate.copies()
3934 c = repo.dirstate.copies()
3932 copied, renamed = [], []
3935 copied, renamed = [], []
3933 for d, s in c.iteritems():
3936 for d, s in c.iteritems():
3934 if s in st[2]:
3937 if s in st[2]:
3935 st[2].remove(s)
3938 st[2].remove(s)
3936 renamed.append(d)
3939 renamed.append(d)
3937 else:
3940 else:
3938 copied.append(d)
3941 copied.append(d)
3939 if d in st[1]:
3942 if d in st[1]:
3940 st[1].remove(d)
3943 st[1].remove(d)
3941 st.insert(3, renamed)
3944 st.insert(3, renamed)
3942 st.insert(4, copied)
3945 st.insert(4, copied)
3943
3946
3944 ms = mergemod.mergestate(repo)
3947 ms = mergemod.mergestate(repo)
3945 st.append([f for f in ms if ms[f] == 'u'])
3948 st.append([f for f in ms if ms[f] == 'u'])
3946
3949
3947 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3950 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3948 st.append(subs)
3951 st.append(subs)
3949
3952
3950 labels = [ui.label(_('%d modified'), 'status.modified'),
3953 labels = [ui.label(_('%d modified'), 'status.modified'),
3951 ui.label(_('%d added'), 'status.added'),
3954 ui.label(_('%d added'), 'status.added'),
3952 ui.label(_('%d removed'), 'status.removed'),
3955 ui.label(_('%d removed'), 'status.removed'),
3953 ui.label(_('%d renamed'), 'status.copied'),
3956 ui.label(_('%d renamed'), 'status.copied'),
3954 ui.label(_('%d copied'), 'status.copied'),
3957 ui.label(_('%d copied'), 'status.copied'),
3955 ui.label(_('%d deleted'), 'status.deleted'),
3958 ui.label(_('%d deleted'), 'status.deleted'),
3956 ui.label(_('%d unknown'), 'status.unknown'),
3959 ui.label(_('%d unknown'), 'status.unknown'),
3957 ui.label(_('%d ignored'), 'status.ignored'),
3960 ui.label(_('%d ignored'), 'status.ignored'),
3958 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3961 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3959 ui.label(_('%d subrepos'), 'status.modified')]
3962 ui.label(_('%d subrepos'), 'status.modified')]
3960 t = []
3963 t = []
3961 for s, l in zip(st, labels):
3964 for s, l in zip(st, labels):
3962 if s:
3965 if s:
3963 t.append(l % len(s))
3966 t.append(l % len(s))
3964
3967
3965 t = ', '.join(t)
3968 t = ', '.join(t)
3966 cleanworkdir = False
3969 cleanworkdir = False
3967
3970
3968 if len(parents) > 1:
3971 if len(parents) > 1:
3969 t += _(' (merge)')
3972 t += _(' (merge)')
3970 elif branch != parents[0].branch():
3973 elif branch != parents[0].branch():
3971 t += _(' (new branch)')
3974 t += _(' (new branch)')
3972 elif (parents[0].extra().get('close') and
3975 elif (parents[0].extra().get('close') and
3973 pnode in repo.branchheads(branch, closed=True)):
3976 pnode in repo.branchheads(branch, closed=True)):
3974 t += _(' (head closed)')
3977 t += _(' (head closed)')
3975 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3978 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3976 t += _(' (clean)')
3979 t += _(' (clean)')
3977 cleanworkdir = True
3980 cleanworkdir = True
3978 elif pnode not in bheads:
3981 elif pnode not in bheads:
3979 t += _(' (new branch head)')
3982 t += _(' (new branch head)')
3980
3983
3981 if cleanworkdir:
3984 if cleanworkdir:
3982 ui.status(_('commit: %s\n') % t.strip())
3985 ui.status(_('commit: %s\n') % t.strip())
3983 else:
3986 else:
3984 ui.write(_('commit: %s\n') % t.strip())
3987 ui.write(_('commit: %s\n') % t.strip())
3985
3988
3986 # all ancestors of branch heads - all ancestors of parent = new csets
3989 # all ancestors of branch heads - all ancestors of parent = new csets
3987 new = [0] * len(repo)
3990 new = [0] * len(repo)
3988 cl = repo.changelog
3991 cl = repo.changelog
3989 for a in [cl.rev(n) for n in bheads]:
3992 for a in [cl.rev(n) for n in bheads]:
3990 new[a] = 1
3993 new[a] = 1
3991 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3994 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3992 new[a] = 1
3995 new[a] = 1
3993 for a in [p.rev() for p in parents]:
3996 for a in [p.rev() for p in parents]:
3994 if a >= 0:
3997 if a >= 0:
3995 new[a] = 0
3998 new[a] = 0
3996 for a in cl.ancestors(*[p.rev() for p in parents]):
3999 for a in cl.ancestors(*[p.rev() for p in parents]):
3997 new[a] = 0
4000 new[a] = 0
3998 new = sum(new)
4001 new = sum(new)
3999
4002
4000 if new == 0:
4003 if new == 0:
4001 ui.status(_('update: (current)\n'))
4004 ui.status(_('update: (current)\n'))
4002 elif pnode not in bheads:
4005 elif pnode not in bheads:
4003 ui.write(_('update: %d new changesets (update)\n') % new)
4006 ui.write(_('update: %d new changesets (update)\n') % new)
4004 else:
4007 else:
4005 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
4008 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
4006 (new, len(bheads)))
4009 (new, len(bheads)))
4007
4010
4008 if opts.get('remote'):
4011 if opts.get('remote'):
4009 t = []
4012 t = []
4010 source, branches = hg.parseurl(ui.expandpath('default'))
4013 source, branches = hg.parseurl(ui.expandpath('default'))
4011 other = hg.repository(hg.remoteui(repo, {}), source)
4014 other = hg.repository(hg.remoteui(repo, {}), source)
4012 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4015 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4013 ui.debug('comparing with %s\n' % util.hidepassword(source))
4016 ui.debug('comparing with %s\n' % util.hidepassword(source))
4014 repo.ui.pushbuffer()
4017 repo.ui.pushbuffer()
4015 common, incoming, rheads = discovery.findcommonincoming(repo, other)
4018 common, incoming, rheads = discovery.findcommonincoming(repo, other)
4016 repo.ui.popbuffer()
4019 repo.ui.popbuffer()
4017 if incoming:
4020 if incoming:
4018 t.append(_('1 or more incoming'))
4021 t.append(_('1 or more incoming'))
4019
4022
4020 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
4023 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
4021 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
4024 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
4022 other = hg.repository(hg.remoteui(repo, {}), dest)
4025 other = hg.repository(hg.remoteui(repo, {}), dest)
4023 ui.debug('comparing with %s\n' % util.hidepassword(dest))
4026 ui.debug('comparing with %s\n' % util.hidepassword(dest))
4024 repo.ui.pushbuffer()
4027 repo.ui.pushbuffer()
4025 common, _anyinc, _heads = discovery.findcommonincoming(repo, other)
4028 common, _anyinc, _heads = discovery.findcommonincoming(repo, other)
4026 repo.ui.popbuffer()
4029 repo.ui.popbuffer()
4027 o = repo.changelog.findmissing(common=common)
4030 o = repo.changelog.findmissing(common=common)
4028 if o:
4031 if o:
4029 t.append(_('%d outgoing') % len(o))
4032 t.append(_('%d outgoing') % len(o))
4030 if 'bookmarks' in other.listkeys('namespaces'):
4033 if 'bookmarks' in other.listkeys('namespaces'):
4031 lmarks = repo.listkeys('bookmarks')
4034 lmarks = repo.listkeys('bookmarks')
4032 rmarks = other.listkeys('bookmarks')
4035 rmarks = other.listkeys('bookmarks')
4033 diff = set(rmarks) - set(lmarks)
4036 diff = set(rmarks) - set(lmarks)
4034 if len(diff) > 0:
4037 if len(diff) > 0:
4035 t.append(_('%d incoming bookmarks') % len(diff))
4038 t.append(_('%d incoming bookmarks') % len(diff))
4036 diff = set(lmarks) - set(rmarks)
4039 diff = set(lmarks) - set(rmarks)
4037 if len(diff) > 0:
4040 if len(diff) > 0:
4038 t.append(_('%d outgoing bookmarks') % len(diff))
4041 t.append(_('%d outgoing bookmarks') % len(diff))
4039
4042
4040 if t:
4043 if t:
4041 ui.write(_('remote: %s\n') % (', '.join(t)))
4044 ui.write(_('remote: %s\n') % (', '.join(t)))
4042 else:
4045 else:
4043 ui.status(_('remote: (synced)\n'))
4046 ui.status(_('remote: (synced)\n'))
4044
4047
4045 def tag(ui, repo, name1, *names, **opts):
4048 def tag(ui, repo, name1, *names, **opts):
4046 """add one or more tags for the current or given revision
4049 """add one or more tags for the current or given revision
4047
4050
4048 Name a particular revision using <name>.
4051 Name a particular revision using <name>.
4049
4052
4050 Tags are used to name particular revisions of the repository and are
4053 Tags are used to name particular revisions of the repository and are
4051 very useful to compare different revisions, to go back to significant
4054 very useful to compare different revisions, to go back to significant
4052 earlier versions or to mark branch points as releases, etc. Changing
4055 earlier versions or to mark branch points as releases, etc. Changing
4053 an existing tag is normally disallowed; use -f/--force to override.
4056 an existing tag is normally disallowed; use -f/--force to override.
4054
4057
4055 If no revision is given, the parent of the working directory is
4058 If no revision is given, the parent of the working directory is
4056 used, or tip if no revision is checked out.
4059 used, or tip if no revision is checked out.
4057
4060
4058 To facilitate version control, distribution, and merging of tags,
4061 To facilitate version control, distribution, and merging of tags,
4059 they are stored as a file named ".hgtags" which is managed similarly
4062 they are stored as a file named ".hgtags" which is managed similarly
4060 to other project files and can be hand-edited if necessary. This
4063 to other project files and can be hand-edited if necessary. This
4061 also means that tagging creates a new commit. The file
4064 also means that tagging creates a new commit. The file
4062 ".hg/localtags" is used for local tags (not shared among
4065 ".hg/localtags" is used for local tags (not shared among
4063 repositories).
4066 repositories).
4064
4067
4065 Tag commits are usually made at the head of a branch. If the parent
4068 Tag commits are usually made at the head of a branch. If the parent
4066 of the working directory is not a branch head, :hg:`tag` aborts; use
4069 of the working directory is not a branch head, :hg:`tag` aborts; use
4067 -f/--force to force the tag commit to be based on a non-head
4070 -f/--force to force the tag commit to be based on a non-head
4068 changeset.
4071 changeset.
4069
4072
4070 See :hg:`help dates` for a list of formats valid for -d/--date.
4073 See :hg:`help dates` for a list of formats valid for -d/--date.
4071
4074
4072 Since tag names have priority over branch names during revision
4075 Since tag names have priority over branch names during revision
4073 lookup, using an existing branch name as a tag name is discouraged.
4076 lookup, using an existing branch name as a tag name is discouraged.
4074
4077
4075 Returns 0 on success.
4078 Returns 0 on success.
4076 """
4079 """
4077
4080
4078 rev_ = "."
4081 rev_ = "."
4079 names = [t.strip() for t in (name1,) + names]
4082 names = [t.strip() for t in (name1,) + names]
4080 if len(names) != len(set(names)):
4083 if len(names) != len(set(names)):
4081 raise util.Abort(_('tag names must be unique'))
4084 raise util.Abort(_('tag names must be unique'))
4082 for n in names:
4085 for n in names:
4083 if n in ['tip', '.', 'null']:
4086 if n in ['tip', '.', 'null']:
4084 raise util.Abort(_('the name \'%s\' is reserved') % n)
4087 raise util.Abort(_('the name \'%s\' is reserved') % n)
4085 if not n:
4088 if not n:
4086 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
4089 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
4087 if opts.get('rev') and opts.get('remove'):
4090 if opts.get('rev') and opts.get('remove'):
4088 raise util.Abort(_("--rev and --remove are incompatible"))
4091 raise util.Abort(_("--rev and --remove are incompatible"))
4089 if opts.get('rev'):
4092 if opts.get('rev'):
4090 rev_ = opts['rev']
4093 rev_ = opts['rev']
4091 message = opts.get('message')
4094 message = opts.get('message')
4092 if opts.get('remove'):
4095 if opts.get('remove'):
4093 expectedtype = opts.get('local') and 'local' or 'global'
4096 expectedtype = opts.get('local') and 'local' or 'global'
4094 for n in names:
4097 for n in names:
4095 if not repo.tagtype(n):
4098 if not repo.tagtype(n):
4096 raise util.Abort(_('tag \'%s\' does not exist') % n)
4099 raise util.Abort(_('tag \'%s\' does not exist') % n)
4097 if repo.tagtype(n) != expectedtype:
4100 if repo.tagtype(n) != expectedtype:
4098 if expectedtype == 'global':
4101 if expectedtype == 'global':
4099 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
4102 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
4100 else:
4103 else:
4101 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
4104 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
4102 rev_ = nullid
4105 rev_ = nullid
4103 if not message:
4106 if not message:
4104 # we don't translate commit messages
4107 # we don't translate commit messages
4105 message = 'Removed tag %s' % ', '.join(names)
4108 message = 'Removed tag %s' % ', '.join(names)
4106 elif not opts.get('force'):
4109 elif not opts.get('force'):
4107 for n in names:
4110 for n in names:
4108 if n in repo.tags():
4111 if n in repo.tags():
4109 raise util.Abort(_('tag \'%s\' already exists '
4112 raise util.Abort(_('tag \'%s\' already exists '
4110 '(use -f to force)') % n)
4113 '(use -f to force)') % n)
4111 if not opts.get('local'):
4114 if not opts.get('local'):
4112 p1, p2 = repo.dirstate.parents()
4115 p1, p2 = repo.dirstate.parents()
4113 if p2 != nullid:
4116 if p2 != nullid:
4114 raise util.Abort(_('uncommitted merge'))
4117 raise util.Abort(_('uncommitted merge'))
4115 bheads = repo.branchheads()
4118 bheads = repo.branchheads()
4116 if not opts.get('force') and bheads and p1 not in bheads:
4119 if not opts.get('force') and bheads and p1 not in bheads:
4117 raise util.Abort(_('not at a branch head (use -f to force)'))
4120 raise util.Abort(_('not at a branch head (use -f to force)'))
4118 r = cmdutil.revsingle(repo, rev_).node()
4121 r = cmdutil.revsingle(repo, rev_).node()
4119
4122
4120 if not message:
4123 if not message:
4121 # we don't translate commit messages
4124 # we don't translate commit messages
4122 message = ('Added tag %s for changeset %s' %
4125 message = ('Added tag %s for changeset %s' %
4123 (', '.join(names), short(r)))
4126 (', '.join(names), short(r)))
4124
4127
4125 date = opts.get('date')
4128 date = opts.get('date')
4126 if date:
4129 if date:
4127 date = util.parsedate(date)
4130 date = util.parsedate(date)
4128
4131
4129 if opts.get('edit'):
4132 if opts.get('edit'):
4130 message = ui.edit(message, ui.username())
4133 message = ui.edit(message, ui.username())
4131
4134
4132 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
4135 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
4133
4136
4134 def tags(ui, repo):
4137 def tags(ui, repo):
4135 """list repository tags
4138 """list repository tags
4136
4139
4137 This lists both regular and local tags. When the -v/--verbose
4140 This lists both regular and local tags. When the -v/--verbose
4138 switch is used, a third column "local" is printed for local tags.
4141 switch is used, a third column "local" is printed for local tags.
4139
4142
4140 Returns 0 on success.
4143 Returns 0 on success.
4141 """
4144 """
4142
4145
4143 hexfunc = ui.debugflag and hex or short
4146 hexfunc = ui.debugflag and hex or short
4144 tagtype = ""
4147 tagtype = ""
4145
4148
4146 for t, n in reversed(repo.tagslist()):
4149 for t, n in reversed(repo.tagslist()):
4147 if ui.quiet:
4150 if ui.quiet:
4148 ui.write("%s\n" % t)
4151 ui.write("%s\n" % t)
4149 continue
4152 continue
4150
4153
4151 hn = hexfunc(n)
4154 hn = hexfunc(n)
4152 r = "%5d:%s" % (repo.changelog.rev(n), hn)
4155 r = "%5d:%s" % (repo.changelog.rev(n), hn)
4153 spaces = " " * (30 - encoding.colwidth(t))
4156 spaces = " " * (30 - encoding.colwidth(t))
4154
4157
4155 if ui.verbose:
4158 if ui.verbose:
4156 if repo.tagtype(t) == 'local':
4159 if repo.tagtype(t) == 'local':
4157 tagtype = " local"
4160 tagtype = " local"
4158 else:
4161 else:
4159 tagtype = ""
4162 tagtype = ""
4160 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
4163 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
4161
4164
4162 def tip(ui, repo, **opts):
4165 def tip(ui, repo, **opts):
4163 """show the tip revision
4166 """show the tip revision
4164
4167
4165 The tip revision (usually just called the tip) is the changeset
4168 The tip revision (usually just called the tip) is the changeset
4166 most recently added to the repository (and therefore the most
4169 most recently added to the repository (and therefore the most
4167 recently changed head).
4170 recently changed head).
4168
4171
4169 If you have just made a commit, that commit will be the tip. If
4172 If you have just made a commit, that commit will be the tip. If
4170 you have just pulled changes from another repository, the tip of
4173 you have just pulled changes from another repository, the tip of
4171 that repository becomes the current tip. The "tip" tag is special
4174 that repository becomes the current tip. The "tip" tag is special
4172 and cannot be renamed or assigned to a different changeset.
4175 and cannot be renamed or assigned to a different changeset.
4173
4176
4174 Returns 0 on success.
4177 Returns 0 on success.
4175 """
4178 """
4176 displayer = cmdutil.show_changeset(ui, repo, opts)
4179 displayer = cmdutil.show_changeset(ui, repo, opts)
4177 displayer.show(repo[len(repo) - 1])
4180 displayer.show(repo[len(repo) - 1])
4178 displayer.close()
4181 displayer.close()
4179
4182
4180 def unbundle(ui, repo, fname1, *fnames, **opts):
4183 def unbundle(ui, repo, fname1, *fnames, **opts):
4181 """apply one or more changegroup files
4184 """apply one or more changegroup files
4182
4185
4183 Apply one or more compressed changegroup files generated by the
4186 Apply one or more compressed changegroup files generated by the
4184 bundle command.
4187 bundle command.
4185
4188
4186 Returns 0 on success, 1 if an update has unresolved files.
4189 Returns 0 on success, 1 if an update has unresolved files.
4187 """
4190 """
4188 fnames = (fname1,) + fnames
4191 fnames = (fname1,) + fnames
4189
4192
4190 lock = repo.lock()
4193 lock = repo.lock()
4191 wc = repo['.']
4194 wc = repo['.']
4192 try:
4195 try:
4193 for fname in fnames:
4196 for fname in fnames:
4194 f = url.open(ui, fname)
4197 f = url.open(ui, fname)
4195 gen = changegroup.readbundle(f, fname)
4198 gen = changegroup.readbundle(f, fname)
4196 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
4199 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
4197 lock=lock)
4200 lock=lock)
4198 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
4201 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
4199 finally:
4202 finally:
4200 lock.release()
4203 lock.release()
4201 return postincoming(ui, repo, modheads, opts.get('update'), None)
4204 return postincoming(ui, repo, modheads, opts.get('update'), None)
4202
4205
4203 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
4206 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
4204 """update working directory (or switch revisions)
4207 """update working directory (or switch revisions)
4205
4208
4206 Update the repository's working directory to the specified
4209 Update the repository's working directory to the specified
4207 changeset. If no changeset is specified, update to the tip of the
4210 changeset. If no changeset is specified, update to the tip of the
4208 current named branch.
4211 current named branch.
4209
4212
4210 If the changeset is not a descendant of the working directory's
4213 If the changeset is not a descendant of the working directory's
4211 parent, the update is aborted. With the -c/--check option, the
4214 parent, the update is aborted. With the -c/--check option, the
4212 working directory is checked for uncommitted changes; if none are
4215 working directory is checked for uncommitted changes; if none are
4213 found, the working directory is updated to the specified
4216 found, the working directory is updated to the specified
4214 changeset.
4217 changeset.
4215
4218
4216 The following rules apply when the working directory contains
4219 The following rules apply when the working directory contains
4217 uncommitted changes:
4220 uncommitted changes:
4218
4221
4219 1. If neither -c/--check nor -C/--clean is specified, and if
4222 1. If neither -c/--check nor -C/--clean is specified, and if
4220 the requested changeset is an ancestor or descendant of
4223 the requested changeset is an ancestor or descendant of
4221 the working directory's parent, the uncommitted changes
4224 the working directory's parent, the uncommitted changes
4222 are merged into the requested changeset and the merged
4225 are merged into the requested changeset and the merged
4223 result is left uncommitted. If the requested changeset is
4226 result is left uncommitted. If the requested changeset is
4224 not an ancestor or descendant (that is, it is on another
4227 not an ancestor or descendant (that is, it is on another
4225 branch), the update is aborted and the uncommitted changes
4228 branch), the update is aborted and the uncommitted changes
4226 are preserved.
4229 are preserved.
4227
4230
4228 2. With the -c/--check option, the update is aborted and the
4231 2. With the -c/--check option, the update is aborted and the
4229 uncommitted changes are preserved.
4232 uncommitted changes are preserved.
4230
4233
4231 3. With the -C/--clean option, uncommitted changes are discarded and
4234 3. With the -C/--clean option, uncommitted changes are discarded and
4232 the working directory is updated to the requested changeset.
4235 the working directory is updated to the requested changeset.
4233
4236
4234 Use null as the changeset to remove the working directory (like
4237 Use null as the changeset to remove the working directory (like
4235 :hg:`clone -U`).
4238 :hg:`clone -U`).
4236
4239
4237 If you want to update just one file to an older changeset, use
4240 If you want to update just one file to an older changeset, use
4238 :hg:`revert`.
4241 :hg:`revert`.
4239
4242
4240 See :hg:`help dates` for a list of formats valid for -d/--date.
4243 See :hg:`help dates` for a list of formats valid for -d/--date.
4241
4244
4242 Returns 0 on success, 1 if there are unresolved files.
4245 Returns 0 on success, 1 if there are unresolved files.
4243 """
4246 """
4244 if rev and node:
4247 if rev and node:
4245 raise util.Abort(_("please specify just one revision"))
4248 raise util.Abort(_("please specify just one revision"))
4246
4249
4247 if rev is None or rev == '':
4250 if rev is None or rev == '':
4248 rev = node
4251 rev = node
4249
4252
4250 # if we defined a bookmark, we have to remember the original bookmark name
4253 # if we defined a bookmark, we have to remember the original bookmark name
4251 brev = rev
4254 brev = rev
4252 rev = cmdutil.revsingle(repo, rev, rev).rev()
4255 rev = cmdutil.revsingle(repo, rev, rev).rev()
4253
4256
4254 if check and clean:
4257 if check and clean:
4255 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4258 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4256
4259
4257 if check:
4260 if check:
4258 # we could use dirty() but we can ignore merge and branch trivia
4261 # we could use dirty() but we can ignore merge and branch trivia
4259 c = repo[None]
4262 c = repo[None]
4260 if c.modified() or c.added() or c.removed():
4263 if c.modified() or c.added() or c.removed():
4261 raise util.Abort(_("uncommitted local changes"))
4264 raise util.Abort(_("uncommitted local changes"))
4262
4265
4263 if date:
4266 if date:
4264 if rev is not None:
4267 if rev is not None:
4265 raise util.Abort(_("you can't specify a revision and a date"))
4268 raise util.Abort(_("you can't specify a revision and a date"))
4266 rev = cmdutil.finddate(ui, repo, date)
4269 rev = cmdutil.finddate(ui, repo, date)
4267
4270
4268 if clean or check:
4271 if clean or check:
4269 ret = hg.clean(repo, rev)
4272 ret = hg.clean(repo, rev)
4270 else:
4273 else:
4271 ret = hg.update(repo, rev)
4274 ret = hg.update(repo, rev)
4272
4275
4273 if brev in repo._bookmarks:
4276 if brev in repo._bookmarks:
4274 bookmarks.setcurrent(repo, brev)
4277 bookmarks.setcurrent(repo, brev)
4275
4278
4276 return ret
4279 return ret
4277
4280
4278 def verify(ui, repo):
4281 def verify(ui, repo):
4279 """verify the integrity of the repository
4282 """verify the integrity of the repository
4280
4283
4281 Verify the integrity of the current repository.
4284 Verify the integrity of the current repository.
4282
4285
4283 This will perform an extensive check of the repository's
4286 This will perform an extensive check of the repository's
4284 integrity, validating the hashes and checksums of each entry in
4287 integrity, validating the hashes and checksums of each entry in
4285 the changelog, manifest, and tracked files, as well as the
4288 the changelog, manifest, and tracked files, as well as the
4286 integrity of their crosslinks and indices.
4289 integrity of their crosslinks and indices.
4287
4290
4288 Returns 0 on success, 1 if errors are encountered.
4291 Returns 0 on success, 1 if errors are encountered.
4289 """
4292 """
4290 return hg.verify(repo)
4293 return hg.verify(repo)
4291
4294
4292 def version_(ui):
4295 def version_(ui):
4293 """output version and copyright information"""
4296 """output version and copyright information"""
4294 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4297 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4295 % util.version())
4298 % util.version())
4296 ui.status(_(
4299 ui.status(_(
4297 "(see http://mercurial.selenic.com for more information)\n"
4300 "(see http://mercurial.selenic.com for more information)\n"
4298 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
4301 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
4299 "This is free software; see the source for copying conditions. "
4302 "This is free software; see the source for copying conditions. "
4300 "There is NO\nwarranty; "
4303 "There is NO\nwarranty; "
4301 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4304 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4302 ))
4305 ))
4303
4306
4304 # Command options and aliases are listed here, alphabetically
4307 # Command options and aliases are listed here, alphabetically
4305
4308
4306 globalopts = [
4309 globalopts = [
4307 ('R', 'repository', '',
4310 ('R', 'repository', '',
4308 _('repository root directory or name of overlay bundle file'),
4311 _('repository root directory or name of overlay bundle file'),
4309 _('REPO')),
4312 _('REPO')),
4310 ('', 'cwd', '',
4313 ('', 'cwd', '',
4311 _('change working directory'), _('DIR')),
4314 _('change working directory'), _('DIR')),
4312 ('y', 'noninteractive', None,
4315 ('y', 'noninteractive', None,
4313 _('do not prompt, assume \'yes\' for any required answers')),
4316 _('do not prompt, assume \'yes\' for any required answers')),
4314 ('q', 'quiet', None, _('suppress output')),
4317 ('q', 'quiet', None, _('suppress output')),
4315 ('v', 'verbose', None, _('enable additional output')),
4318 ('v', 'verbose', None, _('enable additional output')),
4316 ('', 'config', [],
4319 ('', 'config', [],
4317 _('set/override config option (use \'section.name=value\')'),
4320 _('set/override config option (use \'section.name=value\')'),
4318 _('CONFIG')),
4321 _('CONFIG')),
4319 ('', 'debug', None, _('enable debugging output')),
4322 ('', 'debug', None, _('enable debugging output')),
4320 ('', 'debugger', None, _('start debugger')),
4323 ('', 'debugger', None, _('start debugger')),
4321 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4324 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4322 _('ENCODE')),
4325 _('ENCODE')),
4323 ('', 'encodingmode', encoding.encodingmode,
4326 ('', 'encodingmode', encoding.encodingmode,
4324 _('set the charset encoding mode'), _('MODE')),
4327 _('set the charset encoding mode'), _('MODE')),
4325 ('', 'traceback', None, _('always print a traceback on exception')),
4328 ('', 'traceback', None, _('always print a traceback on exception')),
4326 ('', 'time', None, _('time how long the command takes')),
4329 ('', 'time', None, _('time how long the command takes')),
4327 ('', 'profile', None, _('print command execution profile')),
4330 ('', 'profile', None, _('print command execution profile')),
4328 ('', 'version', None, _('output version information and exit')),
4331 ('', 'version', None, _('output version information and exit')),
4329 ('h', 'help', None, _('display help and exit')),
4332 ('h', 'help', None, _('display help and exit')),
4330 ]
4333 ]
4331
4334
4332 dryrunopts = [('n', 'dry-run', None,
4335 dryrunopts = [('n', 'dry-run', None,
4333 _('do not perform actions, just print output'))]
4336 _('do not perform actions, just print output'))]
4334
4337
4335 remoteopts = [
4338 remoteopts = [
4336 ('e', 'ssh', '',
4339 ('e', 'ssh', '',
4337 _('specify ssh command to use'), _('CMD')),
4340 _('specify ssh command to use'), _('CMD')),
4338 ('', 'remotecmd', '',
4341 ('', 'remotecmd', '',
4339 _('specify hg command to run on the remote side'), _('CMD')),
4342 _('specify hg command to run on the remote side'), _('CMD')),
4340 ('', 'insecure', None,
4343 ('', 'insecure', None,
4341 _('do not verify server certificate (ignoring web.cacerts config)')),
4344 _('do not verify server certificate (ignoring web.cacerts config)')),
4342 ]
4345 ]
4343
4346
4344 walkopts = [
4347 walkopts = [
4345 ('I', 'include', [],
4348 ('I', 'include', [],
4346 _('include names matching the given patterns'), _('PATTERN')),
4349 _('include names matching the given patterns'), _('PATTERN')),
4347 ('X', 'exclude', [],
4350 ('X', 'exclude', [],
4348 _('exclude names matching the given patterns'), _('PATTERN')),
4351 _('exclude names matching the given patterns'), _('PATTERN')),
4349 ]
4352 ]
4350
4353
4351 commitopts = [
4354 commitopts = [
4352 ('m', 'message', '',
4355 ('m', 'message', '',
4353 _('use text as commit message'), _('TEXT')),
4356 _('use text as commit message'), _('TEXT')),
4354 ('l', 'logfile', '',
4357 ('l', 'logfile', '',
4355 _('read commit message from file'), _('FILE')),
4358 _('read commit message from file'), _('FILE')),
4356 ]
4359 ]
4357
4360
4358 commitopts2 = [
4361 commitopts2 = [
4359 ('d', 'date', '',
4362 ('d', 'date', '',
4360 _('record the specified date as commit date'), _('DATE')),
4363 _('record the specified date as commit date'), _('DATE')),
4361 ('u', 'user', '',
4364 ('u', 'user', '',
4362 _('record the specified user as committer'), _('USER')),
4365 _('record the specified user as committer'), _('USER')),
4363 ]
4366 ]
4364
4367
4365 templateopts = [
4368 templateopts = [
4366 ('', 'style', '',
4369 ('', 'style', '',
4367 _('display using template map file'), _('STYLE')),
4370 _('display using template map file'), _('STYLE')),
4368 ('', 'template', '',
4371 ('', 'template', '',
4369 _('display with template'), _('TEMPLATE')),
4372 _('display with template'), _('TEMPLATE')),
4370 ]
4373 ]
4371
4374
4372 logopts = [
4375 logopts = [
4373 ('p', 'patch', None, _('show patch')),
4376 ('p', 'patch', None, _('show patch')),
4374 ('g', 'git', None, _('use git extended diff format')),
4377 ('g', 'git', None, _('use git extended diff format')),
4375 ('l', 'limit', '',
4378 ('l', 'limit', '',
4376 _('limit number of changes displayed'), _('NUM')),
4379 _('limit number of changes displayed'), _('NUM')),
4377 ('M', 'no-merges', None, _('do not show merges')),
4380 ('M', 'no-merges', None, _('do not show merges')),
4378 ('', 'stat', None, _('output diffstat-style summary of changes')),
4381 ('', 'stat', None, _('output diffstat-style summary of changes')),
4379 ] + templateopts
4382 ] + templateopts
4380
4383
4381 diffopts = [
4384 diffopts = [
4382 ('a', 'text', None, _('treat all files as text')),
4385 ('a', 'text', None, _('treat all files as text')),
4383 ('g', 'git', None, _('use git extended diff format')),
4386 ('g', 'git', None, _('use git extended diff format')),
4384 ('', 'nodates', None, _('omit dates from diff headers'))
4387 ('', 'nodates', None, _('omit dates from diff headers'))
4385 ]
4388 ]
4386
4389
4387 diffopts2 = [
4390 diffopts2 = [
4388 ('p', 'show-function', None, _('show which function each change is in')),
4391 ('p', 'show-function', None, _('show which function each change is in')),
4389 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4392 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4390 ('w', 'ignore-all-space', None,
4393 ('w', 'ignore-all-space', None,
4391 _('ignore white space when comparing lines')),
4394 _('ignore white space when comparing lines')),
4392 ('b', 'ignore-space-change', None,
4395 ('b', 'ignore-space-change', None,
4393 _('ignore changes in the amount of white space')),
4396 _('ignore changes in the amount of white space')),
4394 ('B', 'ignore-blank-lines', None,
4397 ('B', 'ignore-blank-lines', None,
4395 _('ignore changes whose lines are all blank')),
4398 _('ignore changes whose lines are all blank')),
4396 ('U', 'unified', '',
4399 ('U', 'unified', '',
4397 _('number of lines of context to show'), _('NUM')),
4400 _('number of lines of context to show'), _('NUM')),
4398 ('', 'stat', None, _('output diffstat-style summary of changes')),
4401 ('', 'stat', None, _('output diffstat-style summary of changes')),
4399 ]
4402 ]
4400
4403
4401 similarityopts = [
4404 similarityopts = [
4402 ('s', 'similarity', '',
4405 ('s', 'similarity', '',
4403 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4406 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4404 ]
4407 ]
4405
4408
4406 subrepoopts = [
4409 subrepoopts = [
4407 ('S', 'subrepos', None,
4410 ('S', 'subrepos', None,
4408 _('recurse into subrepositories'))
4411 _('recurse into subrepositories'))
4409 ]
4412 ]
4410
4413
4411 table = {
4414 table = {
4412 "^add": (add, walkopts + subrepoopts + dryrunopts,
4415 "^add": (add, walkopts + subrepoopts + dryrunopts,
4413 _('[OPTION]... [FILE]...')),
4416 _('[OPTION]... [FILE]...')),
4414 "addremove":
4417 "addremove":
4415 (addremove, similarityopts + walkopts + dryrunopts,
4418 (addremove, similarityopts + walkopts + dryrunopts,
4416 _('[OPTION]... [FILE]...')),
4419 _('[OPTION]... [FILE]...')),
4417 "^annotate|blame":
4420 "^annotate|blame":
4418 (annotate,
4421 (annotate,
4419 [('r', 'rev', '',
4422 [('r', 'rev', '',
4420 _('annotate the specified revision'), _('REV')),
4423 _('annotate the specified revision'), _('REV')),
4421 ('', 'follow', None,
4424 ('', 'follow', None,
4422 _('follow copies/renames and list the filename (DEPRECATED)')),
4425 _('follow copies/renames and list the filename (DEPRECATED)')),
4423 ('', 'no-follow', None, _("don't follow copies and renames")),
4426 ('', 'no-follow', None, _("don't follow copies and renames")),
4424 ('a', 'text', None, _('treat all files as text')),
4427 ('a', 'text', None, _('treat all files as text')),
4425 ('u', 'user', None, _('list the author (long with -v)')),
4428 ('u', 'user', None, _('list the author (long with -v)')),
4426 ('f', 'file', None, _('list the filename')),
4429 ('f', 'file', None, _('list the filename')),
4427 ('d', 'date', None, _('list the date (short with -q)')),
4430 ('d', 'date', None, _('list the date (short with -q)')),
4428 ('n', 'number', None, _('list the revision number (default)')),
4431 ('n', 'number', None, _('list the revision number (default)')),
4429 ('c', 'changeset', None, _('list the changeset')),
4432 ('c', 'changeset', None, _('list the changeset')),
4430 ('l', 'line-number', None,
4433 ('l', 'line-number', None,
4431 _('show line number at the first appearance'))
4434 _('show line number at the first appearance'))
4432 ] + walkopts,
4435 ] + walkopts,
4433 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4436 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4434 "archive":
4437 "archive":
4435 (archive,
4438 (archive,
4436 [('', 'no-decode', None, _('do not pass files through decoders')),
4439 [('', 'no-decode', None, _('do not pass files through decoders')),
4437 ('p', 'prefix', '',
4440 ('p', 'prefix', '',
4438 _('directory prefix for files in archive'), _('PREFIX')),
4441 _('directory prefix for files in archive'), _('PREFIX')),
4439 ('r', 'rev', '',
4442 ('r', 'rev', '',
4440 _('revision to distribute'), _('REV')),
4443 _('revision to distribute'), _('REV')),
4441 ('t', 'type', '',
4444 ('t', 'type', '',
4442 _('type of distribution to create'), _('TYPE')),
4445 _('type of distribution to create'), _('TYPE')),
4443 ] + subrepoopts + walkopts,
4446 ] + subrepoopts + walkopts,
4444 _('[OPTION]... DEST')),
4447 _('[OPTION]... DEST')),
4445 "backout":
4448 "backout":
4446 (backout,
4449 (backout,
4447 [('', 'merge', None,
4450 [('', 'merge', None,
4448 _('merge with old dirstate parent after backout')),
4451 _('merge with old dirstate parent after backout')),
4449 ('', 'parent', '',
4452 ('', 'parent', '',
4450 _('parent to choose when backing out merge'), _('REV')),
4453 _('parent to choose when backing out merge'), _('REV')),
4451 ('t', 'tool', '',
4454 ('t', 'tool', '',
4452 _('specify merge tool')),
4455 _('specify merge tool')),
4453 ('r', 'rev', '',
4456 ('r', 'rev', '',
4454 _('revision to backout'), _('REV')),
4457 _('revision to backout'), _('REV')),
4455 ] + walkopts + commitopts + commitopts2,
4458 ] + walkopts + commitopts + commitopts2,
4456 _('[OPTION]... [-r] REV')),
4459 _('[OPTION]... [-r] REV')),
4457 "bisect":
4460 "bisect":
4458 (bisect,
4461 (bisect,
4459 [('r', 'reset', False, _('reset bisect state')),
4462 [('r', 'reset', False, _('reset bisect state')),
4460 ('g', 'good', False, _('mark changeset good')),
4463 ('g', 'good', False, _('mark changeset good')),
4461 ('b', 'bad', False, _('mark changeset bad')),
4464 ('b', 'bad', False, _('mark changeset bad')),
4462 ('s', 'skip', False, _('skip testing changeset')),
4465 ('s', 'skip', False, _('skip testing changeset')),
4463 ('e', 'extend', False, _('extend the bisect range')),
4466 ('e', 'extend', False, _('extend the bisect range')),
4464 ('c', 'command', '',
4467 ('c', 'command', '',
4465 _('use command to check changeset state'), _('CMD')),
4468 _('use command to check changeset state'), _('CMD')),
4466 ('U', 'noupdate', False, _('do not update to target'))],
4469 ('U', 'noupdate', False, _('do not update to target'))],
4467 _("[-gbsr] [-U] [-c CMD] [REV]")),
4470 _("[-gbsr] [-U] [-c CMD] [REV]")),
4468 "bookmarks":
4471 "bookmarks":
4469 (bookmark,
4472 (bookmark,
4470 [('f', 'force', False, _('force')),
4473 [('f', 'force', False, _('force')),
4471 ('r', 'rev', '', _('revision'), _('REV')),
4474 ('r', 'rev', '', _('revision'), _('REV')),
4472 ('d', 'delete', False, _('delete a given bookmark')),
4475 ('d', 'delete', False, _('delete a given bookmark')),
4473 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
4476 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
4474 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
4477 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
4475 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]')),
4478 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]')),
4476 "branch":
4479 "branch":
4477 (branch,
4480 (branch,
4478 [('f', 'force', None,
4481 [('f', 'force', None,
4479 _('set branch name even if it shadows an existing branch')),
4482 _('set branch name even if it shadows an existing branch')),
4480 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4483 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4481 _('[-fC] [NAME]')),
4484 _('[-fC] [NAME]')),
4482 "branches":
4485 "branches":
4483 (branches,
4486 (branches,
4484 [('a', 'active', False,
4487 [('a', 'active', False,
4485 _('show only branches that have unmerged heads')),
4488 _('show only branches that have unmerged heads')),
4486 ('c', 'closed', False,
4489 ('c', 'closed', False,
4487 _('show normal and closed branches'))],
4490 _('show normal and closed branches'))],
4488 _('[-ac]')),
4491 _('[-ac]')),
4489 "bundle":
4492 "bundle":
4490 (bundle,
4493 (bundle,
4491 [('f', 'force', None,
4494 [('f', 'force', None,
4492 _('run even when the destination is unrelated')),
4495 _('run even when the destination is unrelated')),
4493 ('r', 'rev', [],
4496 ('r', 'rev', [],
4494 _('a changeset intended to be added to the destination'),
4497 _('a changeset intended to be added to the destination'),
4495 _('REV')),
4498 _('REV')),
4496 ('b', 'branch', [],
4499 ('b', 'branch', [],
4497 _('a specific branch you would like to bundle'),
4500 _('a specific branch you would like to bundle'),
4498 _('BRANCH')),
4501 _('BRANCH')),
4499 ('', 'base', [],
4502 ('', 'base', [],
4500 _('a base changeset assumed to be available at the destination'),
4503 _('a base changeset assumed to be available at the destination'),
4501 _('REV')),
4504 _('REV')),
4502 ('a', 'all', None, _('bundle all changesets in the repository')),
4505 ('a', 'all', None, _('bundle all changesets in the repository')),
4503 ('t', 'type', 'bzip2',
4506 ('t', 'type', 'bzip2',
4504 _('bundle compression type to use'), _('TYPE')),
4507 _('bundle compression type to use'), _('TYPE')),
4505 ] + remoteopts,
4508 ] + remoteopts,
4506 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4509 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4507 "cat":
4510 "cat":
4508 (cat,
4511 (cat,
4509 [('o', 'output', '',
4512 [('o', 'output', '',
4510 _('print output to file with formatted name'), _('FORMAT')),
4513 _('print output to file with formatted name'), _('FORMAT')),
4511 ('r', 'rev', '',
4514 ('r', 'rev', '',
4512 _('print the given revision'), _('REV')),
4515 _('print the given revision'), _('REV')),
4513 ('', 'decode', None, _('apply any matching decode filter')),
4516 ('', 'decode', None, _('apply any matching decode filter')),
4514 ] + walkopts,
4517 ] + walkopts,
4515 _('[OPTION]... FILE...')),
4518 _('[OPTION]... FILE...')),
4516 "^clone":
4519 "^clone":
4517 (clone,
4520 (clone,
4518 [('U', 'noupdate', None,
4521 [('U', 'noupdate', None,
4519 _('the clone will include an empty working copy (only a repository)')),
4522 _('the clone will include an empty working copy (only a repository)')),
4520 ('u', 'updaterev', '',
4523 ('u', 'updaterev', '',
4521 _('revision, tag or branch to check out'), _('REV')),
4524 _('revision, tag or branch to check out'), _('REV')),
4522 ('r', 'rev', [],
4525 ('r', 'rev', [],
4523 _('include the specified changeset'), _('REV')),
4526 _('include the specified changeset'), _('REV')),
4524 ('b', 'branch', [],
4527 ('b', 'branch', [],
4525 _('clone only the specified branch'), _('BRANCH')),
4528 _('clone only the specified branch'), _('BRANCH')),
4526 ('', 'pull', None, _('use pull protocol to copy metadata')),
4529 ('', 'pull', None, _('use pull protocol to copy metadata')),
4527 ('', 'uncompressed', None,
4530 ('', 'uncompressed', None,
4528 _('use uncompressed transfer (fast over LAN)')),
4531 _('use uncompressed transfer (fast over LAN)')),
4529 ] + remoteopts,
4532 ] + remoteopts,
4530 _('[OPTION]... SOURCE [DEST]')),
4533 _('[OPTION]... SOURCE [DEST]')),
4531 "^commit|ci":
4534 "^commit|ci":
4532 (commit,
4535 (commit,
4533 [('A', 'addremove', None,
4536 [('A', 'addremove', None,
4534 _('mark new/missing files as added/removed before committing')),
4537 _('mark new/missing files as added/removed before committing')),
4535 ('', 'close-branch', None,
4538 ('', 'close-branch', None,
4536 _('mark a branch as closed, hiding it from the branch list')),
4539 _('mark a branch as closed, hiding it from the branch list')),
4537 ] + walkopts + commitopts + commitopts2,
4540 ] + walkopts + commitopts + commitopts2,
4538 _('[OPTION]... [FILE]...')),
4541 _('[OPTION]... [FILE]...')),
4539 "copy|cp":
4542 "copy|cp":
4540 (copy,
4543 (copy,
4541 [('A', 'after', None, _('record a copy that has already occurred')),
4544 [('A', 'after', None, _('record a copy that has already occurred')),
4542 ('f', 'force', None,
4545 ('f', 'force', None,
4543 _('forcibly copy over an existing managed file')),
4546 _('forcibly copy over an existing managed file')),
4544 ] + walkopts + dryrunopts,
4547 ] + walkopts + dryrunopts,
4545 _('[OPTION]... [SOURCE]... DEST')),
4548 _('[OPTION]... [SOURCE]... DEST')),
4546 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4549 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4547 "debugbuilddag":
4550 "debugbuilddag":
4548 (debugbuilddag,
4551 (debugbuilddag,
4549 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4552 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4550 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4553 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4551 ('n', 'new-file', None, _('add new file at each rev')),
4554 ('n', 'new-file', None, _('add new file at each rev')),
4552 ],
4555 ],
4553 _('[OPTION]... TEXT')),
4556 _('[OPTION]... TEXT')),
4554 "debugbundle":
4557 "debugbundle":
4555 (debugbundle,
4558 (debugbundle,
4556 [('a', 'all', None, _('show all details')),
4559 [('a', 'all', None, _('show all details')),
4557 ],
4560 ],
4558 _('FILE')),
4561 _('FILE')),
4559 "debugcheckstate": (debugcheckstate, [], ''),
4562 "debugcheckstate": (debugcheckstate, [], ''),
4560 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4563 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4561 "debugcomplete":
4564 "debugcomplete":
4562 (debugcomplete,
4565 (debugcomplete,
4563 [('o', 'options', None, _('show the command options'))],
4566 [('o', 'options', None, _('show the command options'))],
4564 _('[-o] CMD')),
4567 _('[-o] CMD')),
4565 "debugdag":
4568 "debugdag":
4566 (debugdag,
4569 (debugdag,
4567 [('t', 'tags', None, _('use tags as labels')),
4570 [('t', 'tags', None, _('use tags as labels')),
4568 ('b', 'branches', None, _('annotate with branch names')),
4571 ('b', 'branches', None, _('annotate with branch names')),
4569 ('', 'dots', None, _('use dots for runs')),
4572 ('', 'dots', None, _('use dots for runs')),
4570 ('s', 'spaces', None, _('separate elements by spaces')),
4573 ('s', 'spaces', None, _('separate elements by spaces')),
4571 ],
4574 ],
4572 _('[OPTION]... [FILE [REV]...]')),
4575 _('[OPTION]... [FILE [REV]...]')),
4573 "debugdate":
4576 "debugdate":
4574 (debugdate,
4577 (debugdate,
4575 [('e', 'extended', None, _('try extended date formats'))],
4578 [('e', 'extended', None, _('try extended date formats'))],
4576 _('[-e] DATE [RANGE]')),
4579 _('[-e] DATE [RANGE]')),
4577 "debugdata": (debugdata, [], _('FILE REV')),
4580 "debugdata": (debugdata, [], _('FILE REV')),
4578 "debugdiscovery": (debugdiscovery,
4581 "debugdiscovery": (debugdiscovery,
4579 [('', 'old', None,
4582 [('', 'old', None,
4580 _('use old-style discovery')),
4583 _('use old-style discovery')),
4581 ('', 'nonheads', None,
4584 ('', 'nonheads', None,
4582 _('use old-style discovery with non-heads included')),
4585 _('use old-style discovery with non-heads included')),
4583 ] + remoteopts,
4586 ] + remoteopts,
4584 _('[-l REV] [-r REV] [-b BRANCH]...'
4587 _('[-l REV] [-r REV] [-b BRANCH]...'
4585 ' [OTHER]')),
4588 ' [OTHER]')),
4586 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4589 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4587 "debuggetbundle":
4590 "debuggetbundle":
4588 (debuggetbundle,
4591 (debuggetbundle,
4589 [('H', 'head', [], _('id of head node'), _('ID')),
4592 [('H', 'head', [], _('id of head node'), _('ID')),
4590 ('C', 'common', [], _('id of common node'), _('ID')),
4593 ('C', 'common', [], _('id of common node'), _('ID')),
4591 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
4594 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
4592 ],
4595 ],
4593 _('REPO FILE [-H|-C ID]...')),
4596 _('REPO FILE [-H|-C ID]...')),
4594 "debugignore": (debugignore, [], ''),
4597 "debugignore": (debugignore, [], ''),
4595 "debugindex": (debugindex,
4598 "debugindex": (debugindex,
4596 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4599 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4597 _('FILE')),
4600 _('FILE')),
4598 "debugindexdot": (debugindexdot, [], _('FILE')),
4601 "debugindexdot": (debugindexdot, [], _('FILE')),
4599 "debuginstall": (debuginstall, [], ''),
4602 "debuginstall": (debuginstall, [], ''),
4600 "debugknown": (debugknown, [], _('REPO ID...')),
4603 "debugknown": (debugknown, [], _('REPO ID...')),
4601 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4604 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4602 "debugrebuildstate":
4605 "debugrebuildstate":
4603 (debugrebuildstate,
4606 (debugrebuildstate,
4604 [('r', 'rev', '',
4607 [('r', 'rev', '',
4605 _('revision to rebuild to'), _('REV'))],
4608 _('revision to rebuild to'), _('REV'))],
4606 _('[-r REV] [REV]')),
4609 _('[-r REV] [REV]')),
4607 "debugrename":
4610 "debugrename":
4608 (debugrename,
4611 (debugrename,
4609 [('r', 'rev', '',
4612 [('r', 'rev', '',
4610 _('revision to debug'), _('REV'))],
4613 _('revision to debug'), _('REV'))],
4611 _('[-r REV] FILE')),
4614 _('[-r REV] FILE')),
4612 "debugrevspec":
4615 "debugrevspec":
4613 (debugrevspec, [], ('REVSPEC')),
4616 (debugrevspec, [], ('REVSPEC')),
4614 "debugsetparents":
4617 "debugsetparents":
4615 (debugsetparents, [], _('REV1 [REV2]')),
4618 (debugsetparents, [], _('REV1 [REV2]')),
4616 "debugstate":
4619 "debugstate":
4617 (debugstate,
4620 (debugstate,
4618 [('', 'nodates', None, _('do not display the saved mtime')),
4621 [('', 'nodates', None, _('do not display the saved mtime')),
4619 ('', 'datesort', None, _('sort by saved mtime'))],
4622 ('', 'datesort', None, _('sort by saved mtime'))],
4620 _('[OPTION]...')),
4623 _('[OPTION]...')),
4621 "debugsub":
4624 "debugsub":
4622 (debugsub,
4625 (debugsub,
4623 [('r', 'rev', '',
4626 [('r', 'rev', '',
4624 _('revision to check'), _('REV'))],
4627 _('revision to check'), _('REV'))],
4625 _('[-r REV] [REV]')),
4628 _('[-r REV] [REV]')),
4626 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4629 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4627 "debugwireargs":
4630 "debugwireargs":
4628 (debugwireargs,
4631 (debugwireargs,
4629 [('', 'three', '', 'three'),
4632 [('', 'three', '', 'three'),
4630 ('', 'four', '', 'four'),
4633 ('', 'four', '', 'four'),
4631 ('', 'five', '', 'five'),
4634 ('', 'five', '', 'five'),
4632 ] + remoteopts,
4635 ] + remoteopts,
4633 _('REPO [OPTIONS]... [ONE [TWO]]')),
4636 _('REPO [OPTIONS]... [ONE [TWO]]')),
4634 "^diff":
4637 "^diff":
4635 (diff,
4638 (diff,
4636 [('r', 'rev', [],
4639 [('r', 'rev', [],
4637 _('revision'), _('REV')),
4640 _('revision'), _('REV')),
4638 ('c', 'change', '',
4641 ('c', 'change', '',
4639 _('change made by revision'), _('REV'))
4642 _('change made by revision'), _('REV'))
4640 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4643 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4641 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4644 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4642 "^export":
4645 "^export":
4643 (export,
4646 (export,
4644 [('o', 'output', '',
4647 [('o', 'output', '',
4645 _('print output to file with formatted name'), _('FORMAT')),
4648 _('print output to file with formatted name'), _('FORMAT')),
4646 ('', 'switch-parent', None, _('diff against the second parent')),
4649 ('', 'switch-parent', None, _('diff against the second parent')),
4647 ('r', 'rev', [],
4650 ('r', 'rev', [],
4648 _('revisions to export'), _('REV')),
4651 _('revisions to export'), _('REV')),
4649 ] + diffopts,
4652 ] + diffopts,
4650 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4653 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4651 "^forget":
4654 "^forget":
4652 (forget,
4655 (forget,
4653 [] + walkopts,
4656 [] + walkopts,
4654 _('[OPTION]... FILE...')),
4657 _('[OPTION]... FILE...')),
4655 "grep":
4658 "grep":
4656 (grep,
4659 (grep,
4657 [('0', 'print0', None, _('end fields with NUL')),
4660 [('0', 'print0', None, _('end fields with NUL')),
4658 ('', 'all', None, _('print all revisions that match')),
4661 ('', 'all', None, _('print all revisions that match')),
4659 ('a', 'text', None, _('treat all files as text')),
4662 ('a', 'text', None, _('treat all files as text')),
4660 ('f', 'follow', None,
4663 ('f', 'follow', None,
4661 _('follow changeset history,'
4664 _('follow changeset history,'
4662 ' or file history across copies and renames')),
4665 ' or file history across copies and renames')),
4663 ('i', 'ignore-case', None, _('ignore case when matching')),
4666 ('i', 'ignore-case', None, _('ignore case when matching')),
4664 ('l', 'files-with-matches', None,
4667 ('l', 'files-with-matches', None,
4665 _('print only filenames and revisions that match')),
4668 _('print only filenames and revisions that match')),
4666 ('n', 'line-number', None, _('print matching line numbers')),
4669 ('n', 'line-number', None, _('print matching line numbers')),
4667 ('r', 'rev', [],
4670 ('r', 'rev', [],
4668 _('only search files changed within revision range'), _('REV')),
4671 _('only search files changed within revision range'), _('REV')),
4669 ('u', 'user', None, _('list the author (long with -v)')),
4672 ('u', 'user', None, _('list the author (long with -v)')),
4670 ('d', 'date', None, _('list the date (short with -q)')),
4673 ('d', 'date', None, _('list the date (short with -q)')),
4671 ] + walkopts,
4674 ] + walkopts,
4672 _('[OPTION]... PATTERN [FILE]...')),
4675 _('[OPTION]... PATTERN [FILE]...')),
4673 "heads":
4676 "heads":
4674 (heads,
4677 (heads,
4675 [('r', 'rev', '',
4678 [('r', 'rev', '',
4676 _('show only heads which are descendants of STARTREV'),
4679 _('show only heads which are descendants of STARTREV'),
4677 _('STARTREV')),
4680 _('STARTREV')),
4678 ('t', 'topo', False, _('show topological heads only')),
4681 ('t', 'topo', False, _('show topological heads only')),
4679 ('a', 'active', False,
4682 ('a', 'active', False,
4680 _('show active branchheads only (DEPRECATED)')),
4683 _('show active branchheads only (DEPRECATED)')),
4681 ('c', 'closed', False,
4684 ('c', 'closed', False,
4682 _('show normal and closed branch heads')),
4685 _('show normal and closed branch heads')),
4683 ] + templateopts,
4686 ] + templateopts,
4684 _('[-ac] [-r STARTREV] [REV]...')),
4687 _('[-ac] [-r STARTREV] [REV]...')),
4685 "help": (help_, [], _('[TOPIC]')),
4688 "help": (help_, [], _('[TOPIC]')),
4686 "identify|id":
4689 "identify|id":
4687 (identify,
4690 (identify,
4688 [('r', 'rev', '',
4691 [('r', 'rev', '',
4689 _('identify the specified revision'), _('REV')),
4692 _('identify the specified revision'), _('REV')),
4690 ('n', 'num', None, _('show local revision number')),
4693 ('n', 'num', None, _('show local revision number')),
4691 ('i', 'id', None, _('show global revision id')),
4694 ('i', 'id', None, _('show global revision id')),
4692 ('b', 'branch', None, _('show branch')),
4695 ('b', 'branch', None, _('show branch')),
4693 ('t', 'tags', None, _('show tags')),
4696 ('t', 'tags', None, _('show tags')),
4694 ('B', 'bookmarks', None, _('show bookmarks'))],
4697 ('B', 'bookmarks', None, _('show bookmarks'))],
4695 _('[-nibtB] [-r REV] [SOURCE]')),
4698 _('[-nibtB] [-r REV] [SOURCE]')),
4696 "import|patch":
4699 "import|patch":
4697 (import_,
4700 (import_,
4698 [('p', 'strip', 1,
4701 [('p', 'strip', 1,
4699 _('directory strip option for patch. This has the same '
4702 _('directory strip option for patch. This has the same '
4700 'meaning as the corresponding patch option'),
4703 'meaning as the corresponding patch option'),
4701 _('NUM')),
4704 _('NUM')),
4702 ('b', 'base', '',
4705 ('b', 'base', '',
4703 _('base path'), _('PATH')),
4706 _('base path'), _('PATH')),
4704 ('f', 'force', None,
4707 ('f', 'force', None,
4705 _('skip check for outstanding uncommitted changes')),
4708 _('skip check for outstanding uncommitted changes')),
4706 ('', 'no-commit', None,
4709 ('', 'no-commit', None,
4707 _("don't commit, just update the working directory")),
4710 _("don't commit, just update the working directory")),
4708 ('', 'exact', None,
4711 ('', 'exact', None,
4709 _('apply patch to the nodes from which it was generated')),
4712 _('apply patch to the nodes from which it was generated')),
4710 ('', 'import-branch', None,
4713 ('', 'import-branch', None,
4711 _('use any branch information in patch (implied by --exact)'))] +
4714 _('use any branch information in patch (implied by --exact)'))] +
4712 commitopts + commitopts2 + similarityopts,
4715 commitopts + commitopts2 + similarityopts,
4713 _('[OPTION]... PATCH...')),
4716 _('[OPTION]... PATCH...')),
4714 "incoming|in":
4717 "incoming|in":
4715 (incoming,
4718 (incoming,
4716 [('f', 'force', None,
4719 [('f', 'force', None,
4717 _('run even if remote repository is unrelated')),
4720 _('run even if remote repository is unrelated')),
4718 ('n', 'newest-first', None, _('show newest record first')),
4721 ('n', 'newest-first', None, _('show newest record first')),
4719 ('', 'bundle', '',
4722 ('', 'bundle', '',
4720 _('file to store the bundles into'), _('FILE')),
4723 _('file to store the bundles into'), _('FILE')),
4721 ('r', 'rev', [],
4724 ('r', 'rev', [],
4722 _('a remote changeset intended to be added'), _('REV')),
4725 _('a remote changeset intended to be added'), _('REV')),
4723 ('B', 'bookmarks', False, _("compare bookmarks")),
4726 ('B', 'bookmarks', False, _("compare bookmarks")),
4724 ('b', 'branch', [],
4727 ('b', 'branch', [],
4725 _('a specific branch you would like to pull'), _('BRANCH')),
4728 _('a specific branch you would like to pull'), _('BRANCH')),
4726 ] + logopts + remoteopts + subrepoopts,
4729 ] + logopts + remoteopts + subrepoopts,
4727 _('[-p] [-n] [-M] [-f] [-r REV]...'
4730 _('[-p] [-n] [-M] [-f] [-r REV]...'
4728 ' [--bundle FILENAME] [SOURCE]')),
4731 ' [--bundle FILENAME] [SOURCE]')),
4729 "^init":
4732 "^init":
4730 (init,
4733 (init,
4731 remoteopts,
4734 remoteopts,
4732 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4735 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4733 "locate":
4736 "locate":
4734 (locate,
4737 (locate,
4735 [('r', 'rev', '',
4738 [('r', 'rev', '',
4736 _('search the repository as it is in REV'), _('REV')),
4739 _('search the repository as it is in REV'), _('REV')),
4737 ('0', 'print0', None,
4740 ('0', 'print0', None,
4738 _('end filenames with NUL, for use with xargs')),
4741 _('end filenames with NUL, for use with xargs')),
4739 ('f', 'fullpath', None,
4742 ('f', 'fullpath', None,
4740 _('print complete paths from the filesystem root')),
4743 _('print complete paths from the filesystem root')),
4741 ] + walkopts,
4744 ] + walkopts,
4742 _('[OPTION]... [PATTERN]...')),
4745 _('[OPTION]... [PATTERN]...')),
4743 "^log|history":
4746 "^log|history":
4744 (log,
4747 (log,
4745 [('f', 'follow', None,
4748 [('f', 'follow', None,
4746 _('follow changeset history,'
4749 _('follow changeset history,'
4747 ' or file history across copies and renames')),
4750 ' or file history across copies and renames')),
4748 ('', 'follow-first', None,
4751 ('', 'follow-first', None,
4749 _('only follow the first parent of merge changesets')),
4752 _('only follow the first parent of merge changesets')),
4750 ('d', 'date', '',
4753 ('d', 'date', '',
4751 _('show revisions matching date spec'), _('DATE')),
4754 _('show revisions matching date spec'), _('DATE')),
4752 ('C', 'copies', None, _('show copied files')),
4755 ('C', 'copies', None, _('show copied files')),
4753 ('k', 'keyword', [],
4756 ('k', 'keyword', [],
4754 _('do case-insensitive search for a given text'), _('TEXT')),
4757 _('do case-insensitive search for a given text'), _('TEXT')),
4755 ('r', 'rev', [],
4758 ('r', 'rev', [],
4756 _('show the specified revision or range'), _('REV')),
4759 _('show the specified revision or range'), _('REV')),
4757 ('', 'removed', None, _('include revisions where files were removed')),
4760 ('', 'removed', None, _('include revisions where files were removed')),
4758 ('m', 'only-merges', None, _('show only merges')),
4761 ('m', 'only-merges', None, _('show only merges')),
4759 ('u', 'user', [],
4762 ('u', 'user', [],
4760 _('revisions committed by user'), _('USER')),
4763 _('revisions committed by user'), _('USER')),
4761 ('', 'only-branch', [],
4764 ('', 'only-branch', [],
4762 _('show only changesets within the given named branch (DEPRECATED)'),
4765 _('show only changesets within the given named branch (DEPRECATED)'),
4763 _('BRANCH')),
4766 _('BRANCH')),
4764 ('b', 'branch', [],
4767 ('b', 'branch', [],
4765 _('show changesets within the given named branch'), _('BRANCH')),
4768 _('show changesets within the given named branch'), _('BRANCH')),
4766 ('P', 'prune', [],
4769 ('P', 'prune', [],
4767 _('do not display revision or any of its ancestors'), _('REV')),
4770 _('do not display revision or any of its ancestors'), _('REV')),
4768 ] + logopts + walkopts,
4771 ] + logopts + walkopts,
4769 _('[OPTION]... [FILE]')),
4772 _('[OPTION]... [FILE]')),
4770 "manifest":
4773 "manifest":
4771 (manifest,
4774 (manifest,
4772 [('r', 'rev', '',
4775 [('r', 'rev', '',
4773 _('revision to display'), _('REV'))],
4776 _('revision to display'), _('REV'))],
4774 _('[-r REV]')),
4777 _('[-r REV]')),
4775 "^merge":
4778 "^merge":
4776 (merge,
4779 (merge,
4777 [('f', 'force', None, _('force a merge with outstanding changes')),
4780 [('f', 'force', None, _('force a merge with outstanding changes')),
4778 ('t', 'tool', '', _('specify merge tool')),
4781 ('t', 'tool', '', _('specify merge tool')),
4779 ('r', 'rev', '',
4782 ('r', 'rev', '',
4780 _('revision to merge'), _('REV')),
4783 _('revision to merge'), _('REV')),
4781 ('P', 'preview', None,
4784 ('P', 'preview', None,
4782 _('review revisions to merge (no merge is performed)'))],
4785 _('review revisions to merge (no merge is performed)'))],
4783 _('[-P] [-f] [[-r] REV]')),
4786 _('[-P] [-f] [[-r] REV]')),
4784 "outgoing|out":
4787 "outgoing|out":
4785 (outgoing,
4788 (outgoing,
4786 [('f', 'force', None,
4789 [('f', 'force', None,
4787 _('run even when the destination is unrelated')),
4790 _('run even when the destination is unrelated')),
4788 ('r', 'rev', [],
4791 ('r', 'rev', [],
4789 _('a changeset intended to be included in the destination'),
4792 _('a changeset intended to be included in the destination'),
4790 _('REV')),
4793 _('REV')),
4791 ('n', 'newest-first', None, _('show newest record first')),
4794 ('n', 'newest-first', None, _('show newest record first')),
4792 ('B', 'bookmarks', False, _("compare bookmarks")),
4795 ('B', 'bookmarks', False, _("compare bookmarks")),
4793 ('b', 'branch', [],
4796 ('b', 'branch', [],
4794 _('a specific branch you would like to push'), _('BRANCH')),
4797 _('a specific branch you would like to push'), _('BRANCH')),
4795 ] + logopts + remoteopts + subrepoopts,
4798 ] + logopts + remoteopts + subrepoopts,
4796 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4799 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4797 "parents":
4800 "parents":
4798 (parents,
4801 (parents,
4799 [('r', 'rev', '',
4802 [('r', 'rev', '',
4800 _('show parents of the specified revision'), _('REV')),
4803 _('show parents of the specified revision'), _('REV')),
4801 ] + templateopts,
4804 ] + templateopts,
4802 _('[-r REV] [FILE]')),
4805 _('[-r REV] [FILE]')),
4803 "paths": (paths, [], _('[NAME]')),
4806 "paths": (paths, [], _('[NAME]')),
4804 "^pull":
4807 "^pull":
4805 (pull,
4808 (pull,
4806 [('u', 'update', None,
4809 [('u', 'update', None,
4807 _('update to new branch head if changesets were pulled')),
4810 _('update to new branch head if changesets were pulled')),
4808 ('f', 'force', None,
4811 ('f', 'force', None,
4809 _('run even when remote repository is unrelated')),
4812 _('run even when remote repository is unrelated')),
4810 ('r', 'rev', [],
4813 ('r', 'rev', [],
4811 _('a remote changeset intended to be added'), _('REV')),
4814 _('a remote changeset intended to be added'), _('REV')),
4812 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4815 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4813 ('b', 'branch', [],
4816 ('b', 'branch', [],
4814 _('a specific branch you would like to pull'), _('BRANCH')),
4817 _('a specific branch you would like to pull'), _('BRANCH')),
4815 ] + remoteopts,
4818 ] + remoteopts,
4816 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4819 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4817 "^push":
4820 "^push":
4818 (push,
4821 (push,
4819 [('f', 'force', None, _('force push')),
4822 [('f', 'force', None, _('force push')),
4820 ('r', 'rev', [],
4823 ('r', 'rev', [],
4821 _('a changeset intended to be included in the destination'),
4824 _('a changeset intended to be included in the destination'),
4822 _('REV')),
4825 _('REV')),
4823 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4826 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4824 ('b', 'branch', [],
4827 ('b', 'branch', [],
4825 _('a specific branch you would like to push'), _('BRANCH')),
4828 _('a specific branch you would like to push'), _('BRANCH')),
4826 ('', 'new-branch', False, _('allow pushing a new branch')),
4829 ('', 'new-branch', False, _('allow pushing a new branch')),
4827 ] + remoteopts,
4830 ] + remoteopts,
4828 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4831 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4829 "recover": (recover, []),
4832 "recover": (recover, []),
4830 "^remove|rm":
4833 "^remove|rm":
4831 (remove,
4834 (remove,
4832 [('A', 'after', None, _('record delete for missing files')),
4835 [('A', 'after', None, _('record delete for missing files')),
4833 ('f', 'force', None,
4836 ('f', 'force', None,
4834 _('remove (and delete) file even if added or modified')),
4837 _('remove (and delete) file even if added or modified')),
4835 ] + walkopts,
4838 ] + walkopts,
4836 _('[OPTION]... FILE...')),
4839 _('[OPTION]... FILE...')),
4837 "rename|move|mv":
4840 "rename|move|mv":
4838 (rename,
4841 (rename,
4839 [('A', 'after', None, _('record a rename that has already occurred')),
4842 [('A', 'after', None, _('record a rename that has already occurred')),
4840 ('f', 'force', None,
4843 ('f', 'force', None,
4841 _('forcibly copy over an existing managed file')),
4844 _('forcibly copy over an existing managed file')),
4842 ] + walkopts + dryrunopts,
4845 ] + walkopts + dryrunopts,
4843 _('[OPTION]... SOURCE... DEST')),
4846 _('[OPTION]... SOURCE... DEST')),
4844 "resolve":
4847 "resolve":
4845 (resolve,
4848 (resolve,
4846 [('a', 'all', None, _('select all unresolved files')),
4849 [('a', 'all', None, _('select all unresolved files')),
4847 ('l', 'list', None, _('list state of files needing merge')),
4850 ('l', 'list', None, _('list state of files needing merge')),
4848 ('m', 'mark', None, _('mark files as resolved')),
4851 ('m', 'mark', None, _('mark files as resolved')),
4849 ('u', 'unmark', None, _('mark files as unresolved')),
4852 ('u', 'unmark', None, _('mark files as unresolved')),
4850 ('t', 'tool', '', _('specify merge tool')),
4853 ('t', 'tool', '', _('specify merge tool')),
4851 ('n', 'no-status', None, _('hide status prefix'))]
4854 ('n', 'no-status', None, _('hide status prefix'))]
4852 + walkopts,
4855 + walkopts,
4853 _('[OPTION]... [FILE]...')),
4856 _('[OPTION]... [FILE]...')),
4854 "revert":
4857 "revert":
4855 (revert,
4858 (revert,
4856 [('a', 'all', None, _('revert all changes when no arguments given')),
4859 [('a', 'all', None, _('revert all changes when no arguments given')),
4857 ('d', 'date', '',
4860 ('d', 'date', '',
4858 _('tipmost revision matching date'), _('DATE')),
4861 _('tipmost revision matching date'), _('DATE')),
4859 ('r', 'rev', '',
4862 ('r', 'rev', '',
4860 _('revert to the specified revision'), _('REV')),
4863 _('revert to the specified revision'), _('REV')),
4861 ('', 'no-backup', None, _('do not save backup copies of files')),
4864 ('', 'no-backup', None, _('do not save backup copies of files')),
4862 ] + walkopts + dryrunopts,
4865 ] + walkopts + dryrunopts,
4863 _('[OPTION]... [-r REV] [NAME]...')),
4866 _('[OPTION]... [-r REV] [NAME]...')),
4864 "rollback": (rollback, dryrunopts),
4867 "rollback": (rollback, dryrunopts),
4865 "root": (root, []),
4868 "root": (root, []),
4866 "^serve":
4869 "^serve":
4867 (serve,
4870 (serve,
4868 [('A', 'accesslog', '',
4871 [('A', 'accesslog', '',
4869 _('name of access log file to write to'), _('FILE')),
4872 _('name of access log file to write to'), _('FILE')),
4870 ('d', 'daemon', None, _('run server in background')),
4873 ('d', 'daemon', None, _('run server in background')),
4871 ('', 'daemon-pipefds', '',
4874 ('', 'daemon-pipefds', '',
4872 _('used internally by daemon mode'), _('NUM')),
4875 _('used internally by daemon mode'), _('NUM')),
4873 ('E', 'errorlog', '',
4876 ('E', 'errorlog', '',
4874 _('name of error log file to write to'), _('FILE')),
4877 _('name of error log file to write to'), _('FILE')),
4875 # use string type, then we can check if something was passed
4878 # use string type, then we can check if something was passed
4876 ('p', 'port', '',
4879 ('p', 'port', '',
4877 _('port to listen on (default: 8000)'), _('PORT')),
4880 _('port to listen on (default: 8000)'), _('PORT')),
4878 ('a', 'address', '',
4881 ('a', 'address', '',
4879 _('address to listen on (default: all interfaces)'), _('ADDR')),
4882 _('address to listen on (default: all interfaces)'), _('ADDR')),
4880 ('', 'prefix', '',
4883 ('', 'prefix', '',
4881 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4884 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4882 ('n', 'name', '',
4885 ('n', 'name', '',
4883 _('name to show in web pages (default: working directory)'),
4886 _('name to show in web pages (default: working directory)'),
4884 _('NAME')),
4887 _('NAME')),
4885 ('', 'web-conf', '',
4888 ('', 'web-conf', '',
4886 _('name of the hgweb config file (see "hg help hgweb")'),
4889 _('name of the hgweb config file (see "hg help hgweb")'),
4887 _('FILE')),
4890 _('FILE')),
4888 ('', 'webdir-conf', '',
4891 ('', 'webdir-conf', '',
4889 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4892 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4890 ('', 'pid-file', '',
4893 ('', 'pid-file', '',
4891 _('name of file to write process ID to'), _('FILE')),
4894 _('name of file to write process ID to'), _('FILE')),
4892 ('', 'stdio', None, _('for remote clients')),
4895 ('', 'stdio', None, _('for remote clients')),
4893 ('t', 'templates', '',
4896 ('t', 'templates', '',
4894 _('web templates to use'), _('TEMPLATE')),
4897 _('web templates to use'), _('TEMPLATE')),
4895 ('', 'style', '',
4898 ('', 'style', '',
4896 _('template style to use'), _('STYLE')),
4899 _('template style to use'), _('STYLE')),
4897 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4900 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4898 ('', 'certificate', '',
4901 ('', 'certificate', '',
4899 _('SSL certificate file'), _('FILE'))],
4902 _('SSL certificate file'), _('FILE'))],
4900 _('[OPTION]...')),
4903 _('[OPTION]...')),
4901 "showconfig|debugconfig":
4904 "showconfig|debugconfig":
4902 (showconfig,
4905 (showconfig,
4903 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4906 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4904 _('[-u] [NAME]...')),
4907 _('[-u] [NAME]...')),
4905 "^summary|sum":
4908 "^summary|sum":
4906 (summary,
4909 (summary,
4907 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4910 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4908 "^status|st":
4911 "^status|st":
4909 (status,
4912 (status,
4910 [('A', 'all', None, _('show status of all files')),
4913 [('A', 'all', None, _('show status of all files')),
4911 ('m', 'modified', None, _('show only modified files')),
4914 ('m', 'modified', None, _('show only modified files')),
4912 ('a', 'added', None, _('show only added files')),
4915 ('a', 'added', None, _('show only added files')),
4913 ('r', 'removed', None, _('show only removed files')),
4916 ('r', 'removed', None, _('show only removed files')),
4914 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4917 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4915 ('c', 'clean', None, _('show only files without changes')),
4918 ('c', 'clean', None, _('show only files without changes')),
4916 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4919 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4917 ('i', 'ignored', None, _('show only ignored files')),
4920 ('i', 'ignored', None, _('show only ignored files')),
4918 ('n', 'no-status', None, _('hide status prefix')),
4921 ('n', 'no-status', None, _('hide status prefix')),
4919 ('C', 'copies', None, _('show source of copied files')),
4922 ('C', 'copies', None, _('show source of copied files')),
4920 ('0', 'print0', None,
4923 ('0', 'print0', None,
4921 _('end filenames with NUL, for use with xargs')),
4924 _('end filenames with NUL, for use with xargs')),
4922 ('', 'rev', [],
4925 ('', 'rev', [],
4923 _('show difference from revision'), _('REV')),
4926 _('show difference from revision'), _('REV')),
4924 ('', 'change', '',
4927 ('', 'change', '',
4925 _('list the changed files of a revision'), _('REV')),
4928 _('list the changed files of a revision'), _('REV')),
4926 ] + walkopts + subrepoopts,
4929 ] + walkopts + subrepoopts,
4927 _('[OPTION]... [FILE]...')),
4930 _('[OPTION]... [FILE]...')),
4928 "tag":
4931 "tag":
4929 (tag,
4932 (tag,
4930 [('f', 'force', None, _('force tag')),
4933 [('f', 'force', None, _('force tag')),
4931 ('l', 'local', None, _('make the tag local')),
4934 ('l', 'local', None, _('make the tag local')),
4932 ('r', 'rev', '',
4935 ('r', 'rev', '',
4933 _('revision to tag'), _('REV')),
4936 _('revision to tag'), _('REV')),
4934 ('', 'remove', None, _('remove a tag')),
4937 ('', 'remove', None, _('remove a tag')),
4935 # -l/--local is already there, commitopts cannot be used
4938 # -l/--local is already there, commitopts cannot be used
4936 ('e', 'edit', None, _('edit commit message')),
4939 ('e', 'edit', None, _('edit commit message')),
4937 ('m', 'message', '',
4940 ('m', 'message', '',
4938 _('use <text> as commit message'), _('TEXT')),
4941 _('use <text> as commit message'), _('TEXT')),
4939 ] + commitopts2,
4942 ] + commitopts2,
4940 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4943 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4941 "tags": (tags, [], ''),
4944 "tags": (tags, [], ''),
4942 "tip":
4945 "tip":
4943 (tip,
4946 (tip,
4944 [('p', 'patch', None, _('show patch')),
4947 [('p', 'patch', None, _('show patch')),
4945 ('g', 'git', None, _('use git extended diff format')),
4948 ('g', 'git', None, _('use git extended diff format')),
4946 ] + templateopts,
4949 ] + templateopts,
4947 _('[-p] [-g]')),
4950 _('[-p] [-g]')),
4948 "unbundle":
4951 "unbundle":
4949 (unbundle,
4952 (unbundle,
4950 [('u', 'update', None,
4953 [('u', 'update', None,
4951 _('update to new branch head if changesets were unbundled'))],
4954 _('update to new branch head if changesets were unbundled'))],
4952 _('[-u] FILE...')),
4955 _('[-u] FILE...')),
4953 "^update|up|checkout|co":
4956 "^update|up|checkout|co":
4954 (update,
4957 (update,
4955 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4958 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4956 ('c', 'check', None,
4959 ('c', 'check', None,
4957 _('update across branches if no uncommitted changes')),
4960 _('update across branches if no uncommitted changes')),
4958 ('d', 'date', '',
4961 ('d', 'date', '',
4959 _('tipmost revision matching date'), _('DATE')),
4962 _('tipmost revision matching date'), _('DATE')),
4960 ('r', 'rev', '',
4963 ('r', 'rev', '',
4961 _('revision'), _('REV'))],
4964 _('revision'), _('REV'))],
4962 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4965 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4963 "verify": (verify, []),
4966 "verify": (verify, []),
4964 "version": (version_, []),
4967 "version": (version_, []),
4965 }
4968 }
4966
4969
4967 norepo = ("clone init version help debugcommands debugcomplete"
4970 norepo = ("clone init version help debugcommands debugcomplete"
4968 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
4971 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
4969 " debugknown debuggetbundle debugbundle")
4972 " debugknown debuggetbundle debugbundle")
4970 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4973 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4971 " debugdata debugindex debugindexdot")
4974 " debugdata debugindex debugindexdot")
@@ -1,108 +1,127 b''
1 $ hg init
1 $ hg init
2
2
3 no bookmarks
3 no bookmarks
4
4
5 $ hg bookmarks
5 $ hg bookmarks
6 no bookmarks set
6 no bookmarks set
7
7
8 set bookmark X
8 set bookmark X
9
9
10 $ hg bookmark X
10 $ hg bookmark X
11
11
12 list bookmarks
12 list bookmarks
13
13
14 $ hg bookmark
14 $ hg bookmark
15 * X -1:000000000000
15 * X -1:000000000000
16
16
17 list bookmarks with color
17 list bookmarks with color
18
18
19 $ hg --config extensions.color= --config color.mode=ansi \
19 $ hg --config extensions.color= --config color.mode=ansi \
20 > bookmark --color=always
20 > bookmark --color=always
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
22
22
23 update to bookmark X
23 update to bookmark X
24
24
25 $ hg update X
25 $ hg update X
26 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
26 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
27
27
28 list bookmarks
28 list bookmarks
29
29
30 $ hg bookmarks
30 $ hg bookmarks
31 * X -1:000000000000
31 * X -1:000000000000
32
32
33 rename
33 rename
34
34
35 $ hg bookmark -m X Z
35 $ hg bookmark -m X Z
36
36
37 list bookmarks
37 list bookmarks
38
38
39 $ cat .hg/bookmarks.current
39 $ cat .hg/bookmarks.current
40 Z (no-eol)
40 Z (no-eol)
41 $ cat .hg/bookmarks
41 $ cat .hg/bookmarks
42 0000000000000000000000000000000000000000 Z
42 0000000000000000000000000000000000000000 Z
43 $ hg bookmarks
43 $ hg bookmarks
44 * Z -1:000000000000
44 * Z -1:000000000000
45
45
46 new bookmark Y
46 new bookmark Y
47
47
48 $ hg bookmark Y
48 $ hg bookmark Y
49
49
50 list bookmarks
50 list bookmarks
51
51
52 $ hg bookmark
52 $ hg bookmark
53 * Y -1:000000000000
53 * Y -1:000000000000
54 Z -1:000000000000
54 Z -1:000000000000
55
55
56 commit
56 commit
57
57
58 $ echo 'b' > b
58 $ echo 'b' > b
59 $ hg add b
59 $ hg add b
60 $ hg commit -m'test'
60 $ hg commit -m'test'
61
61
62 list bookmarks
62 list bookmarks
63
63
64 $ hg bookmark
64 $ hg bookmark
65 * Y 0:719295282060
65 * Y 0:719295282060
66 Z -1:000000000000
66 Z -1:000000000000
67
67
68 Verify that switching to Z updates the current bookmark:
68 Verify that switching to Z updates the current bookmark:
69 $ hg update Z
69 $ hg update Z
70 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
70 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
71 $ hg bookmark
71 $ hg bookmark
72 Y 0:719295282060
72 Y 0:719295282060
73 * Z -1:000000000000
73 * Z -1:000000000000
74
74
75 Switch back to Y for the remaining tests in this file:
75 Switch back to Y for the remaining tests in this file:
76 $ hg update Y
76 $ hg update Y
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
78
78
79 delete bookmarks
79 delete bookmarks
80
80
81 $ hg bookmark -d Y
81 $ hg bookmark -d Y
82 $ hg bookmark -d Z
82 $ hg bookmark -d Z
83
83
84 list bookmarks
84 list bookmarks
85
85
86 $ hg bookmark
86 $ hg bookmark
87 no bookmarks set
87 no bookmarks set
88
88
89 update to tip
89 update to tip
90
90
91 $ hg update tip
91 $ hg update tip
92 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
93
93
94 set bookmark Y using -r .
94 set bookmark Y using -r .
95
95
96 $ hg bookmark -r . Y
96 $ hg bookmark -r . Y
97
97
98 list bookmarks
98 list bookmarks
99
99
100 $ hg bookmark
100 $ hg bookmark
101 * Y 0:719295282060
101 * Y 0:719295282060
102
102
103 set bookmark Z using -i
103 set bookmark Z using -i
104
104
105 $ hg bookmark -r . -i Z
105 $ hg bookmark -r . -i Z
106 $ hg bookmarks
106 $ hg bookmarks
107 * Y 0:719295282060
107 * Y 0:719295282060
108 Z 0:719295282060
108 Z 0:719295282060
109
110 deactivate current bookmark using -i
111
112 $ hg bookmark -i Y
113 $ hg bookmarks
114 Y 0:719295282060
115 Z 0:719295282060
116
117 $ hg up -q Y
118 $ hg bookmarks
119 * Y 0:719295282060
120 Z 0:719295282060
121
122 deactivate current bookmark while renaming
123
124 $ hg bookmark -i -m Y X
125 $ hg bookmarks
126 X 0:719295282060
127 Z 0:719295282060
@@ -1,263 +1,263 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 copy
16 copy
17 diff
17 diff
18 export
18 export
19 forget
19 forget
20 grep
20 grep
21 heads
21 heads
22 help
22 help
23 identify
23 identify
24 import
24 import
25 incoming
25 incoming
26 init
26 init
27 locate
27 locate
28 log
28 log
29 manifest
29 manifest
30 merge
30 merge
31 outgoing
31 outgoing
32 parents
32 parents
33 paths
33 paths
34 pull
34 pull
35 push
35 push
36 recover
36 recover
37 remove
37 remove
38 rename
38 rename
39 resolve
39 resolve
40 revert
40 revert
41 rollback
41 rollback
42 root
42 root
43 serve
43 serve
44 showconfig
44 showconfig
45 status
45 status
46 summary
46 summary
47 tag
47 tag
48 tags
48 tags
49 tip
49 tip
50 unbundle
50 unbundle
51 update
51 update
52 verify
52 verify
53 version
53 version
54
54
55 Show all commands that start with "a"
55 Show all commands that start with "a"
56 $ hg debugcomplete a
56 $ hg debugcomplete a
57 add
57 add
58 addremove
58 addremove
59 annotate
59 annotate
60 archive
60 archive
61
61
62 Do not show debug commands if there are other candidates
62 Do not show debug commands if there are other candidates
63 $ hg debugcomplete d
63 $ hg debugcomplete d
64 diff
64 diff
65
65
66 Show debug commands if there are no other candidates
66 Show debug commands if there are no other candidates
67 $ hg debugcomplete debug
67 $ hg debugcomplete debug
68 debugancestor
68 debugancestor
69 debugbuilddag
69 debugbuilddag
70 debugbundle
70 debugbundle
71 debugcheckstate
71 debugcheckstate
72 debugcommands
72 debugcommands
73 debugcomplete
73 debugcomplete
74 debugconfig
74 debugconfig
75 debugdag
75 debugdag
76 debugdata
76 debugdata
77 debugdate
77 debugdate
78 debugdiscovery
78 debugdiscovery
79 debugfsinfo
79 debugfsinfo
80 debuggetbundle
80 debuggetbundle
81 debugignore
81 debugignore
82 debugindex
82 debugindex
83 debugindexdot
83 debugindexdot
84 debuginstall
84 debuginstall
85 debugknown
85 debugknown
86 debugpushkey
86 debugpushkey
87 debugrebuildstate
87 debugrebuildstate
88 debugrename
88 debugrename
89 debugrevspec
89 debugrevspec
90 debugsetparents
90 debugsetparents
91 debugstate
91 debugstate
92 debugsub
92 debugsub
93 debugwalk
93 debugwalk
94 debugwireargs
94 debugwireargs
95
95
96 Do not show the alias of a debug command if there are other candidates
96 Do not show the alias of a debug command if there are other candidates
97 (this should hide rawcommit)
97 (this should hide rawcommit)
98 $ hg debugcomplete r
98 $ hg debugcomplete r
99 recover
99 recover
100 remove
100 remove
101 rename
101 rename
102 resolve
102 resolve
103 revert
103 revert
104 rollback
104 rollback
105 root
105 root
106 Show the alias of a debug command if there are no other candidates
106 Show the alias of a debug command if there are no other candidates
107 $ hg debugcomplete rawc
107 $ hg debugcomplete rawc
108
108
109
109
110 Show the global options
110 Show the global options
111 $ hg debugcomplete --options | sort
111 $ hg debugcomplete --options | sort
112 --config
112 --config
113 --cwd
113 --cwd
114 --debug
114 --debug
115 --debugger
115 --debugger
116 --encoding
116 --encoding
117 --encodingmode
117 --encodingmode
118 --help
118 --help
119 --noninteractive
119 --noninteractive
120 --profile
120 --profile
121 --quiet
121 --quiet
122 --repository
122 --repository
123 --time
123 --time
124 --traceback
124 --traceback
125 --verbose
125 --verbose
126 --version
126 --version
127 -R
127 -R
128 -h
128 -h
129 -q
129 -q
130 -v
130 -v
131 -y
131 -y
132
132
133 Show the options for the "serve" command
133 Show the options for the "serve" command
134 $ hg debugcomplete --options serve | sort
134 $ hg debugcomplete --options serve | sort
135 --accesslog
135 --accesslog
136 --address
136 --address
137 --certificate
137 --certificate
138 --config
138 --config
139 --cwd
139 --cwd
140 --daemon
140 --daemon
141 --daemon-pipefds
141 --daemon-pipefds
142 --debug
142 --debug
143 --debugger
143 --debugger
144 --encoding
144 --encoding
145 --encodingmode
145 --encodingmode
146 --errorlog
146 --errorlog
147 --help
147 --help
148 --ipv6
148 --ipv6
149 --name
149 --name
150 --noninteractive
150 --noninteractive
151 --pid-file
151 --pid-file
152 --port
152 --port
153 --prefix
153 --prefix
154 --profile
154 --profile
155 --quiet
155 --quiet
156 --repository
156 --repository
157 --stdio
157 --stdio
158 --style
158 --style
159 --templates
159 --templates
160 --time
160 --time
161 --traceback
161 --traceback
162 --verbose
162 --verbose
163 --version
163 --version
164 --web-conf
164 --web-conf
165 -6
165 -6
166 -A
166 -A
167 -E
167 -E
168 -R
168 -R
169 -a
169 -a
170 -d
170 -d
171 -h
171 -h
172 -n
172 -n
173 -p
173 -p
174 -q
174 -q
175 -t
175 -t
176 -v
176 -v
177 -y
177 -y
178
178
179 Show an error if we use --options with an ambiguous abbreviation
179 Show an error if we use --options with an ambiguous abbreviation
180 $ hg debugcomplete --options s
180 $ hg debugcomplete --options s
181 hg: command 's' is ambiguous:
181 hg: command 's' is ambiguous:
182 serve showconfig status summary
182 serve showconfig status summary
183 [255]
183 [255]
184
184
185 Show all commands + options
185 Show all commands + options
186 $ hg debugcommands
186 $ hg debugcommands
187 add: include, exclude, subrepos, dry-run
187 add: include, exclude, subrepos, dry-run
188 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
188 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
189 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
189 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
190 commit: addremove, close-branch, include, exclude, message, logfile, date, user
190 commit: addremove, close-branch, include, exclude, message, logfile, date, user
191 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
191 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
192 export: output, switch-parent, rev, text, git, nodates
192 export: output, switch-parent, rev, text, git, nodates
193 forget: include, exclude
193 forget: include, exclude
194 init: ssh, remotecmd, insecure
194 init: ssh, remotecmd, insecure
195 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
195 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
196 merge: force, tool, rev, preview
196 merge: force, tool, rev, preview
197 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
197 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
198 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
198 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
199 remove: after, force, include, exclude
199 remove: after, force, include, exclude
200 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
200 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
201 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
201 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
202 summary: remote
202 summary: remote
203 update: clean, check, date, rev
203 update: clean, check, date, rev
204 addremove: similarity, include, exclude, dry-run
204 addremove: similarity, include, exclude, dry-run
205 archive: no-decode, prefix, rev, type, subrepos, include, exclude
205 archive: no-decode, prefix, rev, type, subrepos, include, exclude
206 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
206 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
207 bisect: reset, good, bad, skip, extend, command, noupdate
207 bisect: reset, good, bad, skip, extend, command, noupdate
208 bookmarks: force, rev, delete, rename
208 bookmarks: force, rev, delete, rename, inactive
209 branch: force, clean
209 branch: force, clean
210 branches: active, closed
210 branches: active, closed
211 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
211 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
212 cat: output, rev, decode, include, exclude
212 cat: output, rev, decode, include, exclude
213 copy: after, force, include, exclude, dry-run
213 copy: after, force, include, exclude, dry-run
214 debugancestor:
214 debugancestor:
215 debugbuilddag: mergeable-file, overwritten-file, new-file
215 debugbuilddag: mergeable-file, overwritten-file, new-file
216 debugbundle: all
216 debugbundle: all
217 debugcheckstate:
217 debugcheckstate:
218 debugcommands:
218 debugcommands:
219 debugcomplete: options
219 debugcomplete: options
220 debugdag: tags, branches, dots, spaces
220 debugdag: tags, branches, dots, spaces
221 debugdata:
221 debugdata:
222 debugdate: extended
222 debugdate: extended
223 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
223 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
224 debugfsinfo:
224 debugfsinfo:
225 debuggetbundle: head, common, type
225 debuggetbundle: head, common, type
226 debugignore:
226 debugignore:
227 debugindex: format
227 debugindex: format
228 debugindexdot:
228 debugindexdot:
229 debuginstall:
229 debuginstall:
230 debugknown:
230 debugknown:
231 debugpushkey:
231 debugpushkey:
232 debugrebuildstate: rev
232 debugrebuildstate: rev
233 debugrename: rev
233 debugrename: rev
234 debugrevspec:
234 debugrevspec:
235 debugsetparents:
235 debugsetparents:
236 debugstate: nodates, datesort
236 debugstate: nodates, datesort
237 debugsub: rev
237 debugsub: rev
238 debugwalk: include, exclude
238 debugwalk: include, exclude
239 debugwireargs: three, four, five, ssh, remotecmd, insecure
239 debugwireargs: three, four, five, ssh, remotecmd, insecure
240 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
240 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
241 heads: rev, topo, active, closed, style, template
241 heads: rev, topo, active, closed, style, template
242 help:
242 help:
243 identify: rev, num, id, branch, tags, bookmarks
243 identify: rev, num, id, branch, tags, bookmarks
244 import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
244 import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
245 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
245 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
246 locate: rev, print0, fullpath, include, exclude
246 locate: rev, print0, fullpath, include, exclude
247 manifest: rev
247 manifest: rev
248 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
248 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
249 parents: rev, style, template
249 parents: rev, style, template
250 paths:
250 paths:
251 recover:
251 recover:
252 rename: after, force, include, exclude, dry-run
252 rename: after, force, include, exclude, dry-run
253 resolve: all, list, mark, unmark, tool, no-status, include, exclude
253 resolve: all, list, mark, unmark, tool, no-status, include, exclude
254 revert: all, date, rev, no-backup, include, exclude, dry-run
254 revert: all, date, rev, no-backup, include, exclude, dry-run
255 rollback: dry-run
255 rollback: dry-run
256 root:
256 root:
257 showconfig: untrusted
257 showconfig: untrusted
258 tag: force, local, rev, remove, edit, message, date, user
258 tag: force, local, rev, remove, edit, message, date, user
259 tags:
259 tags:
260 tip: patch, git, style, template
260 tip: patch, git, style, template
261 unbundle: update
261 unbundle: update
262 verify:
262 verify:
263 version:
263 version:
General Comments 0
You need to be logged in to leave comments. Login now