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