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