##// END OF EJS Templates
add debugignore which yields the combined ignore patten of the .hgignore files...
jfh -
r13396:3e66eec9 default
parent child Browse files
Show More
@@ -1,4714 +1,4720
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex, nullid, nullrev, short
8 from node import hex, nullid, nullrev, short
9 from lock import release
9 from lock import release
10 from i18n import _, gettext
10 from i18n import _, gettext
11 import os, re, sys, difflib, time, tempfile
11 import os, re, sys, difflib, time, tempfile
12 import hg, util, revlog, extensions, copies, error, bookmarks
12 import hg, util, revlog, extensions, copies, error, bookmarks
13 import patch, help, mdiff, url, encoding, templatekw, discovery
13 import patch, help, mdiff, url, encoding, templatekw, discovery
14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
15 import merge as mergemod
15 import merge as mergemod
16 import minirst, revset
16 import minirst, revset
17 import dagparser
17 import dagparser
18
18
19 # Commands start here, listed alphabetically
19 # Commands start here, listed alphabetically
20
20
21 def add(ui, repo, *pats, **opts):
21 def add(ui, repo, *pats, **opts):
22 """add the specified files on the next commit
22 """add the specified files on the next commit
23
23
24 Schedule files to be version controlled and added to the
24 Schedule files to be version controlled and added to the
25 repository.
25 repository.
26
26
27 The files will be added to the repository at the next commit. To
27 The files will be added to the repository at the next commit. To
28 undo an add before that, see :hg:`forget`.
28 undo an add before that, see :hg:`forget`.
29
29
30 If no names are given, add all files to the repository.
30 If no names are given, add all files to the repository.
31
31
32 .. container:: verbose
32 .. container:: verbose
33
33
34 An example showing how new (unknown) files are added
34 An example showing how new (unknown) files are added
35 automatically by :hg:`add`::
35 automatically by :hg:`add`::
36
36
37 $ ls
37 $ ls
38 foo.c
38 foo.c
39 $ hg status
39 $ hg status
40 ? foo.c
40 ? foo.c
41 $ hg add
41 $ hg add
42 adding foo.c
42 adding foo.c
43 $ hg status
43 $ hg status
44 A foo.c
44 A foo.c
45
45
46 Returns 0 if all files are successfully added.
46 Returns 0 if all files are successfully added.
47 """
47 """
48
48
49 m = cmdutil.match(repo, pats, opts)
49 m = cmdutil.match(repo, pats, opts)
50 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
50 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
51 opts.get('subrepos'), prefix="")
51 opts.get('subrepos'), prefix="")
52 return rejected and 1 or 0
52 return rejected and 1 or 0
53
53
54 def addremove(ui, repo, *pats, **opts):
54 def addremove(ui, repo, *pats, **opts):
55 """add all new files, delete all missing files
55 """add all new files, delete all missing files
56
56
57 Add all new files and remove all missing files from the
57 Add all new files and remove all missing files from the
58 repository.
58 repository.
59
59
60 New files are ignored if they match any of the patterns in
60 New files are ignored if they match any of the patterns in
61 ``.hgignore``. As with add, these changes take effect at the next
61 ``.hgignore``. As with add, these changes take effect at the next
62 commit.
62 commit.
63
63
64 Use the -s/--similarity option to detect renamed files. With a
64 Use the -s/--similarity option to detect renamed files. With a
65 parameter greater than 0, this compares every removed file with
65 parameter greater than 0, this compares every removed file with
66 every added file and records those similar enough as renames. This
66 every added file and records those similar enough as renames. This
67 option takes a percentage between 0 (disabled) and 100 (files must
67 option takes a percentage between 0 (disabled) and 100 (files must
68 be identical) as its parameter. Detecting renamed files this way
68 be identical) as its parameter. Detecting renamed files this way
69 can be expensive. After using this option, :hg:`status -C` can be
69 can be expensive. After using this option, :hg:`status -C` can be
70 used to check which files were identified as moved or renamed.
70 used to check which files were identified as moved or renamed.
71
71
72 Returns 0 if all files are successfully added.
72 Returns 0 if all files are successfully added.
73 """
73 """
74 try:
74 try:
75 sim = float(opts.get('similarity') or 100)
75 sim = float(opts.get('similarity') or 100)
76 except ValueError:
76 except ValueError:
77 raise util.Abort(_('similarity must be a number'))
77 raise util.Abort(_('similarity must be a number'))
78 if sim < 0 or sim > 100:
78 if sim < 0 or sim > 100:
79 raise util.Abort(_('similarity must be between 0 and 100'))
79 raise util.Abort(_('similarity must be between 0 and 100'))
80 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
80 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
81
81
82 def annotate(ui, repo, *pats, **opts):
82 def annotate(ui, repo, *pats, **opts):
83 """show changeset information by line for each file
83 """show changeset information by line for each file
84
84
85 List changes in files, showing the revision id responsible for
85 List changes in files, showing the revision id responsible for
86 each line
86 each line
87
87
88 This command is useful for discovering when a change was made and
88 This command is useful for discovering when a change was made and
89 by whom.
89 by whom.
90
90
91 Without the -a/--text option, annotate will avoid processing files
91 Without the -a/--text option, annotate will avoid processing files
92 it detects as binary. With -a, annotate will annotate the file
92 it detects as binary. With -a, annotate will annotate the file
93 anyway, although the results will probably be neither useful
93 anyway, although the results will probably be neither useful
94 nor desirable.
94 nor desirable.
95
95
96 Returns 0 on success.
96 Returns 0 on success.
97 """
97 """
98 if opts.get('follow'):
98 if opts.get('follow'):
99 # --follow is deprecated and now just an alias for -f/--file
99 # --follow is deprecated and now just an alias for -f/--file
100 # to mimic the behavior of Mercurial before version 1.5
100 # to mimic the behavior of Mercurial before version 1.5
101 opts['file'] = 1
101 opts['file'] = 1
102
102
103 datefunc = ui.quiet and util.shortdate or util.datestr
103 datefunc = ui.quiet and util.shortdate or util.datestr
104 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
104 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
105
105
106 if not pats:
106 if not pats:
107 raise util.Abort(_('at least one filename or pattern is required'))
107 raise util.Abort(_('at least one filename or pattern is required'))
108
108
109 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
109 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
110 ('number', lambda x: str(x[0].rev())),
110 ('number', lambda x: str(x[0].rev())),
111 ('changeset', lambda x: short(x[0].node())),
111 ('changeset', lambda x: short(x[0].node())),
112 ('date', getdate),
112 ('date', getdate),
113 ('file', lambda x: x[0].path()),
113 ('file', lambda x: x[0].path()),
114 ]
114 ]
115
115
116 if (not opts.get('user') and not opts.get('changeset')
116 if (not opts.get('user') and not opts.get('changeset')
117 and not opts.get('date') and not opts.get('file')):
117 and not opts.get('date') and not opts.get('file')):
118 opts['number'] = 1
118 opts['number'] = 1
119
119
120 linenumber = opts.get('line_number') is not None
120 linenumber = opts.get('line_number') is not None
121 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
121 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
122 raise util.Abort(_('at least one of -n/-c is required for -l'))
122 raise util.Abort(_('at least one of -n/-c is required for -l'))
123
123
124 funcmap = [func for op, func in opmap if opts.get(op)]
124 funcmap = [func for op, func in opmap if opts.get(op)]
125 if linenumber:
125 if linenumber:
126 lastfunc = funcmap[-1]
126 lastfunc = funcmap[-1]
127 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
127 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
128
128
129 ctx = cmdutil.revsingle(repo, opts.get('rev'))
129 ctx = cmdutil.revsingle(repo, opts.get('rev'))
130 m = cmdutil.match(repo, pats, opts)
130 m = cmdutil.match(repo, pats, opts)
131 follow = not opts.get('no_follow')
131 follow = not opts.get('no_follow')
132 for abs in ctx.walk(m):
132 for abs in ctx.walk(m):
133 fctx = ctx[abs]
133 fctx = ctx[abs]
134 if not opts.get('text') and util.binary(fctx.data()):
134 if not opts.get('text') and util.binary(fctx.data()):
135 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
135 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
136 continue
136 continue
137
137
138 lines = fctx.annotate(follow=follow, linenumber=linenumber)
138 lines = fctx.annotate(follow=follow, linenumber=linenumber)
139 pieces = []
139 pieces = []
140
140
141 for f in funcmap:
141 for f in funcmap:
142 l = [f(n) for n, dummy in lines]
142 l = [f(n) for n, dummy in lines]
143 if l:
143 if l:
144 sized = [(x, encoding.colwidth(x)) for x in l]
144 sized = [(x, encoding.colwidth(x)) for x in l]
145 ml = max([w for x, w in sized])
145 ml = max([w for x, w in sized])
146 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
146 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
147
147
148 if pieces:
148 if pieces:
149 for p, l in zip(zip(*pieces), lines):
149 for p, l in zip(zip(*pieces), lines):
150 ui.write("%s: %s" % (" ".join(p), l[1]))
150 ui.write("%s: %s" % (" ".join(p), l[1]))
151
151
152 def archive(ui, repo, dest, **opts):
152 def archive(ui, repo, dest, **opts):
153 '''create an unversioned archive of a repository revision
153 '''create an unversioned archive of a repository revision
154
154
155 By default, the revision used is the parent of the working
155 By default, the revision used is the parent of the working
156 directory; use -r/--rev to specify a different revision.
156 directory; use -r/--rev to specify a different revision.
157
157
158 The archive type is automatically detected based on file
158 The archive type is automatically detected based on file
159 extension (or override using -t/--type).
159 extension (or override using -t/--type).
160
160
161 Valid types are:
161 Valid types are:
162
162
163 :``files``: a directory full of files (default)
163 :``files``: a directory full of files (default)
164 :``tar``: tar archive, uncompressed
164 :``tar``: tar archive, uncompressed
165 :``tbz2``: tar archive, compressed using bzip2
165 :``tbz2``: tar archive, compressed using bzip2
166 :``tgz``: tar archive, compressed using gzip
166 :``tgz``: tar archive, compressed using gzip
167 :``uzip``: zip archive, uncompressed
167 :``uzip``: zip archive, uncompressed
168 :``zip``: zip archive, compressed using deflate
168 :``zip``: zip archive, compressed using deflate
169
169
170 The exact name of the destination archive or directory is given
170 The exact name of the destination archive or directory is given
171 using a format string; see :hg:`help export` for details.
171 using a format string; see :hg:`help export` for details.
172
172
173 Each member added to an archive file has a directory prefix
173 Each member added to an archive file has a directory prefix
174 prepended. Use -p/--prefix to specify a format string for the
174 prepended. Use -p/--prefix to specify a format string for the
175 prefix. The default is the basename of the archive, with suffixes
175 prefix. The default is the basename of the archive, with suffixes
176 removed.
176 removed.
177
177
178 Returns 0 on success.
178 Returns 0 on success.
179 '''
179 '''
180
180
181 ctx = cmdutil.revsingle(repo, opts.get('rev'))
181 ctx = cmdutil.revsingle(repo, opts.get('rev'))
182 if not ctx:
182 if not ctx:
183 raise util.Abort(_('no working directory: please specify a revision'))
183 raise util.Abort(_('no working directory: please specify a revision'))
184 node = ctx.node()
184 node = ctx.node()
185 dest = cmdutil.make_filename(repo, dest, node)
185 dest = cmdutil.make_filename(repo, dest, node)
186 if os.path.realpath(dest) == repo.root:
186 if os.path.realpath(dest) == repo.root:
187 raise util.Abort(_('repository root cannot be destination'))
187 raise util.Abort(_('repository root cannot be destination'))
188
188
189 kind = opts.get('type') or archival.guesskind(dest) or 'files'
189 kind = opts.get('type') or archival.guesskind(dest) or 'files'
190 prefix = opts.get('prefix')
190 prefix = opts.get('prefix')
191
191
192 if dest == '-':
192 if dest == '-':
193 if kind == 'files':
193 if kind == 'files':
194 raise util.Abort(_('cannot archive plain files to stdout'))
194 raise util.Abort(_('cannot archive plain files to stdout'))
195 dest = sys.stdout
195 dest = sys.stdout
196 if not prefix:
196 if not prefix:
197 prefix = os.path.basename(repo.root) + '-%h'
197 prefix = os.path.basename(repo.root) + '-%h'
198
198
199 prefix = cmdutil.make_filename(repo, prefix, node)
199 prefix = cmdutil.make_filename(repo, prefix, node)
200 matchfn = cmdutil.match(repo, [], opts)
200 matchfn = cmdutil.match(repo, [], opts)
201 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
201 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
202 matchfn, prefix, subrepos=opts.get('subrepos'))
202 matchfn, prefix, subrepos=opts.get('subrepos'))
203
203
204 def backout(ui, repo, node=None, rev=None, **opts):
204 def backout(ui, repo, node=None, rev=None, **opts):
205 '''reverse effect of earlier changeset
205 '''reverse effect of earlier changeset
206
206
207 Prepare a new changeset with the effect of REV undone in the
207 Prepare a new changeset with the effect of REV undone in the
208 current working directory.
208 current working directory.
209
209
210 If REV is the parent of the working directory, then this changeset
210 If REV is the parent of the working directory, then this changeset
211 is committed automatically. Otherwise, hg needs to merge the
211 is committed automatically. Otherwise, hg needs to merge the
212 changes and the merged result is left uncommitted.
212 changes and the merged result is left uncommitted.
213
213
214 By default, the pending changeset will have one parent,
214 By default, the pending changeset will have one parent,
215 maintaining a linear history. With --merge, the pending changeset
215 maintaining a linear history. With --merge, the pending changeset
216 will instead have two parents: the old parent of the working
216 will instead have two parents: the old parent of the working
217 directory and a child of REV that simply undoes REV.
217 directory and a child of REV that simply undoes REV.
218
218
219 Before version 1.7, the default behavior was equivalent to
219 Before version 1.7, the default behavior was equivalent to
220 specifying --merge followed by :hg:`update --clean .` to cancel
220 specifying --merge followed by :hg:`update --clean .` to cancel
221 the merge and leave the child of REV as a head to be merged
221 the merge and leave the child of REV as a head to be merged
222 separately.
222 separately.
223
223
224 See :hg:`help dates` for a list of formats valid for -d/--date.
224 See :hg:`help dates` for a list of formats valid for -d/--date.
225
225
226 Returns 0 on success.
226 Returns 0 on success.
227 '''
227 '''
228 if rev and node:
228 if rev and node:
229 raise util.Abort(_("please specify just one revision"))
229 raise util.Abort(_("please specify just one revision"))
230
230
231 if not rev:
231 if not rev:
232 rev = node
232 rev = node
233
233
234 if not rev:
234 if not rev:
235 raise util.Abort(_("please specify a revision to backout"))
235 raise util.Abort(_("please specify a revision to backout"))
236
236
237 date = opts.get('date')
237 date = opts.get('date')
238 if date:
238 if date:
239 opts['date'] = util.parsedate(date)
239 opts['date'] = util.parsedate(date)
240
240
241 cmdutil.bail_if_changed(repo)
241 cmdutil.bail_if_changed(repo)
242 node = cmdutil.revsingle(repo, rev).node()
242 node = cmdutil.revsingle(repo, rev).node()
243
243
244 op1, op2 = repo.dirstate.parents()
244 op1, op2 = repo.dirstate.parents()
245 a = repo.changelog.ancestor(op1, node)
245 a = repo.changelog.ancestor(op1, node)
246 if a != node:
246 if a != node:
247 raise util.Abort(_('cannot backout change on a different branch'))
247 raise util.Abort(_('cannot backout change on a different branch'))
248
248
249 p1, p2 = repo.changelog.parents(node)
249 p1, p2 = repo.changelog.parents(node)
250 if p1 == nullid:
250 if p1 == nullid:
251 raise util.Abort(_('cannot backout a change with no parents'))
251 raise util.Abort(_('cannot backout a change with no parents'))
252 if p2 != nullid:
252 if p2 != nullid:
253 if not opts.get('parent'):
253 if not opts.get('parent'):
254 raise util.Abort(_('cannot backout a merge changeset without '
254 raise util.Abort(_('cannot backout a merge changeset without '
255 '--parent'))
255 '--parent'))
256 p = repo.lookup(opts['parent'])
256 p = repo.lookup(opts['parent'])
257 if p not in (p1, p2):
257 if p not in (p1, p2):
258 raise util.Abort(_('%s is not a parent of %s') %
258 raise util.Abort(_('%s is not a parent of %s') %
259 (short(p), short(node)))
259 (short(p), short(node)))
260 parent = p
260 parent = p
261 else:
261 else:
262 if opts.get('parent'):
262 if opts.get('parent'):
263 raise util.Abort(_('cannot use --parent on non-merge changeset'))
263 raise util.Abort(_('cannot use --parent on non-merge changeset'))
264 parent = p1
264 parent = p1
265
265
266 # the backout should appear on the same branch
266 # the backout should appear on the same branch
267 branch = repo.dirstate.branch()
267 branch = repo.dirstate.branch()
268 hg.clean(repo, node, show_stats=False)
268 hg.clean(repo, node, show_stats=False)
269 repo.dirstate.setbranch(branch)
269 repo.dirstate.setbranch(branch)
270 revert_opts = opts.copy()
270 revert_opts = opts.copy()
271 revert_opts['date'] = None
271 revert_opts['date'] = None
272 revert_opts['all'] = True
272 revert_opts['all'] = True
273 revert_opts['rev'] = hex(parent)
273 revert_opts['rev'] = hex(parent)
274 revert_opts['no_backup'] = None
274 revert_opts['no_backup'] = None
275 revert(ui, repo, **revert_opts)
275 revert(ui, repo, **revert_opts)
276 if not opts.get('merge') and op1 != node:
276 if not opts.get('merge') and op1 != node:
277 try:
277 try:
278 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
278 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
279 return hg.update(repo, op1)
279 return hg.update(repo, op1)
280 finally:
280 finally:
281 ui.setconfig('ui', 'forcemerge', '')
281 ui.setconfig('ui', 'forcemerge', '')
282
282
283 commit_opts = opts.copy()
283 commit_opts = opts.copy()
284 commit_opts['addremove'] = False
284 commit_opts['addremove'] = False
285 if not commit_opts['message'] and not commit_opts['logfile']:
285 if not commit_opts['message'] and not commit_opts['logfile']:
286 # we don't translate commit messages
286 # we don't translate commit messages
287 commit_opts['message'] = "Backed out changeset %s" % short(node)
287 commit_opts['message'] = "Backed out changeset %s" % short(node)
288 commit_opts['force_editor'] = True
288 commit_opts['force_editor'] = True
289 commit(ui, repo, **commit_opts)
289 commit(ui, repo, **commit_opts)
290 def nice(node):
290 def nice(node):
291 return '%d:%s' % (repo.changelog.rev(node), short(node))
291 return '%d:%s' % (repo.changelog.rev(node), short(node))
292 ui.status(_('changeset %s backs out changeset %s\n') %
292 ui.status(_('changeset %s backs out changeset %s\n') %
293 (nice(repo.changelog.tip()), nice(node)))
293 (nice(repo.changelog.tip()), nice(node)))
294 if opts.get('merge') and op1 != node:
294 if opts.get('merge') and op1 != node:
295 hg.clean(repo, op1, show_stats=False)
295 hg.clean(repo, op1, show_stats=False)
296 ui.status(_('merging with changeset %s\n')
296 ui.status(_('merging with changeset %s\n')
297 % nice(repo.changelog.tip()))
297 % nice(repo.changelog.tip()))
298 try:
298 try:
299 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
299 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
300 return hg.merge(repo, hex(repo.changelog.tip()))
300 return hg.merge(repo, hex(repo.changelog.tip()))
301 finally:
301 finally:
302 ui.setconfig('ui', 'forcemerge', '')
302 ui.setconfig('ui', 'forcemerge', '')
303 return 0
303 return 0
304
304
305 def bisect(ui, repo, rev=None, extra=None, command=None,
305 def bisect(ui, repo, rev=None, extra=None, command=None,
306 reset=None, good=None, bad=None, skip=None, noupdate=None):
306 reset=None, good=None, bad=None, skip=None, noupdate=None):
307 """subdivision search of changesets
307 """subdivision search of changesets
308
308
309 This command helps to find changesets which introduce problems. To
309 This command helps to find changesets which introduce problems. To
310 use, mark the earliest changeset you know exhibits the problem as
310 use, mark the earliest changeset you know exhibits the problem as
311 bad, then mark the latest changeset which is free from the problem
311 bad, then mark the latest changeset which is free from the problem
312 as good. Bisect will update your working directory to a revision
312 as good. Bisect will update your working directory to a revision
313 for testing (unless the -U/--noupdate option is specified). Once
313 for testing (unless the -U/--noupdate option is specified). Once
314 you have performed tests, mark the working directory as good or
314 you have performed tests, mark the working directory as good or
315 bad, and bisect will either update to another candidate changeset
315 bad, and bisect will either update to another candidate changeset
316 or announce that it has found the bad revision.
316 or announce that it has found the bad revision.
317
317
318 As a shortcut, you can also use the revision argument to mark a
318 As a shortcut, you can also use the revision argument to mark a
319 revision as good or bad without checking it out first.
319 revision as good or bad without checking it out first.
320
320
321 If you supply a command, it will be used for automatic bisection.
321 If you supply a command, it will be used for automatic bisection.
322 Its exit status will be used to mark revisions as good or bad:
322 Its exit status will be used to mark revisions as good or bad:
323 status 0 means good, 125 means to skip the revision, 127
323 status 0 means good, 125 means to skip the revision, 127
324 (command not found) will abort the bisection, and any other
324 (command not found) will abort the bisection, and any other
325 non-zero exit status means the revision is bad.
325 non-zero exit status means the revision is bad.
326
326
327 Returns 0 on success.
327 Returns 0 on success.
328 """
328 """
329 def print_result(nodes, good):
329 def print_result(nodes, good):
330 displayer = cmdutil.show_changeset(ui, repo, {})
330 displayer = cmdutil.show_changeset(ui, repo, {})
331 if len(nodes) == 1:
331 if len(nodes) == 1:
332 # narrowed it down to a single revision
332 # narrowed it down to a single revision
333 if good:
333 if good:
334 ui.write(_("The first good revision is:\n"))
334 ui.write(_("The first good revision is:\n"))
335 else:
335 else:
336 ui.write(_("The first bad revision is:\n"))
336 ui.write(_("The first bad revision is:\n"))
337 displayer.show(repo[nodes[0]])
337 displayer.show(repo[nodes[0]])
338 parents = repo[nodes[0]].parents()
338 parents = repo[nodes[0]].parents()
339 if len(parents) > 1:
339 if len(parents) > 1:
340 side = good and state['bad'] or state['good']
340 side = good and state['bad'] or state['good']
341 num = len(set(i.node() for i in parents) & set(side))
341 num = len(set(i.node() for i in parents) & set(side))
342 if num == 1:
342 if num == 1:
343 common = parents[0].ancestor(parents[1])
343 common = parents[0].ancestor(parents[1])
344 ui.write(_('Not all ancestors of this changeset have been'
344 ui.write(_('Not all ancestors of this changeset have been'
345 ' checked.\nTo check the other ancestors, start'
345 ' checked.\nTo check the other ancestors, start'
346 ' from the common ancestor, %s.\n' % common))
346 ' from the common ancestor, %s.\n' % common))
347 else:
347 else:
348 # multiple possible revisions
348 # multiple possible revisions
349 if good:
349 if good:
350 ui.write(_("Due to skipped revisions, the first "
350 ui.write(_("Due to skipped revisions, the first "
351 "good revision could be any of:\n"))
351 "good revision could be any of:\n"))
352 else:
352 else:
353 ui.write(_("Due to skipped revisions, the first "
353 ui.write(_("Due to skipped revisions, the first "
354 "bad revision could be any of:\n"))
354 "bad revision could be any of:\n"))
355 for n in nodes:
355 for n in nodes:
356 displayer.show(repo[n])
356 displayer.show(repo[n])
357 displayer.close()
357 displayer.close()
358
358
359 def check_state(state, interactive=True):
359 def check_state(state, interactive=True):
360 if not state['good'] or not state['bad']:
360 if not state['good'] or not state['bad']:
361 if (good or bad or skip or reset) and interactive:
361 if (good or bad or skip or reset) and interactive:
362 return
362 return
363 if not state['good']:
363 if not state['good']:
364 raise util.Abort(_('cannot bisect (no known good revisions)'))
364 raise util.Abort(_('cannot bisect (no known good revisions)'))
365 else:
365 else:
366 raise util.Abort(_('cannot bisect (no known bad revisions)'))
366 raise util.Abort(_('cannot bisect (no known bad revisions)'))
367 return True
367 return True
368
368
369 # backward compatibility
369 # backward compatibility
370 if rev in "good bad reset init".split():
370 if rev in "good bad reset init".split():
371 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
371 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
372 cmd, rev, extra = rev, extra, None
372 cmd, rev, extra = rev, extra, None
373 if cmd == "good":
373 if cmd == "good":
374 good = True
374 good = True
375 elif cmd == "bad":
375 elif cmd == "bad":
376 bad = True
376 bad = True
377 else:
377 else:
378 reset = True
378 reset = True
379 elif extra or good + bad + skip + reset + bool(command) > 1:
379 elif extra or good + bad + skip + reset + bool(command) > 1:
380 raise util.Abort(_('incompatible arguments'))
380 raise util.Abort(_('incompatible arguments'))
381
381
382 if reset:
382 if reset:
383 p = repo.join("bisect.state")
383 p = repo.join("bisect.state")
384 if os.path.exists(p):
384 if os.path.exists(p):
385 os.unlink(p)
385 os.unlink(p)
386 return
386 return
387
387
388 state = hbisect.load_state(repo)
388 state = hbisect.load_state(repo)
389
389
390 if command:
390 if command:
391 changesets = 1
391 changesets = 1
392 try:
392 try:
393 while changesets:
393 while changesets:
394 # update state
394 # update state
395 status = util.system(command)
395 status = util.system(command)
396 if status == 125:
396 if status == 125:
397 transition = "skip"
397 transition = "skip"
398 elif status == 0:
398 elif status == 0:
399 transition = "good"
399 transition = "good"
400 # status < 0 means process was killed
400 # status < 0 means process was killed
401 elif status == 127:
401 elif status == 127:
402 raise util.Abort(_("failed to execute %s") % command)
402 raise util.Abort(_("failed to execute %s") % command)
403 elif status < 0:
403 elif status < 0:
404 raise util.Abort(_("%s killed") % command)
404 raise util.Abort(_("%s killed") % command)
405 else:
405 else:
406 transition = "bad"
406 transition = "bad"
407 ctx = cmdutil.revsingle(repo, rev)
407 ctx = cmdutil.revsingle(repo, rev)
408 rev = None # clear for future iterations
408 rev = None # clear for future iterations
409 state[transition].append(ctx.node())
409 state[transition].append(ctx.node())
410 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
410 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
411 check_state(state, interactive=False)
411 check_state(state, interactive=False)
412 # bisect
412 # bisect
413 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
413 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
414 # update to next check
414 # update to next check
415 cmdutil.bail_if_changed(repo)
415 cmdutil.bail_if_changed(repo)
416 hg.clean(repo, nodes[0], show_stats=False)
416 hg.clean(repo, nodes[0], show_stats=False)
417 finally:
417 finally:
418 hbisect.save_state(repo, state)
418 hbisect.save_state(repo, state)
419 print_result(nodes, good)
419 print_result(nodes, good)
420 return
420 return
421
421
422 # update state
422 # update state
423
423
424 if rev:
424 if rev:
425 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
425 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
426 else:
426 else:
427 nodes = [repo.lookup('.')]
427 nodes = [repo.lookup('.')]
428
428
429 if good or bad or skip:
429 if good or bad or skip:
430 if good:
430 if good:
431 state['good'] += nodes
431 state['good'] += nodes
432 elif bad:
432 elif bad:
433 state['bad'] += nodes
433 state['bad'] += nodes
434 elif skip:
434 elif skip:
435 state['skip'] += nodes
435 state['skip'] += nodes
436 hbisect.save_state(repo, state)
436 hbisect.save_state(repo, state)
437
437
438 if not check_state(state):
438 if not check_state(state):
439 return
439 return
440
440
441 # actually bisect
441 # actually bisect
442 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
442 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
443 if changesets == 0:
443 if changesets == 0:
444 print_result(nodes, good)
444 print_result(nodes, good)
445 else:
445 else:
446 assert len(nodes) == 1 # only a single node can be tested next
446 assert len(nodes) == 1 # only a single node can be tested next
447 node = nodes[0]
447 node = nodes[0]
448 # compute the approximate number of remaining tests
448 # compute the approximate number of remaining tests
449 tests, size = 0, 2
449 tests, size = 0, 2
450 while size <= changesets:
450 while size <= changesets:
451 tests, size = tests + 1, size * 2
451 tests, size = tests + 1, size * 2
452 rev = repo.changelog.rev(node)
452 rev = repo.changelog.rev(node)
453 ui.write(_("Testing changeset %d:%s "
453 ui.write(_("Testing changeset %d:%s "
454 "(%d changesets remaining, ~%d tests)\n")
454 "(%d changesets remaining, ~%d tests)\n")
455 % (rev, short(node), changesets, tests))
455 % (rev, short(node), changesets, tests))
456 if not noupdate:
456 if not noupdate:
457 cmdutil.bail_if_changed(repo)
457 cmdutil.bail_if_changed(repo)
458 return hg.clean(repo, node)
458 return hg.clean(repo, node)
459
459
460 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
460 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
461 '''track a line of development with movable markers
461 '''track a line of development with movable markers
462
462
463 Bookmarks are pointers to certain commits that move when
463 Bookmarks are pointers to certain commits that move when
464 committing. Bookmarks are local. They can be renamed, copied and
464 committing. Bookmarks are local. They can be renamed, copied and
465 deleted. It is possible to use bookmark names in :hg:`merge` and
465 deleted. It is possible to use bookmark names in :hg:`merge` and
466 :hg:`update` to merge and update respectively to a given bookmark.
466 :hg:`update` to merge and update respectively to a given bookmark.
467
467
468 You can use :hg:`bookmark NAME` to set a bookmark on the working
468 You can use :hg:`bookmark NAME` to set a bookmark on the working
469 directory's parent revision with the given name. If you specify
469 directory's parent revision with the given name. If you specify
470 a revision using -r REV (where REV may be an existing bookmark),
470 a revision using -r REV (where REV may be an existing bookmark),
471 the bookmark is assigned to that revision.
471 the bookmark is assigned to that revision.
472
472
473 Bookmarks can be pushed and pulled between repositories (see :hg:`help
473 Bookmarks can be pushed and pulled between repositories (see :hg:`help
474 push` and :hg:`help pull`). This requires the bookmark extension to be
474 push` and :hg:`help pull`). This requires the bookmark extension to be
475 enabled for both the local and remote repositories.
475 enabled for both the local and remote repositories.
476 '''
476 '''
477 hexfn = ui.debugflag and hex or short
477 hexfn = ui.debugflag and hex or short
478 marks = repo._bookmarks
478 marks = repo._bookmarks
479 cur = repo.changectx('.').node()
479 cur = repo.changectx('.').node()
480
480
481 if rename:
481 if rename:
482 if rename not in marks:
482 if rename not in marks:
483 raise util.Abort(_("a bookmark of this name does not exist"))
483 raise util.Abort(_("a bookmark of this name does not exist"))
484 if mark in marks and not force:
484 if mark in marks and not force:
485 raise util.Abort(_("a bookmark of the same name already exists"))
485 raise util.Abort(_("a bookmark of the same name already exists"))
486 if mark is None:
486 if mark is None:
487 raise util.Abort(_("new bookmark name required"))
487 raise util.Abort(_("new bookmark name required"))
488 marks[mark] = marks[rename]
488 marks[mark] = marks[rename]
489 del marks[rename]
489 del marks[rename]
490 if repo._bookmarkcurrent == rename:
490 if repo._bookmarkcurrent == rename:
491 bookmarks.setcurrent(repo, mark)
491 bookmarks.setcurrent(repo, mark)
492 bookmarks.write(repo)
492 bookmarks.write(repo)
493 return
493 return
494
494
495 if delete:
495 if delete:
496 if mark is None:
496 if mark is None:
497 raise util.Abort(_("bookmark name required"))
497 raise util.Abort(_("bookmark name required"))
498 if mark not in marks:
498 if mark not in marks:
499 raise util.Abort(_("a bookmark of this name does not exist"))
499 raise util.Abort(_("a bookmark of this name does not exist"))
500 if mark == repo._bookmarkcurrent:
500 if mark == repo._bookmarkcurrent:
501 bookmarks.setcurrent(repo, None)
501 bookmarks.setcurrent(repo, None)
502 del marks[mark]
502 del marks[mark]
503 bookmarks.write(repo)
503 bookmarks.write(repo)
504 return
504 return
505
505
506 if mark is not None:
506 if mark is not None:
507 if "\n" in mark:
507 if "\n" in mark:
508 raise util.Abort(_("bookmark name cannot contain newlines"))
508 raise util.Abort(_("bookmark name cannot contain newlines"))
509 mark = mark.strip()
509 mark = mark.strip()
510 if not mark:
510 if not mark:
511 raise util.Abort(_("bookmark names cannot consist entirely of "
511 raise util.Abort(_("bookmark names cannot consist entirely of "
512 "whitespace"))
512 "whitespace"))
513 if mark in marks and not force:
513 if mark in marks and not force:
514 raise util.Abort(_("a bookmark of the same name already exists"))
514 raise util.Abort(_("a bookmark of the same name already exists"))
515 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
515 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
516 and not force):
516 and not force):
517 raise util.Abort(
517 raise util.Abort(
518 _("a bookmark cannot have the name of an existing branch"))
518 _("a bookmark cannot have the name of an existing branch"))
519 if rev:
519 if rev:
520 marks[mark] = repo.lookup(rev)
520 marks[mark] = repo.lookup(rev)
521 else:
521 else:
522 marks[mark] = repo.changectx('.').node()
522 marks[mark] = repo.changectx('.').node()
523 bookmarks.setcurrent(repo, mark)
523 bookmarks.setcurrent(repo, mark)
524 bookmarks.write(repo)
524 bookmarks.write(repo)
525 return
525 return
526
526
527 if mark is None:
527 if mark is None:
528 if rev:
528 if rev:
529 raise util.Abort(_("bookmark name required"))
529 raise util.Abort(_("bookmark name required"))
530 if len(marks) == 0:
530 if len(marks) == 0:
531 ui.status(_("no bookmarks set\n"))
531 ui.status(_("no bookmarks set\n"))
532 else:
532 else:
533 for bmark, n in sorted(marks.iteritems()):
533 for bmark, n in sorted(marks.iteritems()):
534 if ui.configbool('bookmarks', 'track.current'):
534 if ui.configbool('bookmarks', 'track.current'):
535 current = repo._bookmarkcurrent
535 current = repo._bookmarkcurrent
536 if bmark == current and n == cur:
536 if bmark == current and n == cur:
537 prefix, label = '*', 'bookmarks.current'
537 prefix, label = '*', 'bookmarks.current'
538 else:
538 else:
539 prefix, label = ' ', ''
539 prefix, label = ' ', ''
540 else:
540 else:
541 if n == cur:
541 if n == cur:
542 prefix, label = '*', 'bookmarks.current'
542 prefix, label = '*', 'bookmarks.current'
543 else:
543 else:
544 prefix, label = ' ', ''
544 prefix, label = ' ', ''
545
545
546 if ui.quiet:
546 if ui.quiet:
547 ui.write("%s\n" % bmark, label=label)
547 ui.write("%s\n" % bmark, label=label)
548 else:
548 else:
549 ui.write(" %s %-25s %d:%s\n" % (
549 ui.write(" %s %-25s %d:%s\n" % (
550 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
550 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
551 label=label)
551 label=label)
552 return
552 return
553
553
554 def branch(ui, repo, label=None, **opts):
554 def branch(ui, repo, label=None, **opts):
555 """set or show the current branch name
555 """set or show the current branch name
556
556
557 With no argument, show the current branch name. With one argument,
557 With no argument, show the current branch name. With one argument,
558 set the working directory branch name (the branch will not exist
558 set the working directory branch name (the branch will not exist
559 in the repository until the next commit). Standard practice
559 in the repository until the next commit). Standard practice
560 recommends that primary development take place on the 'default'
560 recommends that primary development take place on the 'default'
561 branch.
561 branch.
562
562
563 Unless -f/--force is specified, branch will not let you set a
563 Unless -f/--force is specified, branch will not let you set a
564 branch name that already exists, even if it's inactive.
564 branch name that already exists, even if it's inactive.
565
565
566 Use -C/--clean to reset the working directory branch to that of
566 Use -C/--clean to reset the working directory branch to that of
567 the parent of the working directory, negating a previous branch
567 the parent of the working directory, negating a previous branch
568 change.
568 change.
569
569
570 Use the command :hg:`update` to switch to an existing branch. Use
570 Use the command :hg:`update` to switch to an existing branch. Use
571 :hg:`commit --close-branch` to mark this branch as closed.
571 :hg:`commit --close-branch` to mark this branch as closed.
572
572
573 Returns 0 on success.
573 Returns 0 on success.
574 """
574 """
575
575
576 if opts.get('clean'):
576 if opts.get('clean'):
577 label = repo[None].parents()[0].branch()
577 label = repo[None].parents()[0].branch()
578 repo.dirstate.setbranch(label)
578 repo.dirstate.setbranch(label)
579 ui.status(_('reset working directory to branch %s\n') % label)
579 ui.status(_('reset working directory to branch %s\n') % label)
580 elif label:
580 elif label:
581 if not opts.get('force') and label in repo.branchtags():
581 if not opts.get('force') and label in repo.branchtags():
582 if label not in [p.branch() for p in repo.parents()]:
582 if label not in [p.branch() for p in repo.parents()]:
583 raise util.Abort(_('a branch of the same name already exists'
583 raise util.Abort(_('a branch of the same name already exists'
584 " (use 'hg update' to switch to it)"))
584 " (use 'hg update' to switch to it)"))
585 repo.dirstate.setbranch(label)
585 repo.dirstate.setbranch(label)
586 ui.status(_('marked working directory as branch %s\n') % label)
586 ui.status(_('marked working directory as branch %s\n') % label)
587 else:
587 else:
588 ui.write("%s\n" % repo.dirstate.branch())
588 ui.write("%s\n" % repo.dirstate.branch())
589
589
590 def branches(ui, repo, active=False, closed=False):
590 def branches(ui, repo, active=False, closed=False):
591 """list repository named branches
591 """list repository named branches
592
592
593 List the repository's named branches, indicating which ones are
593 List the repository's named branches, indicating which ones are
594 inactive. If -c/--closed is specified, also list branches which have
594 inactive. If -c/--closed is specified, also list branches which have
595 been marked closed (see :hg:`commit --close-branch`).
595 been marked closed (see :hg:`commit --close-branch`).
596
596
597 If -a/--active is specified, only show active branches. A branch
597 If -a/--active is specified, only show active branches. A branch
598 is considered active if it contains repository heads.
598 is considered active if it contains repository heads.
599
599
600 Use the command :hg:`update` to switch to an existing branch.
600 Use the command :hg:`update` to switch to an existing branch.
601
601
602 Returns 0.
602 Returns 0.
603 """
603 """
604
604
605 hexfunc = ui.debugflag and hex or short
605 hexfunc = ui.debugflag and hex or short
606 activebranches = [repo[n].branch() for n in repo.heads()]
606 activebranches = [repo[n].branch() for n in repo.heads()]
607 def testactive(tag, node):
607 def testactive(tag, node):
608 realhead = tag in activebranches
608 realhead = tag in activebranches
609 open = node in repo.branchheads(tag, closed=False)
609 open = node in repo.branchheads(tag, closed=False)
610 return realhead and open
610 return realhead and open
611 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
611 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
612 for tag, node in repo.branchtags().items()],
612 for tag, node in repo.branchtags().items()],
613 reverse=True)
613 reverse=True)
614
614
615 for isactive, node, tag in branches:
615 for isactive, node, tag in branches:
616 if (not active) or isactive:
616 if (not active) or isactive:
617 if ui.quiet:
617 if ui.quiet:
618 ui.write("%s\n" % tag)
618 ui.write("%s\n" % tag)
619 else:
619 else:
620 hn = repo.lookup(node)
620 hn = repo.lookup(node)
621 if isactive:
621 if isactive:
622 label = 'branches.active'
622 label = 'branches.active'
623 notice = ''
623 notice = ''
624 elif hn not in repo.branchheads(tag, closed=False):
624 elif hn not in repo.branchheads(tag, closed=False):
625 if not closed:
625 if not closed:
626 continue
626 continue
627 label = 'branches.closed'
627 label = 'branches.closed'
628 notice = _(' (closed)')
628 notice = _(' (closed)')
629 else:
629 else:
630 label = 'branches.inactive'
630 label = 'branches.inactive'
631 notice = _(' (inactive)')
631 notice = _(' (inactive)')
632 if tag == repo.dirstate.branch():
632 if tag == repo.dirstate.branch():
633 label = 'branches.current'
633 label = 'branches.current'
634 rev = str(node).rjust(31 - encoding.colwidth(tag))
634 rev = str(node).rjust(31 - encoding.colwidth(tag))
635 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
635 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
636 tag = ui.label(tag, label)
636 tag = ui.label(tag, label)
637 ui.write("%s %s%s\n" % (tag, rev, notice))
637 ui.write("%s %s%s\n" % (tag, rev, notice))
638
638
639 def bundle(ui, repo, fname, dest=None, **opts):
639 def bundle(ui, repo, fname, dest=None, **opts):
640 """create a changegroup file
640 """create a changegroup file
641
641
642 Generate a compressed changegroup file collecting changesets not
642 Generate a compressed changegroup file collecting changesets not
643 known to be in another repository.
643 known to be in another repository.
644
644
645 If you omit the destination repository, then hg assumes the
645 If you omit the destination repository, then hg assumes the
646 destination will have all the nodes you specify with --base
646 destination will have all the nodes you specify with --base
647 parameters. To create a bundle containing all changesets, use
647 parameters. To create a bundle containing all changesets, use
648 -a/--all (or --base null).
648 -a/--all (or --base null).
649
649
650 You can change compression method with the -t/--type option.
650 You can change compression method with the -t/--type option.
651 The available compression methods are: none, bzip2, and
651 The available compression methods are: none, bzip2, and
652 gzip (by default, bundles are compressed using bzip2).
652 gzip (by default, bundles are compressed using bzip2).
653
653
654 The bundle file can then be transferred using conventional means
654 The bundle file can then be transferred using conventional means
655 and applied to another repository with the unbundle or pull
655 and applied to another repository with the unbundle or pull
656 command. This is useful when direct push and pull are not
656 command. This is useful when direct push and pull are not
657 available or when exporting an entire repository is undesirable.
657 available or when exporting an entire repository is undesirable.
658
658
659 Applying bundles preserves all changeset contents including
659 Applying bundles preserves all changeset contents including
660 permissions, copy/rename information, and revision history.
660 permissions, copy/rename information, and revision history.
661
661
662 Returns 0 on success, 1 if no changes found.
662 Returns 0 on success, 1 if no changes found.
663 """
663 """
664 revs = None
664 revs = None
665 if 'rev' in opts:
665 if 'rev' in opts:
666 revs = cmdutil.revrange(repo, opts['rev'])
666 revs = cmdutil.revrange(repo, opts['rev'])
667
667
668 if opts.get('all'):
668 if opts.get('all'):
669 base = ['null']
669 base = ['null']
670 else:
670 else:
671 base = cmdutil.revrange(repo, opts.get('base'))
671 base = cmdutil.revrange(repo, opts.get('base'))
672 if base:
672 if base:
673 if dest:
673 if dest:
674 raise util.Abort(_("--base is incompatible with specifying "
674 raise util.Abort(_("--base is incompatible with specifying "
675 "a destination"))
675 "a destination"))
676 base = [repo.lookup(rev) for rev in base]
676 base = [repo.lookup(rev) for rev in base]
677 # create the right base
677 # create the right base
678 # XXX: nodesbetween / changegroup* should be "fixed" instead
678 # XXX: nodesbetween / changegroup* should be "fixed" instead
679 o = []
679 o = []
680 has = set((nullid,))
680 has = set((nullid,))
681 for n in base:
681 for n in base:
682 has.update(repo.changelog.reachable(n))
682 has.update(repo.changelog.reachable(n))
683 if revs:
683 if revs:
684 revs = [repo.lookup(rev) for rev in revs]
684 revs = [repo.lookup(rev) for rev in revs]
685 visit = revs[:]
685 visit = revs[:]
686 has.difference_update(visit)
686 has.difference_update(visit)
687 else:
687 else:
688 visit = repo.changelog.heads()
688 visit = repo.changelog.heads()
689 seen = {}
689 seen = {}
690 while visit:
690 while visit:
691 n = visit.pop(0)
691 n = visit.pop(0)
692 parents = [p for p in repo.changelog.parents(n) if p not in has]
692 parents = [p for p in repo.changelog.parents(n) if p not in has]
693 if len(parents) == 0:
693 if len(parents) == 0:
694 if n not in has:
694 if n not in has:
695 o.append(n)
695 o.append(n)
696 else:
696 else:
697 for p in parents:
697 for p in parents:
698 if p not in seen:
698 if p not in seen:
699 seen[p] = 1
699 seen[p] = 1
700 visit.append(p)
700 visit.append(p)
701 else:
701 else:
702 dest = ui.expandpath(dest or 'default-push', dest or 'default')
702 dest = ui.expandpath(dest or 'default-push', dest or 'default')
703 dest, branches = hg.parseurl(dest, opts.get('branch'))
703 dest, branches = hg.parseurl(dest, opts.get('branch'))
704 other = hg.repository(hg.remoteui(repo, opts), dest)
704 other = hg.repository(hg.remoteui(repo, opts), dest)
705 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
705 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
706 if revs:
706 if revs:
707 revs = [repo.lookup(rev) for rev in revs]
707 revs = [repo.lookup(rev) for rev in revs]
708 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
708 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
709
709
710 if not o:
710 if not o:
711 ui.status(_("no changes found\n"))
711 ui.status(_("no changes found\n"))
712 return 1
712 return 1
713
713
714 if revs:
714 if revs:
715 cg = repo.changegroupsubset(o, revs, 'bundle')
715 cg = repo.changegroupsubset(o, revs, 'bundle')
716 else:
716 else:
717 cg = repo.changegroup(o, 'bundle')
717 cg = repo.changegroup(o, 'bundle')
718
718
719 bundletype = opts.get('type', 'bzip2').lower()
719 bundletype = opts.get('type', 'bzip2').lower()
720 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
720 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
721 bundletype = btypes.get(bundletype)
721 bundletype = btypes.get(bundletype)
722 if bundletype not in changegroup.bundletypes:
722 if bundletype not in changegroup.bundletypes:
723 raise util.Abort(_('unknown bundle type specified with --type'))
723 raise util.Abort(_('unknown bundle type specified with --type'))
724
724
725 changegroup.writebundle(cg, fname, bundletype)
725 changegroup.writebundle(cg, fname, bundletype)
726
726
727 def cat(ui, repo, file1, *pats, **opts):
727 def cat(ui, repo, file1, *pats, **opts):
728 """output the current or given revision of files
728 """output the current or given revision of files
729
729
730 Print the specified files as they were at the given revision. If
730 Print the specified files as they were at the given revision. If
731 no revision is given, the parent of the working directory is used,
731 no revision is given, the parent of the working directory is used,
732 or tip if no revision is checked out.
732 or tip if no revision is checked out.
733
733
734 Output may be to a file, in which case the name of the file is
734 Output may be to a file, in which case the name of the file is
735 given using a format string. The formatting rules are the same as
735 given using a format string. The formatting rules are the same as
736 for the export command, with the following additions:
736 for the export command, with the following additions:
737
737
738 :``%s``: basename of file being printed
738 :``%s``: basename of file being printed
739 :``%d``: dirname of file being printed, or '.' if in repository root
739 :``%d``: dirname of file being printed, or '.' if in repository root
740 :``%p``: root-relative path name of file being printed
740 :``%p``: root-relative path name of file being printed
741
741
742 Returns 0 on success.
742 Returns 0 on success.
743 """
743 """
744 ctx = cmdutil.revsingle(repo, opts.get('rev'))
744 ctx = cmdutil.revsingle(repo, opts.get('rev'))
745 err = 1
745 err = 1
746 m = cmdutil.match(repo, (file1,) + pats, opts)
746 m = cmdutil.match(repo, (file1,) + pats, opts)
747 for abs in ctx.walk(m):
747 for abs in ctx.walk(m):
748 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
748 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
749 data = ctx[abs].data()
749 data = ctx[abs].data()
750 if opts.get('decode'):
750 if opts.get('decode'):
751 data = repo.wwritedata(abs, data)
751 data = repo.wwritedata(abs, data)
752 fp.write(data)
752 fp.write(data)
753 err = 0
753 err = 0
754 return err
754 return err
755
755
756 def clone(ui, source, dest=None, **opts):
756 def clone(ui, source, dest=None, **opts):
757 """make a copy of an existing repository
757 """make a copy of an existing repository
758
758
759 Create a copy of an existing repository in a new directory.
759 Create a copy of an existing repository in a new directory.
760
760
761 If no destination directory name is specified, it defaults to the
761 If no destination directory name is specified, it defaults to the
762 basename of the source.
762 basename of the source.
763
763
764 The location of the source is added to the new repository's
764 The location of the source is added to the new repository's
765 ``.hg/hgrc`` file, as the default to be used for future pulls.
765 ``.hg/hgrc`` file, as the default to be used for future pulls.
766
766
767 See :hg:`help urls` for valid source format details.
767 See :hg:`help urls` for valid source format details.
768
768
769 It is possible to specify an ``ssh://`` URL as the destination, but no
769 It is possible to specify an ``ssh://`` URL as the destination, but no
770 ``.hg/hgrc`` and working directory will be created on the remote side.
770 ``.hg/hgrc`` and working directory will be created on the remote side.
771 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
771 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
772
772
773 A set of changesets (tags, or branch names) to pull may be specified
773 A set of changesets (tags, or branch names) to pull may be specified
774 by listing each changeset (tag, or branch name) with -r/--rev.
774 by listing each changeset (tag, or branch name) with -r/--rev.
775 If -r/--rev is used, the cloned repository will contain only a subset
775 If -r/--rev is used, the cloned repository will contain only a subset
776 of the changesets of the source repository. Only the set of changesets
776 of the changesets of the source repository. Only the set of changesets
777 defined by all -r/--rev options (including all their ancestors)
777 defined by all -r/--rev options (including all their ancestors)
778 will be pulled into the destination repository.
778 will be pulled into the destination repository.
779 No subsequent changesets (including subsequent tags) will be present
779 No subsequent changesets (including subsequent tags) will be present
780 in the destination.
780 in the destination.
781
781
782 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
782 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
783 local source repositories.
783 local source repositories.
784
784
785 For efficiency, hardlinks are used for cloning whenever the source
785 For efficiency, hardlinks are used for cloning whenever the source
786 and destination are on the same filesystem (note this applies only
786 and destination are on the same filesystem (note this applies only
787 to the repository data, not to the working directory). Some
787 to the repository data, not to the working directory). Some
788 filesystems, such as AFS, implement hardlinking incorrectly, but
788 filesystems, such as AFS, implement hardlinking incorrectly, but
789 do not report errors. In these cases, use the --pull option to
789 do not report errors. In these cases, use the --pull option to
790 avoid hardlinking.
790 avoid hardlinking.
791
791
792 In some cases, you can clone repositories and the working directory
792 In some cases, you can clone repositories and the working directory
793 using full hardlinks with ::
793 using full hardlinks with ::
794
794
795 $ cp -al REPO REPOCLONE
795 $ cp -al REPO REPOCLONE
796
796
797 This is the fastest way to clone, but it is not always safe. The
797 This is the fastest way to clone, but it is not always safe. The
798 operation is not atomic (making sure REPO is not modified during
798 operation is not atomic (making sure REPO is not modified during
799 the operation is up to you) and you have to make sure your editor
799 the operation is up to you) and you have to make sure your editor
800 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
800 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
801 this is not compatible with certain extensions that place their
801 this is not compatible with certain extensions that place their
802 metadata under the .hg directory, such as mq.
802 metadata under the .hg directory, such as mq.
803
803
804 Mercurial will update the working directory to the first applicable
804 Mercurial will update the working directory to the first applicable
805 revision from this list:
805 revision from this list:
806
806
807 a) null if -U or the source repository has no changesets
807 a) null if -U or the source repository has no changesets
808 b) if -u . and the source repository is local, the first parent of
808 b) if -u . and the source repository is local, the first parent of
809 the source repository's working directory
809 the source repository's working directory
810 c) the changeset specified with -u (if a branch name, this means the
810 c) the changeset specified with -u (if a branch name, this means the
811 latest head of that branch)
811 latest head of that branch)
812 d) the changeset specified with -r
812 d) the changeset specified with -r
813 e) the tipmost head specified with -b
813 e) the tipmost head specified with -b
814 f) the tipmost head specified with the url#branch source syntax
814 f) the tipmost head specified with the url#branch source syntax
815 g) the tipmost head of the default branch
815 g) the tipmost head of the default branch
816 h) tip
816 h) tip
817
817
818 Returns 0 on success.
818 Returns 0 on success.
819 """
819 """
820 if opts.get('noupdate') and opts.get('updaterev'):
820 if opts.get('noupdate') and opts.get('updaterev'):
821 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
821 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
822
822
823 r = hg.clone(hg.remoteui(ui, opts), source, dest,
823 r = hg.clone(hg.remoteui(ui, opts), source, dest,
824 pull=opts.get('pull'),
824 pull=opts.get('pull'),
825 stream=opts.get('uncompressed'),
825 stream=opts.get('uncompressed'),
826 rev=opts.get('rev'),
826 rev=opts.get('rev'),
827 update=opts.get('updaterev') or not opts.get('noupdate'),
827 update=opts.get('updaterev') or not opts.get('noupdate'),
828 branch=opts.get('branch'))
828 branch=opts.get('branch'))
829
829
830 return r is None
830 return r is None
831
831
832 def commit(ui, repo, *pats, **opts):
832 def commit(ui, repo, *pats, **opts):
833 """commit the specified files or all outstanding changes
833 """commit the specified files or all outstanding changes
834
834
835 Commit changes to the given files into the repository. Unlike a
835 Commit changes to the given files into the repository. Unlike a
836 centralized SCM, this operation is a local operation. See
836 centralized SCM, this operation is a local operation. See
837 :hg:`push` for a way to actively distribute your changes.
837 :hg:`push` for a way to actively distribute your changes.
838
838
839 If a list of files is omitted, all changes reported by :hg:`status`
839 If a list of files is omitted, all changes reported by :hg:`status`
840 will be committed.
840 will be committed.
841
841
842 If you are committing the result of a merge, do not provide any
842 If you are committing the result of a merge, do not provide any
843 filenames or -I/-X filters.
843 filenames or -I/-X filters.
844
844
845 If no commit message is specified, Mercurial starts your
845 If no commit message is specified, Mercurial starts your
846 configured editor where you can enter a message. In case your
846 configured editor where you can enter a message. In case your
847 commit fails, you will find a backup of your message in
847 commit fails, you will find a backup of your message in
848 ``.hg/last-message.txt``.
848 ``.hg/last-message.txt``.
849
849
850 See :hg:`help dates` for a list of formats valid for -d/--date.
850 See :hg:`help dates` for a list of formats valid for -d/--date.
851
851
852 Returns 0 on success, 1 if nothing changed.
852 Returns 0 on success, 1 if nothing changed.
853 """
853 """
854 extra = {}
854 extra = {}
855 if opts.get('close_branch'):
855 if opts.get('close_branch'):
856 if repo['.'].node() not in repo.branchheads():
856 if repo['.'].node() not in repo.branchheads():
857 # The topo heads set is included in the branch heads set of the
857 # The topo heads set is included in the branch heads set of the
858 # current branch, so it's sufficient to test branchheads
858 # current branch, so it's sufficient to test branchheads
859 raise util.Abort(_('can only close branch heads'))
859 raise util.Abort(_('can only close branch heads'))
860 extra['close'] = 1
860 extra['close'] = 1
861 e = cmdutil.commiteditor
861 e = cmdutil.commiteditor
862 if opts.get('force_editor'):
862 if opts.get('force_editor'):
863 e = cmdutil.commitforceeditor
863 e = cmdutil.commitforceeditor
864
864
865 def commitfunc(ui, repo, message, match, opts):
865 def commitfunc(ui, repo, message, match, opts):
866 return repo.commit(message, opts.get('user'), opts.get('date'), match,
866 return repo.commit(message, opts.get('user'), opts.get('date'), match,
867 editor=e, extra=extra)
867 editor=e, extra=extra)
868
868
869 branch = repo[None].branch()
869 branch = repo[None].branch()
870 bheads = repo.branchheads(branch)
870 bheads = repo.branchheads(branch)
871
871
872 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
872 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
873 if not node:
873 if not node:
874 ui.status(_("nothing changed\n"))
874 ui.status(_("nothing changed\n"))
875 return 1
875 return 1
876
876
877 ctx = repo[node]
877 ctx = repo[node]
878 parents = ctx.parents()
878 parents = ctx.parents()
879
879
880 if bheads and not [x for x in parents
880 if bheads and not [x for x in parents
881 if x.node() in bheads and x.branch() == branch]:
881 if x.node() in bheads and x.branch() == branch]:
882 ui.status(_('created new head\n'))
882 ui.status(_('created new head\n'))
883 # The message is not printed for initial roots. For the other
883 # The message is not printed for initial roots. For the other
884 # changesets, it is printed in the following situations:
884 # changesets, it is printed in the following situations:
885 #
885 #
886 # Par column: for the 2 parents with ...
886 # Par column: for the 2 parents with ...
887 # N: null or no parent
887 # N: null or no parent
888 # B: parent is on another named branch
888 # B: parent is on another named branch
889 # C: parent is a regular non head changeset
889 # C: parent is a regular non head changeset
890 # H: parent was a branch head of the current branch
890 # H: parent was a branch head of the current branch
891 # Msg column: whether we print "created new head" message
891 # Msg column: whether we print "created new head" message
892 # In the following, it is assumed that there already exists some
892 # In the following, it is assumed that there already exists some
893 # initial branch heads of the current branch, otherwise nothing is
893 # initial branch heads of the current branch, otherwise nothing is
894 # printed anyway.
894 # printed anyway.
895 #
895 #
896 # Par Msg Comment
896 # Par Msg Comment
897 # NN y additional topo root
897 # NN y additional topo root
898 #
898 #
899 # BN y additional branch root
899 # BN y additional branch root
900 # CN y additional topo head
900 # CN y additional topo head
901 # HN n usual case
901 # HN n usual case
902 #
902 #
903 # BB y weird additional branch root
903 # BB y weird additional branch root
904 # CB y branch merge
904 # CB y branch merge
905 # HB n merge with named branch
905 # HB n merge with named branch
906 #
906 #
907 # CC y additional head from merge
907 # CC y additional head from merge
908 # CH n merge with a head
908 # CH n merge with a head
909 #
909 #
910 # HH n head merge: head count decreases
910 # HH n head merge: head count decreases
911
911
912 if not opts.get('close_branch'):
912 if not opts.get('close_branch'):
913 for r in parents:
913 for r in parents:
914 if r.extra().get('close') and r.branch() == branch:
914 if r.extra().get('close') and r.branch() == branch:
915 ui.status(_('reopening closed branch head %d\n') % r)
915 ui.status(_('reopening closed branch head %d\n') % r)
916
916
917 if ui.debugflag:
917 if ui.debugflag:
918 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
918 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
919 elif ui.verbose:
919 elif ui.verbose:
920 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
920 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
921
921
922 def copy(ui, repo, *pats, **opts):
922 def copy(ui, repo, *pats, **opts):
923 """mark files as copied for the next commit
923 """mark files as copied for the next commit
924
924
925 Mark dest as having copies of source files. If dest is a
925 Mark dest as having copies of source files. If dest is a
926 directory, copies are put in that directory. If dest is a file,
926 directory, copies are put in that directory. If dest is a file,
927 the source must be a single file.
927 the source must be a single file.
928
928
929 By default, this command copies the contents of files as they
929 By default, this command copies the contents of files as they
930 exist in the working directory. If invoked with -A/--after, the
930 exist in the working directory. If invoked with -A/--after, the
931 operation is recorded, but no copying is performed.
931 operation is recorded, but no copying is performed.
932
932
933 This command takes effect with the next commit. To undo a copy
933 This command takes effect with the next commit. To undo a copy
934 before that, see :hg:`revert`.
934 before that, see :hg:`revert`.
935
935
936 Returns 0 on success, 1 if errors are encountered.
936 Returns 0 on success, 1 if errors are encountered.
937 """
937 """
938 wlock = repo.wlock(False)
938 wlock = repo.wlock(False)
939 try:
939 try:
940 return cmdutil.copy(ui, repo, pats, opts)
940 return cmdutil.copy(ui, repo, pats, opts)
941 finally:
941 finally:
942 wlock.release()
942 wlock.release()
943
943
944 def debugancestor(ui, repo, *args):
944 def debugancestor(ui, repo, *args):
945 """find the ancestor revision of two revisions in a given index"""
945 """find the ancestor revision of two revisions in a given index"""
946 if len(args) == 3:
946 if len(args) == 3:
947 index, rev1, rev2 = args
947 index, rev1, rev2 = args
948 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
948 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
949 lookup = r.lookup
949 lookup = r.lookup
950 elif len(args) == 2:
950 elif len(args) == 2:
951 if not repo:
951 if not repo:
952 raise util.Abort(_("there is no Mercurial repository here "
952 raise util.Abort(_("there is no Mercurial repository here "
953 "(.hg not found)"))
953 "(.hg not found)"))
954 rev1, rev2 = args
954 rev1, rev2 = args
955 r = repo.changelog
955 r = repo.changelog
956 lookup = repo.lookup
956 lookup = repo.lookup
957 else:
957 else:
958 raise util.Abort(_('either two or three arguments required'))
958 raise util.Abort(_('either two or three arguments required'))
959 a = r.ancestor(lookup(rev1), lookup(rev2))
959 a = r.ancestor(lookup(rev1), lookup(rev2))
960 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
960 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
961
961
962 def debugbuilddag(ui, repo, text,
962 def debugbuilddag(ui, repo, text,
963 mergeable_file=False,
963 mergeable_file=False,
964 appended_file=False,
964 appended_file=False,
965 overwritten_file=False,
965 overwritten_file=False,
966 new_file=False):
966 new_file=False):
967 """builds a repo with a given dag from scratch in the current empty repo
967 """builds a repo with a given dag from scratch in the current empty repo
968
968
969 Elements:
969 Elements:
970
970
971 - "+n" is a linear run of n nodes based on the current default parent
971 - "+n" is a linear run of n nodes based on the current default parent
972 - "." is a single node based on the current default parent
972 - "." is a single node based on the current default parent
973 - "$" resets the default parent to null (implied at the start);
973 - "$" resets the default parent to null (implied at the start);
974 otherwise the default parent is always the last node created
974 otherwise the default parent is always the last node created
975 - "<p" sets the default parent to the backref p
975 - "<p" sets the default parent to the backref p
976 - "*p" is a fork at parent p, which is a backref
976 - "*p" is a fork at parent p, which is a backref
977 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
977 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
978 - "/p2" is a merge of the preceding node and p2
978 - "/p2" is a merge of the preceding node and p2
979 - ":tag" defines a local tag for the preceding node
979 - ":tag" defines a local tag for the preceding node
980 - "@branch" sets the named branch for subsequent nodes
980 - "@branch" sets the named branch for subsequent nodes
981 - "!command" runs the command using your shell
981 - "!command" runs the command using your shell
982 - "!!my command\\n" is like "!", but to the end of the line
982 - "!!my command\\n" is like "!", but to the end of the line
983 - "#...\\n" is a comment up to the end of the line
983 - "#...\\n" is a comment up to the end of the line
984
984
985 Whitespace between the above elements is ignored.
985 Whitespace between the above elements is ignored.
986
986
987 A backref is either
987 A backref is either
988
988
989 - a number n, which references the node curr-n, where curr is the current
989 - a number n, which references the node curr-n, where curr is the current
990 node, or
990 node, or
991 - the name of a local tag you placed earlier using ":tag", or
991 - the name of a local tag you placed earlier using ":tag", or
992 - empty to denote the default parent.
992 - empty to denote the default parent.
993
993
994 All string valued-elements are either strictly alphanumeric, or must
994 All string valued-elements are either strictly alphanumeric, or must
995 be enclosed in double quotes ("..."), with "\\" as escape character.
995 be enclosed in double quotes ("..."), with "\\" as escape character.
996
996
997 Note that the --overwritten-file and --appended-file options imply the
997 Note that the --overwritten-file and --appended-file options imply the
998 use of "HGMERGE=internal:local" during DAG buildup.
998 use of "HGMERGE=internal:local" during DAG buildup.
999 """
999 """
1000
1000
1001 if not (mergeable_file or appended_file or overwritten_file or new_file):
1001 if not (mergeable_file or appended_file or overwritten_file or new_file):
1002 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
1002 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
1003
1003
1004 if len(repo.changelog) > 0:
1004 if len(repo.changelog) > 0:
1005 raise util.Abort(_('repository is not empty'))
1005 raise util.Abort(_('repository is not empty'))
1006
1006
1007 if overwritten_file or appended_file:
1007 if overwritten_file or appended_file:
1008 # we don't want to fail in merges during buildup
1008 # we don't want to fail in merges during buildup
1009 os.environ['HGMERGE'] = 'internal:local'
1009 os.environ['HGMERGE'] = 'internal:local'
1010
1010
1011 def writefile(fname, text, fmode="wb"):
1011 def writefile(fname, text, fmode="wb"):
1012 f = open(fname, fmode)
1012 f = open(fname, fmode)
1013 try:
1013 try:
1014 f.write(text)
1014 f.write(text)
1015 finally:
1015 finally:
1016 f.close()
1016 f.close()
1017
1017
1018 if mergeable_file:
1018 if mergeable_file:
1019 linesperrev = 2
1019 linesperrev = 2
1020 # determine number of revs in DAG
1020 # determine number of revs in DAG
1021 n = 0
1021 n = 0
1022 for type, data in dagparser.parsedag(text):
1022 for type, data in dagparser.parsedag(text):
1023 if type == 'n':
1023 if type == 'n':
1024 n += 1
1024 n += 1
1025 # make a file with k lines per rev
1025 # make a file with k lines per rev
1026 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
1026 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
1027 + "\n")
1027 + "\n")
1028
1028
1029 at = -1
1029 at = -1
1030 atbranch = 'default'
1030 atbranch = 'default'
1031 for type, data in dagparser.parsedag(text):
1031 for type, data in dagparser.parsedag(text):
1032 if type == 'n':
1032 if type == 'n':
1033 ui.status('node %s\n' % str(data))
1033 ui.status('node %s\n' % str(data))
1034 id, ps = data
1034 id, ps = data
1035 p1 = ps[0]
1035 p1 = ps[0]
1036 if p1 != at:
1036 if p1 != at:
1037 update(ui, repo, node=str(p1), clean=True)
1037 update(ui, repo, node=str(p1), clean=True)
1038 at = p1
1038 at = p1
1039 if repo.dirstate.branch() != atbranch:
1039 if repo.dirstate.branch() != atbranch:
1040 branch(ui, repo, atbranch, force=True)
1040 branch(ui, repo, atbranch, force=True)
1041 if len(ps) > 1:
1041 if len(ps) > 1:
1042 p2 = ps[1]
1042 p2 = ps[1]
1043 merge(ui, repo, node=p2)
1043 merge(ui, repo, node=p2)
1044
1044
1045 if mergeable_file:
1045 if mergeable_file:
1046 f = open("mf", "rb+")
1046 f = open("mf", "rb+")
1047 try:
1047 try:
1048 lines = f.read().split("\n")
1048 lines = f.read().split("\n")
1049 lines[id * linesperrev] += " r%i" % id
1049 lines[id * linesperrev] += " r%i" % id
1050 f.seek(0)
1050 f.seek(0)
1051 f.write("\n".join(lines))
1051 f.write("\n".join(lines))
1052 finally:
1052 finally:
1053 f.close()
1053 f.close()
1054
1054
1055 if appended_file:
1055 if appended_file:
1056 writefile("af", "r%i\n" % id, "ab")
1056 writefile("af", "r%i\n" % id, "ab")
1057
1057
1058 if overwritten_file:
1058 if overwritten_file:
1059 writefile("of", "r%i\n" % id)
1059 writefile("of", "r%i\n" % id)
1060
1060
1061 if new_file:
1061 if new_file:
1062 writefile("nf%i" % id, "r%i\n" % id)
1062 writefile("nf%i" % id, "r%i\n" % id)
1063
1063
1064 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
1064 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
1065 at = id
1065 at = id
1066 elif type == 'l':
1066 elif type == 'l':
1067 id, name = data
1067 id, name = data
1068 ui.status('tag %s\n' % name)
1068 ui.status('tag %s\n' % name)
1069 tag(ui, repo, name, local=True)
1069 tag(ui, repo, name, local=True)
1070 elif type == 'a':
1070 elif type == 'a':
1071 ui.status('branch %s\n' % data)
1071 ui.status('branch %s\n' % data)
1072 atbranch = data
1072 atbranch = data
1073 elif type in 'cC':
1073 elif type in 'cC':
1074 r = util.system(data, cwd=repo.root)
1074 r = util.system(data, cwd=repo.root)
1075 if r:
1075 if r:
1076 desc, r = util.explain_exit(r)
1076 desc, r = util.explain_exit(r)
1077 raise util.Abort(_('%s command %s') % (data, desc))
1077 raise util.Abort(_('%s command %s') % (data, desc))
1078
1078
1079 def debugcommands(ui, cmd='', *args):
1079 def debugcommands(ui, cmd='', *args):
1080 """list all available commands and options"""
1080 """list all available commands and options"""
1081 for cmd, vals in sorted(table.iteritems()):
1081 for cmd, vals in sorted(table.iteritems()):
1082 cmd = cmd.split('|')[0].strip('^')
1082 cmd = cmd.split('|')[0].strip('^')
1083 opts = ', '.join([i[1] for i in vals[1]])
1083 opts = ', '.join([i[1] for i in vals[1]])
1084 ui.write('%s: %s\n' % (cmd, opts))
1084 ui.write('%s: %s\n' % (cmd, opts))
1085
1085
1086 def debugcomplete(ui, cmd='', **opts):
1086 def debugcomplete(ui, cmd='', **opts):
1087 """returns the completion list associated with the given command"""
1087 """returns the completion list associated with the given command"""
1088
1088
1089 if opts.get('options'):
1089 if opts.get('options'):
1090 options = []
1090 options = []
1091 otables = [globalopts]
1091 otables = [globalopts]
1092 if cmd:
1092 if cmd:
1093 aliases, entry = cmdutil.findcmd(cmd, table, False)
1093 aliases, entry = cmdutil.findcmd(cmd, table, False)
1094 otables.append(entry[1])
1094 otables.append(entry[1])
1095 for t in otables:
1095 for t in otables:
1096 for o in t:
1096 for o in t:
1097 if "(DEPRECATED)" in o[3]:
1097 if "(DEPRECATED)" in o[3]:
1098 continue
1098 continue
1099 if o[0]:
1099 if o[0]:
1100 options.append('-%s' % o[0])
1100 options.append('-%s' % o[0])
1101 options.append('--%s' % o[1])
1101 options.append('--%s' % o[1])
1102 ui.write("%s\n" % "\n".join(options))
1102 ui.write("%s\n" % "\n".join(options))
1103 return
1103 return
1104
1104
1105 cmdlist = cmdutil.findpossible(cmd, table)
1105 cmdlist = cmdutil.findpossible(cmd, table)
1106 if ui.verbose:
1106 if ui.verbose:
1107 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1107 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1108 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1108 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1109
1109
1110 def debugfsinfo(ui, path = "."):
1110 def debugfsinfo(ui, path = "."):
1111 """show information detected about current filesystem"""
1111 """show information detected about current filesystem"""
1112 open('.debugfsinfo', 'w').write('')
1112 open('.debugfsinfo', 'w').write('')
1113 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1113 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1114 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1114 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1115 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1115 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1116 and 'yes' or 'no'))
1116 and 'yes' or 'no'))
1117 os.unlink('.debugfsinfo')
1117 os.unlink('.debugfsinfo')
1118
1118
1119 def debugrebuildstate(ui, repo, rev="tip"):
1119 def debugrebuildstate(ui, repo, rev="tip"):
1120 """rebuild the dirstate as it would look like for the given revision"""
1120 """rebuild the dirstate as it would look like for the given revision"""
1121 ctx = cmdutil.revsingle(repo, rev)
1121 ctx = cmdutil.revsingle(repo, rev)
1122 wlock = repo.wlock()
1122 wlock = repo.wlock()
1123 try:
1123 try:
1124 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1124 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1125 finally:
1125 finally:
1126 wlock.release()
1126 wlock.release()
1127
1127
1128 def debugcheckstate(ui, repo):
1128 def debugcheckstate(ui, repo):
1129 """validate the correctness of the current dirstate"""
1129 """validate the correctness of the current dirstate"""
1130 parent1, parent2 = repo.dirstate.parents()
1130 parent1, parent2 = repo.dirstate.parents()
1131 m1 = repo[parent1].manifest()
1131 m1 = repo[parent1].manifest()
1132 m2 = repo[parent2].manifest()
1132 m2 = repo[parent2].manifest()
1133 errors = 0
1133 errors = 0
1134 for f in repo.dirstate:
1134 for f in repo.dirstate:
1135 state = repo.dirstate[f]
1135 state = repo.dirstate[f]
1136 if state in "nr" and f not in m1:
1136 if state in "nr" and f not in m1:
1137 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1137 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1138 errors += 1
1138 errors += 1
1139 if state in "a" and f in m1:
1139 if state in "a" and f in m1:
1140 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1140 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1141 errors += 1
1141 errors += 1
1142 if state in "m" and f not in m1 and f not in m2:
1142 if state in "m" and f not in m1 and f not in m2:
1143 ui.warn(_("%s in state %s, but not in either manifest\n") %
1143 ui.warn(_("%s in state %s, but not in either manifest\n") %
1144 (f, state))
1144 (f, state))
1145 errors += 1
1145 errors += 1
1146 for f in m1:
1146 for f in m1:
1147 state = repo.dirstate[f]
1147 state = repo.dirstate[f]
1148 if state not in "nrm":
1148 if state not in "nrm":
1149 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1149 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1150 errors += 1
1150 errors += 1
1151 if errors:
1151 if errors:
1152 error = _(".hg/dirstate inconsistent with current parent's manifest")
1152 error = _(".hg/dirstate inconsistent with current parent's manifest")
1153 raise util.Abort(error)
1153 raise util.Abort(error)
1154
1154
1155 def showconfig(ui, repo, *values, **opts):
1155 def showconfig(ui, repo, *values, **opts):
1156 """show combined config settings from all hgrc files
1156 """show combined config settings from all hgrc files
1157
1157
1158 With no arguments, print names and values of all config items.
1158 With no arguments, print names and values of all config items.
1159
1159
1160 With one argument of the form section.name, print just the value
1160 With one argument of the form section.name, print just the value
1161 of that config item.
1161 of that config item.
1162
1162
1163 With multiple arguments, print names and values of all config
1163 With multiple arguments, print names and values of all config
1164 items with matching section names.
1164 items with matching section names.
1165
1165
1166 With --debug, the source (filename and line number) is printed
1166 With --debug, the source (filename and line number) is printed
1167 for each config item.
1167 for each config item.
1168
1168
1169 Returns 0 on success.
1169 Returns 0 on success.
1170 """
1170 """
1171
1171
1172 for f in util.rcpath():
1172 for f in util.rcpath():
1173 ui.debug(_('read config from: %s\n') % f)
1173 ui.debug(_('read config from: %s\n') % f)
1174 untrusted = bool(opts.get('untrusted'))
1174 untrusted = bool(opts.get('untrusted'))
1175 if values:
1175 if values:
1176 sections = [v for v in values if '.' not in v]
1176 sections = [v for v in values if '.' not in v]
1177 items = [v for v in values if '.' in v]
1177 items = [v for v in values if '.' in v]
1178 if len(items) > 1 or items and sections:
1178 if len(items) > 1 or items and sections:
1179 raise util.Abort(_('only one config item permitted'))
1179 raise util.Abort(_('only one config item permitted'))
1180 for section, name, value in ui.walkconfig(untrusted=untrusted):
1180 for section, name, value in ui.walkconfig(untrusted=untrusted):
1181 sectname = section + '.' + name
1181 sectname = section + '.' + name
1182 if values:
1182 if values:
1183 for v in values:
1183 for v in values:
1184 if v == section:
1184 if v == section:
1185 ui.debug('%s: ' %
1185 ui.debug('%s: ' %
1186 ui.configsource(section, name, untrusted))
1186 ui.configsource(section, name, untrusted))
1187 ui.write('%s=%s\n' % (sectname, value))
1187 ui.write('%s=%s\n' % (sectname, value))
1188 elif v == sectname:
1188 elif v == sectname:
1189 ui.debug('%s: ' %
1189 ui.debug('%s: ' %
1190 ui.configsource(section, name, untrusted))
1190 ui.configsource(section, name, untrusted))
1191 ui.write(value, '\n')
1191 ui.write(value, '\n')
1192 else:
1192 else:
1193 ui.debug('%s: ' %
1193 ui.debug('%s: ' %
1194 ui.configsource(section, name, untrusted))
1194 ui.configsource(section, name, untrusted))
1195 ui.write('%s=%s\n' % (sectname, value))
1195 ui.write('%s=%s\n' % (sectname, value))
1196
1196
1197 def debugpushkey(ui, repopath, namespace, *keyinfo):
1197 def debugpushkey(ui, repopath, namespace, *keyinfo):
1198 '''access the pushkey key/value protocol
1198 '''access the pushkey key/value protocol
1199
1199
1200 With two args, list the keys in the given namespace.
1200 With two args, list the keys in the given namespace.
1201
1201
1202 With five args, set a key to new if it currently is set to old.
1202 With five args, set a key to new if it currently is set to old.
1203 Reports success or failure.
1203 Reports success or failure.
1204 '''
1204 '''
1205
1205
1206 target = hg.repository(ui, repopath)
1206 target = hg.repository(ui, repopath)
1207 if keyinfo:
1207 if keyinfo:
1208 key, old, new = keyinfo
1208 key, old, new = keyinfo
1209 r = target.pushkey(namespace, key, old, new)
1209 r = target.pushkey(namespace, key, old, new)
1210 ui.status(str(r) + '\n')
1210 ui.status(str(r) + '\n')
1211 return not r
1211 return not r
1212 else:
1212 else:
1213 for k, v in target.listkeys(namespace).iteritems():
1213 for k, v in target.listkeys(namespace).iteritems():
1214 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1214 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1215 v.encode('string-escape')))
1215 v.encode('string-escape')))
1216
1216
1217 def debugrevspec(ui, repo, expr):
1217 def debugrevspec(ui, repo, expr):
1218 '''parse and apply a revision specification'''
1218 '''parse and apply a revision specification'''
1219 if ui.verbose:
1219 if ui.verbose:
1220 tree = revset.parse(expr)
1220 tree = revset.parse(expr)
1221 ui.note(tree, "\n")
1221 ui.note(tree, "\n")
1222 func = revset.match(expr)
1222 func = revset.match(expr)
1223 for c in func(repo, range(len(repo))):
1223 for c in func(repo, range(len(repo))):
1224 ui.write("%s\n" % c)
1224 ui.write("%s\n" % c)
1225
1225
1226 def debugsetparents(ui, repo, rev1, rev2=None):
1226 def debugsetparents(ui, repo, rev1, rev2=None):
1227 """manually set the parents of the current working directory
1227 """manually set the parents of the current working directory
1228
1228
1229 This is useful for writing repository conversion tools, but should
1229 This is useful for writing repository conversion tools, but should
1230 be used with care.
1230 be used with care.
1231
1231
1232 Returns 0 on success.
1232 Returns 0 on success.
1233 """
1233 """
1234
1234
1235 r1 = cmdutil.revsingle(repo, rev1).node()
1235 r1 = cmdutil.revsingle(repo, rev1).node()
1236 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1236 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1237
1237
1238 wlock = repo.wlock()
1238 wlock = repo.wlock()
1239 try:
1239 try:
1240 repo.dirstate.setparents(r1, r2)
1240 repo.dirstate.setparents(r1, r2)
1241 finally:
1241 finally:
1242 wlock.release()
1242 wlock.release()
1243
1243
1244 def debugstate(ui, repo, nodates=None):
1244 def debugstate(ui, repo, nodates=None):
1245 """show the contents of the current dirstate"""
1245 """show the contents of the current dirstate"""
1246 timestr = ""
1246 timestr = ""
1247 showdate = not nodates
1247 showdate = not nodates
1248 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1248 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1249 if showdate:
1249 if showdate:
1250 if ent[3] == -1:
1250 if ent[3] == -1:
1251 # Pad or slice to locale representation
1251 # Pad or slice to locale representation
1252 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1252 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1253 time.localtime(0)))
1253 time.localtime(0)))
1254 timestr = 'unset'
1254 timestr = 'unset'
1255 timestr = (timestr[:locale_len] +
1255 timestr = (timestr[:locale_len] +
1256 ' ' * (locale_len - len(timestr)))
1256 ' ' * (locale_len - len(timestr)))
1257 else:
1257 else:
1258 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1258 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1259 time.localtime(ent[3]))
1259 time.localtime(ent[3]))
1260 if ent[1] & 020000:
1260 if ent[1] & 020000:
1261 mode = 'lnk'
1261 mode = 'lnk'
1262 else:
1262 else:
1263 mode = '%3o' % (ent[1] & 0777)
1263 mode = '%3o' % (ent[1] & 0777)
1264 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1264 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1265 for f in repo.dirstate.copies():
1265 for f in repo.dirstate.copies():
1266 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1266 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1267
1267
1268 def debugsub(ui, repo, rev=None):
1268 def debugsub(ui, repo, rev=None):
1269 ctx = cmdutil.revsingle(repo, rev, None)
1269 ctx = cmdutil.revsingle(repo, rev, None)
1270 for k, v in sorted(ctx.substate.items()):
1270 for k, v in sorted(ctx.substate.items()):
1271 ui.write('path %s\n' % k)
1271 ui.write('path %s\n' % k)
1272 ui.write(' source %s\n' % v[0])
1272 ui.write(' source %s\n' % v[0])
1273 ui.write(' revision %s\n' % v[1])
1273 ui.write(' revision %s\n' % v[1])
1274
1274
1275 def debugdag(ui, repo, file_=None, *revs, **opts):
1275 def debugdag(ui, repo, file_=None, *revs, **opts):
1276 """format the changelog or an index DAG as a concise textual description
1276 """format the changelog or an index DAG as a concise textual description
1277
1277
1278 If you pass a revlog index, the revlog's DAG is emitted. If you list
1278 If you pass a revlog index, the revlog's DAG is emitted. If you list
1279 revision numbers, they get labelled in the output as rN.
1279 revision numbers, they get labelled in the output as rN.
1280
1280
1281 Otherwise, the changelog DAG of the current repo is emitted.
1281 Otherwise, the changelog DAG of the current repo is emitted.
1282 """
1282 """
1283 spaces = opts.get('spaces')
1283 spaces = opts.get('spaces')
1284 dots = opts.get('dots')
1284 dots = opts.get('dots')
1285 if file_:
1285 if file_:
1286 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1286 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1287 revs = set((int(r) for r in revs))
1287 revs = set((int(r) for r in revs))
1288 def events():
1288 def events():
1289 for r in rlog:
1289 for r in rlog:
1290 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1290 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1291 if r in revs:
1291 if r in revs:
1292 yield 'l', (r, "r%i" % r)
1292 yield 'l', (r, "r%i" % r)
1293 elif repo:
1293 elif repo:
1294 cl = repo.changelog
1294 cl = repo.changelog
1295 tags = opts.get('tags')
1295 tags = opts.get('tags')
1296 branches = opts.get('branches')
1296 branches = opts.get('branches')
1297 if tags:
1297 if tags:
1298 labels = {}
1298 labels = {}
1299 for l, n in repo.tags().items():
1299 for l, n in repo.tags().items():
1300 labels.setdefault(cl.rev(n), []).append(l)
1300 labels.setdefault(cl.rev(n), []).append(l)
1301 def events():
1301 def events():
1302 b = "default"
1302 b = "default"
1303 for r in cl:
1303 for r in cl:
1304 if branches:
1304 if branches:
1305 newb = cl.read(cl.node(r))[5]['branch']
1305 newb = cl.read(cl.node(r))[5]['branch']
1306 if newb != b:
1306 if newb != b:
1307 yield 'a', newb
1307 yield 'a', newb
1308 b = newb
1308 b = newb
1309 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1309 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1310 if tags:
1310 if tags:
1311 ls = labels.get(r)
1311 ls = labels.get(r)
1312 if ls:
1312 if ls:
1313 for l in ls:
1313 for l in ls:
1314 yield 'l', (r, l)
1314 yield 'l', (r, l)
1315 else:
1315 else:
1316 raise util.Abort(_('need repo for changelog dag'))
1316 raise util.Abort(_('need repo for changelog dag'))
1317
1317
1318 for line in dagparser.dagtextlines(events(),
1318 for line in dagparser.dagtextlines(events(),
1319 addspaces=spaces,
1319 addspaces=spaces,
1320 wraplabels=True,
1320 wraplabels=True,
1321 wrapannotations=True,
1321 wrapannotations=True,
1322 wrapnonlinear=dots,
1322 wrapnonlinear=dots,
1323 usedots=dots,
1323 usedots=dots,
1324 maxlinewidth=70):
1324 maxlinewidth=70):
1325 ui.write(line)
1325 ui.write(line)
1326 ui.write("\n")
1326 ui.write("\n")
1327
1327
1328 def debugdata(ui, repo, file_, rev):
1328 def debugdata(ui, repo, file_, rev):
1329 """dump the contents of a data file revision"""
1329 """dump the contents of a data file revision"""
1330 r = None
1330 r = None
1331 if repo:
1331 if repo:
1332 filelog = repo.file(file_)
1332 filelog = repo.file(file_)
1333 if len(filelog):
1333 if len(filelog):
1334 r = filelog
1334 r = filelog
1335 if not r:
1335 if not r:
1336 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1336 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1337 try:
1337 try:
1338 ui.write(r.revision(r.lookup(rev)))
1338 ui.write(r.revision(r.lookup(rev)))
1339 except KeyError:
1339 except KeyError:
1340 raise util.Abort(_('invalid revision identifier %s') % rev)
1340 raise util.Abort(_('invalid revision identifier %s') % rev)
1341
1341
1342 def debugdate(ui, date, range=None, **opts):
1342 def debugdate(ui, date, range=None, **opts):
1343 """parse and display a date"""
1343 """parse and display a date"""
1344 if opts["extended"]:
1344 if opts["extended"]:
1345 d = util.parsedate(date, util.extendeddateformats)
1345 d = util.parsedate(date, util.extendeddateformats)
1346 else:
1346 else:
1347 d = util.parsedate(date)
1347 d = util.parsedate(date)
1348 ui.write("internal: %s %s\n" % d)
1348 ui.write("internal: %s %s\n" % d)
1349 ui.write("standard: %s\n" % util.datestr(d))
1349 ui.write("standard: %s\n" % util.datestr(d))
1350 if range:
1350 if range:
1351 m = util.matchdate(range)
1351 m = util.matchdate(range)
1352 ui.write("match: %s\n" % m(d[0]))
1352 ui.write("match: %s\n" % m(d[0]))
1353
1353
1354 def debugignore(ui, repo, *values, **opts):
1355 """display the combined ignore pattern"""
1356 ignore = repo.dirstate._ignore
1357 ui.write("%s\n" % ignore.includepat)
1358
1354 def debugindex(ui, repo, file_, **opts):
1359 def debugindex(ui, repo, file_, **opts):
1355 """dump the contents of an index file"""
1360 """dump the contents of an index file"""
1356 r = None
1361 r = None
1357 if repo:
1362 if repo:
1358 filelog = repo.file(file_)
1363 filelog = repo.file(file_)
1359 if len(filelog):
1364 if len(filelog):
1360 r = filelog
1365 r = filelog
1361
1366
1362 format = opts.get('format', 0)
1367 format = opts.get('format', 0)
1363 if format not in (0, 1):
1368 if format not in (0, 1):
1364 raise util.Abort("unknown format %d" % format)
1369 raise util.Abort("unknown format %d" % format)
1365
1370
1366 if not r:
1371 if not r:
1367 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1372 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1368
1373
1369 if format == 0:
1374 if format == 0:
1370 ui.write(" rev offset length base linkrev"
1375 ui.write(" rev offset length base linkrev"
1371 " nodeid p1 p2\n")
1376 " nodeid p1 p2\n")
1372 elif format == 1:
1377 elif format == 1:
1373 ui.write(" rev flag offset length"
1378 ui.write(" rev flag offset length"
1374 " size base link p1 p2 nodeid\n")
1379 " size base link p1 p2 nodeid\n")
1375
1380
1376 for i in r:
1381 for i in r:
1377 node = r.node(i)
1382 node = r.node(i)
1378 if format == 0:
1383 if format == 0:
1379 try:
1384 try:
1380 pp = r.parents(node)
1385 pp = r.parents(node)
1381 except:
1386 except:
1382 pp = [nullid, nullid]
1387 pp = [nullid, nullid]
1383 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1388 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1384 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),
1385 short(node), short(pp[0]), short(pp[1])))
1390 short(node), short(pp[0]), short(pp[1])))
1386 elif format == 1:
1391 elif format == 1:
1387 pr = r.parentrevs(i)
1392 pr = r.parentrevs(i)
1388 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" % (
1389 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),
1390 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)))
1391
1396
1392 def debugindexdot(ui, repo, file_):
1397 def debugindexdot(ui, repo, file_):
1393 """dump an index DAG as a graphviz dot file"""
1398 """dump an index DAG as a graphviz dot file"""
1394 r = None
1399 r = None
1395 if repo:
1400 if repo:
1396 filelog = repo.file(file_)
1401 filelog = repo.file(file_)
1397 if len(filelog):
1402 if len(filelog):
1398 r = filelog
1403 r = filelog
1399 if not r:
1404 if not r:
1400 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1405 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1401 ui.write("digraph G {\n")
1406 ui.write("digraph G {\n")
1402 for i in r:
1407 for i in r:
1403 node = r.node(i)
1408 node = r.node(i)
1404 pp = r.parents(node)
1409 pp = r.parents(node)
1405 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1410 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1406 if pp[1] != nullid:
1411 if pp[1] != nullid:
1407 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1412 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1408 ui.write("}\n")
1413 ui.write("}\n")
1409
1414
1410 def debuginstall(ui):
1415 def debuginstall(ui):
1411 '''test Mercurial installation
1416 '''test Mercurial installation
1412
1417
1413 Returns 0 on success.
1418 Returns 0 on success.
1414 '''
1419 '''
1415
1420
1416 def writetemp(contents):
1421 def writetemp(contents):
1417 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1422 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1418 f = os.fdopen(fd, "wb")
1423 f = os.fdopen(fd, "wb")
1419 f.write(contents)
1424 f.write(contents)
1420 f.close()
1425 f.close()
1421 return name
1426 return name
1422
1427
1423 problems = 0
1428 problems = 0
1424
1429
1425 # encoding
1430 # encoding
1426 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1431 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1427 try:
1432 try:
1428 encoding.fromlocal("test")
1433 encoding.fromlocal("test")
1429 except util.Abort, inst:
1434 except util.Abort, inst:
1430 ui.write(" %s\n" % inst)
1435 ui.write(" %s\n" % inst)
1431 ui.write(_(" (check that your locale is properly set)\n"))
1436 ui.write(_(" (check that your locale is properly set)\n"))
1432 problems += 1
1437 problems += 1
1433
1438
1434 # compiled modules
1439 # compiled modules
1435 ui.status(_("Checking installed modules (%s)...\n")
1440 ui.status(_("Checking installed modules (%s)...\n")
1436 % os.path.dirname(__file__))
1441 % os.path.dirname(__file__))
1437 try:
1442 try:
1438 import bdiff, mpatch, base85, osutil
1443 import bdiff, mpatch, base85, osutil
1439 except Exception, inst:
1444 except Exception, inst:
1440 ui.write(" %s\n" % inst)
1445 ui.write(" %s\n" % inst)
1441 ui.write(_(" One or more extensions could not be found"))
1446 ui.write(_(" One or more extensions could not be found"))
1442 ui.write(_(" (check that you compiled the extensions)\n"))
1447 ui.write(_(" (check that you compiled the extensions)\n"))
1443 problems += 1
1448 problems += 1
1444
1449
1445 # templates
1450 # templates
1446 ui.status(_("Checking templates...\n"))
1451 ui.status(_("Checking templates...\n"))
1447 try:
1452 try:
1448 import templater
1453 import templater
1449 templater.templater(templater.templatepath("map-cmdline.default"))
1454 templater.templater(templater.templatepath("map-cmdline.default"))
1450 except Exception, inst:
1455 except Exception, inst:
1451 ui.write(" %s\n" % inst)
1456 ui.write(" %s\n" % inst)
1452 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1457 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1453 problems += 1
1458 problems += 1
1454
1459
1455 # patch
1460 # patch
1456 ui.status(_("Checking patch...\n"))
1461 ui.status(_("Checking patch...\n"))
1457 patchproblems = 0
1462 patchproblems = 0
1458 a = "1\n2\n3\n4\n"
1463 a = "1\n2\n3\n4\n"
1459 b = "1\n2\n3\ninsert\n4\n"
1464 b = "1\n2\n3\ninsert\n4\n"
1460 fa = writetemp(a)
1465 fa = writetemp(a)
1461 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1466 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1462 os.path.basename(fa))
1467 os.path.basename(fa))
1463 fd = writetemp(d)
1468 fd = writetemp(d)
1464
1469
1465 files = {}
1470 files = {}
1466 try:
1471 try:
1467 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1472 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1468 except util.Abort, e:
1473 except util.Abort, e:
1469 ui.write(_(" patch call failed:\n"))
1474 ui.write(_(" patch call failed:\n"))
1470 ui.write(" " + str(e) + "\n")
1475 ui.write(" " + str(e) + "\n")
1471 patchproblems += 1
1476 patchproblems += 1
1472 else:
1477 else:
1473 if list(files) != [os.path.basename(fa)]:
1478 if list(files) != [os.path.basename(fa)]:
1474 ui.write(_(" unexpected patch output!\n"))
1479 ui.write(_(" unexpected patch output!\n"))
1475 patchproblems += 1
1480 patchproblems += 1
1476 a = open(fa).read()
1481 a = open(fa).read()
1477 if a != b:
1482 if a != b:
1478 ui.write(_(" patch test failed!\n"))
1483 ui.write(_(" patch test failed!\n"))
1479 patchproblems += 1
1484 patchproblems += 1
1480
1485
1481 if patchproblems:
1486 if patchproblems:
1482 if ui.config('ui', 'patch'):
1487 if ui.config('ui', 'patch'):
1483 ui.write(_(" (Current patch tool may be incompatible with patch,"
1488 ui.write(_(" (Current patch tool may be incompatible with patch,"
1484 " or misconfigured. Please check your configuration"
1489 " or misconfigured. Please check your configuration"
1485 " file)\n"))
1490 " file)\n"))
1486 else:
1491 else:
1487 ui.write(_(" Internal patcher failure, please report this error"
1492 ui.write(_(" Internal patcher failure, please report this error"
1488 " to http://mercurial.selenic.com/wiki/BugTracker\n"))
1493 " to http://mercurial.selenic.com/wiki/BugTracker\n"))
1489 problems += patchproblems
1494 problems += patchproblems
1490
1495
1491 os.unlink(fa)
1496 os.unlink(fa)
1492 os.unlink(fd)
1497 os.unlink(fd)
1493
1498
1494 # editor
1499 # editor
1495 ui.status(_("Checking commit editor...\n"))
1500 ui.status(_("Checking commit editor...\n"))
1496 editor = ui.geteditor()
1501 editor = ui.geteditor()
1497 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])
1498 if not cmdpath:
1503 if not cmdpath:
1499 if editor == 'vi':
1504 if editor == 'vi':
1500 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"))
1501 ui.write(_(" (specify a commit editor in your configuration"
1506 ui.write(_(" (specify a commit editor in your configuration"
1502 " file)\n"))
1507 " file)\n"))
1503 else:
1508 else:
1504 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1509 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1505 ui.write(_(" (specify a commit editor in your configuration"
1510 ui.write(_(" (specify a commit editor in your configuration"
1506 " file)\n"))
1511 " file)\n"))
1507 problems += 1
1512 problems += 1
1508
1513
1509 # check username
1514 # check username
1510 ui.status(_("Checking username...\n"))
1515 ui.status(_("Checking username...\n"))
1511 try:
1516 try:
1512 ui.username()
1517 ui.username()
1513 except util.Abort, e:
1518 except util.Abort, e:
1514 ui.write(" %s\n" % e)
1519 ui.write(" %s\n" % e)
1515 ui.write(_(" (specify a username in your configuration file)\n"))
1520 ui.write(_(" (specify a username in your configuration file)\n"))
1516 problems += 1
1521 problems += 1
1517
1522
1518 if not problems:
1523 if not problems:
1519 ui.status(_("No problems detected\n"))
1524 ui.status(_("No problems detected\n"))
1520 else:
1525 else:
1521 ui.write(_("%s problems detected,"
1526 ui.write(_("%s problems detected,"
1522 " please check your install!\n") % problems)
1527 " please check your install!\n") % problems)
1523
1528
1524 return problems
1529 return problems
1525
1530
1526 def debugrename(ui, repo, file1, *pats, **opts):
1531 def debugrename(ui, repo, file1, *pats, **opts):
1527 """dump rename information"""
1532 """dump rename information"""
1528
1533
1529 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1534 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1530 m = cmdutil.match(repo, (file1,) + pats, opts)
1535 m = cmdutil.match(repo, (file1,) + pats, opts)
1531 for abs in ctx.walk(m):
1536 for abs in ctx.walk(m):
1532 fctx = ctx[abs]
1537 fctx = ctx[abs]
1533 o = fctx.filelog().renamed(fctx.filenode())
1538 o = fctx.filelog().renamed(fctx.filenode())
1534 rel = m.rel(abs)
1539 rel = m.rel(abs)
1535 if o:
1540 if o:
1536 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])))
1537 else:
1542 else:
1538 ui.write(_("%s not renamed\n") % rel)
1543 ui.write(_("%s not renamed\n") % rel)
1539
1544
1540 def debugwalk(ui, repo, *pats, **opts):
1545 def debugwalk(ui, repo, *pats, **opts):
1541 """show how files match on given patterns"""
1546 """show how files match on given patterns"""
1542 m = cmdutil.match(repo, pats, opts)
1547 m = cmdutil.match(repo, pats, opts)
1543 items = list(repo.walk(m))
1548 items = list(repo.walk(m))
1544 if not items:
1549 if not items:
1545 return
1550 return
1546 fmt = 'f %%-%ds %%-%ds %%s' % (
1551 fmt = 'f %%-%ds %%-%ds %%s' % (
1547 max([len(abs) for abs in items]),
1552 max([len(abs) for abs in items]),
1548 max([len(m.rel(abs)) for abs in items]))
1553 max([len(m.rel(abs)) for abs in items]))
1549 for abs in items:
1554 for abs in items:
1550 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 '')
1551 ui.write("%s\n" % line.rstrip())
1556 ui.write("%s\n" % line.rstrip())
1552
1557
1553 def diff(ui, repo, *pats, **opts):
1558 def diff(ui, repo, *pats, **opts):
1554 """diff repository (or selected files)
1559 """diff repository (or selected files)
1555
1560
1556 Show differences between revisions for the specified files.
1561 Show differences between revisions for the specified files.
1557
1562
1558 Differences between files are shown using the unified diff format.
1563 Differences between files are shown using the unified diff format.
1559
1564
1560 .. note::
1565 .. note::
1561 diff may generate unexpected results for merges, as it will
1566 diff may generate unexpected results for merges, as it will
1562 default to comparing against the working directory's first
1567 default to comparing against the working directory's first
1563 parent changeset if no revisions are specified.
1568 parent changeset if no revisions are specified.
1564
1569
1565 When two revision arguments are given, then changes are shown
1570 When two revision arguments are given, then changes are shown
1566 between those revisions. If only one revision is specified then
1571 between those revisions. If only one revision is specified then
1567 that revision is compared to the working directory, and, when no
1572 that revision is compared to the working directory, and, when no
1568 revisions are specified, the working directory files are compared
1573 revisions are specified, the working directory files are compared
1569 to its parent.
1574 to its parent.
1570
1575
1571 Alternatively you can specify -c/--change with a revision to see
1576 Alternatively you can specify -c/--change with a revision to see
1572 the changes in that changeset relative to its first parent.
1577 the changes in that changeset relative to its first parent.
1573
1578
1574 Without the -a/--text option, diff will avoid generating diffs of
1579 Without the -a/--text option, diff will avoid generating diffs of
1575 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
1576 anyway, probably with undesirable results.
1581 anyway, probably with undesirable results.
1577
1582
1578 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
1579 format. For more information, read :hg:`help diffs`.
1584 format. For more information, read :hg:`help diffs`.
1580
1585
1581 Returns 0 on success.
1586 Returns 0 on success.
1582 """
1587 """
1583
1588
1584 revs = opts.get('rev')
1589 revs = opts.get('rev')
1585 change = opts.get('change')
1590 change = opts.get('change')
1586 stat = opts.get('stat')
1591 stat = opts.get('stat')
1587 reverse = opts.get('reverse')
1592 reverse = opts.get('reverse')
1588
1593
1589 if revs and change:
1594 if revs and change:
1590 msg = _('cannot specify --rev and --change at the same time')
1595 msg = _('cannot specify --rev and --change at the same time')
1591 raise util.Abort(msg)
1596 raise util.Abort(msg)
1592 elif change:
1597 elif change:
1593 node2 = repo.lookup(change)
1598 node2 = repo.lookup(change)
1594 node1 = repo[node2].parents()[0].node()
1599 node1 = repo[node2].parents()[0].node()
1595 else:
1600 else:
1596 node1, node2 = cmdutil.revpair(repo, revs)
1601 node1, node2 = cmdutil.revpair(repo, revs)
1597
1602
1598 if reverse:
1603 if reverse:
1599 node1, node2 = node2, node1
1604 node1, node2 = node2, node1
1600
1605
1601 diffopts = patch.diffopts(ui, opts)
1606 diffopts = patch.diffopts(ui, opts)
1602 m = cmdutil.match(repo, pats, opts)
1607 m = cmdutil.match(repo, pats, opts)
1603 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1608 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1604 listsubrepos=opts.get('subrepos'))
1609 listsubrepos=opts.get('subrepos'))
1605
1610
1606 def export(ui, repo, *changesets, **opts):
1611 def export(ui, repo, *changesets, **opts):
1607 """dump the header and diffs for one or more changesets
1612 """dump the header and diffs for one or more changesets
1608
1613
1609 Print the changeset header and diffs for one or more revisions.
1614 Print the changeset header and diffs for one or more revisions.
1610
1615
1611 The information shown in the changeset header is: author, date,
1616 The information shown in the changeset header is: author, date,
1612 branch name (if non-default), changeset hash, parent(s) and commit
1617 branch name (if non-default), changeset hash, parent(s) and commit
1613 comment.
1618 comment.
1614
1619
1615 .. note::
1620 .. note::
1616 export may generate unexpected diff output for merge
1621 export may generate unexpected diff output for merge
1617 changesets, as it will compare the merge changeset against its
1622 changesets, as it will compare the merge changeset against its
1618 first parent only.
1623 first parent only.
1619
1624
1620 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
1621 given using a format string. The formatting rules are as follows:
1626 given using a format string. The formatting rules are as follows:
1622
1627
1623 :``%%``: literal "%" character
1628 :``%%``: literal "%" character
1624 :``%H``: changeset hash (40 hexadecimal digits)
1629 :``%H``: changeset hash (40 hexadecimal digits)
1625 :``%N``: number of patches being generated
1630 :``%N``: number of patches being generated
1626 :``%R``: changeset revision number
1631 :``%R``: changeset revision number
1627 :``%b``: basename of the exporting repository
1632 :``%b``: basename of the exporting repository
1628 :``%h``: short-form changeset hash (12 hexadecimal digits)
1633 :``%h``: short-form changeset hash (12 hexadecimal digits)
1629 :``%n``: zero-padded sequence number, starting at 1
1634 :``%n``: zero-padded sequence number, starting at 1
1630 :``%r``: zero-padded changeset revision number
1635 :``%r``: zero-padded changeset revision number
1631
1636
1632 Without the -a/--text option, export will avoid generating diffs
1637 Without the -a/--text option, export will avoid generating diffs
1633 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
1634 diff anyway, probably with undesirable results.
1639 diff anyway, probably with undesirable results.
1635
1640
1636 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
1637 format. See :hg:`help diffs` for more information.
1642 format. See :hg:`help diffs` for more information.
1638
1643
1639 With the --switch-parent option, the diff will be against the
1644 With the --switch-parent option, the diff will be against the
1640 second parent. It can be useful to review a merge.
1645 second parent. It can be useful to review a merge.
1641
1646
1642 Returns 0 on success.
1647 Returns 0 on success.
1643 """
1648 """
1644 changesets += tuple(opts.get('rev', []))
1649 changesets += tuple(opts.get('rev', []))
1645 if not changesets:
1650 if not changesets:
1646 raise util.Abort(_("export requires at least one changeset"))
1651 raise util.Abort(_("export requires at least one changeset"))
1647 revs = cmdutil.revrange(repo, changesets)
1652 revs = cmdutil.revrange(repo, changesets)
1648 if len(revs) > 1:
1653 if len(revs) > 1:
1649 ui.note(_('exporting patches:\n'))
1654 ui.note(_('exporting patches:\n'))
1650 else:
1655 else:
1651 ui.note(_('exporting patch:\n'))
1656 ui.note(_('exporting patch:\n'))
1652 cmdutil.export(repo, revs, template=opts.get('output'),
1657 cmdutil.export(repo, revs, template=opts.get('output'),
1653 switch_parent=opts.get('switch_parent'),
1658 switch_parent=opts.get('switch_parent'),
1654 opts=patch.diffopts(ui, opts))
1659 opts=patch.diffopts(ui, opts))
1655
1660
1656 def forget(ui, repo, *pats, **opts):
1661 def forget(ui, repo, *pats, **opts):
1657 """forget the specified files on the next commit
1662 """forget the specified files on the next commit
1658
1663
1659 Mark the specified files so they will no longer be tracked
1664 Mark the specified files so they will no longer be tracked
1660 after the next commit.
1665 after the next commit.
1661
1666
1662 This only removes files from the current branch, not from the
1667 This only removes files from the current branch, not from the
1663 entire project history, and it does not delete them from the
1668 entire project history, and it does not delete them from the
1664 working directory.
1669 working directory.
1665
1670
1666 To undo a forget before the next commit, see :hg:`add`.
1671 To undo a forget before the next commit, see :hg:`add`.
1667
1672
1668 Returns 0 on success.
1673 Returns 0 on success.
1669 """
1674 """
1670
1675
1671 if not pats:
1676 if not pats:
1672 raise util.Abort(_('no files specified'))
1677 raise util.Abort(_('no files specified'))
1673
1678
1674 m = cmdutil.match(repo, pats, opts)
1679 m = cmdutil.match(repo, pats, opts)
1675 s = repo.status(match=m, clean=True)
1680 s = repo.status(match=m, clean=True)
1676 forget = sorted(s[0] + s[1] + s[3] + s[6])
1681 forget = sorted(s[0] + s[1] + s[3] + s[6])
1677 errs = 0
1682 errs = 0
1678
1683
1679 for f in m.files():
1684 for f in m.files():
1680 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)):
1681 ui.warn(_('not removing %s: file is already untracked\n')
1686 ui.warn(_('not removing %s: file is already untracked\n')
1682 % m.rel(f))
1687 % m.rel(f))
1683 errs = 1
1688 errs = 1
1684
1689
1685 for f in forget:
1690 for f in forget:
1686 if ui.verbose or not m.exact(f):
1691 if ui.verbose or not m.exact(f):
1687 ui.status(_('removing %s\n') % m.rel(f))
1692 ui.status(_('removing %s\n') % m.rel(f))
1688
1693
1689 repo[None].remove(forget, unlink=False)
1694 repo[None].remove(forget, unlink=False)
1690 return errs
1695 return errs
1691
1696
1692 def grep(ui, repo, pattern, *pats, **opts):
1697 def grep(ui, repo, pattern, *pats, **opts):
1693 """search for a pattern in specified files and revisions
1698 """search for a pattern in specified files and revisions
1694
1699
1695 Search revisions of files for a regular expression.
1700 Search revisions of files for a regular expression.
1696
1701
1697 This command behaves differently than Unix grep. It only accepts
1702 This command behaves differently than Unix grep. It only accepts
1698 Python/Perl regexps. It searches repository history, not the
1703 Python/Perl regexps. It searches repository history, not the
1699 working directory. It always prints the revision number in which a
1704 working directory. It always prints the revision number in which a
1700 match appears.
1705 match appears.
1701
1706
1702 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
1703 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
1704 that contains a change in match status ("-" for a match that
1709 that contains a change in match status ("-" for a match that
1705 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),
1706 use the --all flag.
1711 use the --all flag.
1707
1712
1708 Returns 0 if a match is found, 1 otherwise.
1713 Returns 0 if a match is found, 1 otherwise.
1709 """
1714 """
1710 reflags = 0
1715 reflags = 0
1711 if opts.get('ignore_case'):
1716 if opts.get('ignore_case'):
1712 reflags |= re.I
1717 reflags |= re.I
1713 try:
1718 try:
1714 regexp = re.compile(pattern, reflags)
1719 regexp = re.compile(pattern, reflags)
1715 except re.error, inst:
1720 except re.error, inst:
1716 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1721 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1717 return 1
1722 return 1
1718 sep, eol = ':', '\n'
1723 sep, eol = ':', '\n'
1719 if opts.get('print0'):
1724 if opts.get('print0'):
1720 sep = eol = '\0'
1725 sep = eol = '\0'
1721
1726
1722 getfile = util.lrucachefunc(repo.file)
1727 getfile = util.lrucachefunc(repo.file)
1723
1728
1724 def matchlines(body):
1729 def matchlines(body):
1725 begin = 0
1730 begin = 0
1726 linenum = 0
1731 linenum = 0
1727 while True:
1732 while True:
1728 match = regexp.search(body, begin)
1733 match = regexp.search(body, begin)
1729 if not match:
1734 if not match:
1730 break
1735 break
1731 mstart, mend = match.span()
1736 mstart, mend = match.span()
1732 linenum += body.count('\n', begin, mstart) + 1
1737 linenum += body.count('\n', begin, mstart) + 1
1733 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1738 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1734 begin = body.find('\n', mend) + 1 or len(body)
1739 begin = body.find('\n', mend) + 1 or len(body)
1735 lend = begin - 1
1740 lend = begin - 1
1736 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1741 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1737
1742
1738 class linestate(object):
1743 class linestate(object):
1739 def __init__(self, line, linenum, colstart, colend):
1744 def __init__(self, line, linenum, colstart, colend):
1740 self.line = line
1745 self.line = line
1741 self.linenum = linenum
1746 self.linenum = linenum
1742 self.colstart = colstart
1747 self.colstart = colstart
1743 self.colend = colend
1748 self.colend = colend
1744
1749
1745 def __hash__(self):
1750 def __hash__(self):
1746 return hash((self.linenum, self.line))
1751 return hash((self.linenum, self.line))
1747
1752
1748 def __eq__(self, other):
1753 def __eq__(self, other):
1749 return self.line == other.line
1754 return self.line == other.line
1750
1755
1751 matches = {}
1756 matches = {}
1752 copies = {}
1757 copies = {}
1753 def grepbody(fn, rev, body):
1758 def grepbody(fn, rev, body):
1754 matches[rev].setdefault(fn, [])
1759 matches[rev].setdefault(fn, [])
1755 m = matches[rev][fn]
1760 m = matches[rev][fn]
1756 for lnum, cstart, cend, line in matchlines(body):
1761 for lnum, cstart, cend, line in matchlines(body):
1757 s = linestate(line, lnum, cstart, cend)
1762 s = linestate(line, lnum, cstart, cend)
1758 m.append(s)
1763 m.append(s)
1759
1764
1760 def difflinestates(a, b):
1765 def difflinestates(a, b):
1761 sm = difflib.SequenceMatcher(None, a, b)
1766 sm = difflib.SequenceMatcher(None, a, b)
1762 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1767 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1763 if tag == 'insert':
1768 if tag == 'insert':
1764 for i in xrange(blo, bhi):
1769 for i in xrange(blo, bhi):
1765 yield ('+', b[i])
1770 yield ('+', b[i])
1766 elif tag == 'delete':
1771 elif tag == 'delete':
1767 for i in xrange(alo, ahi):
1772 for i in xrange(alo, ahi):
1768 yield ('-', a[i])
1773 yield ('-', a[i])
1769 elif tag == 'replace':
1774 elif tag == 'replace':
1770 for i in xrange(alo, ahi):
1775 for i in xrange(alo, ahi):
1771 yield ('-', a[i])
1776 yield ('-', a[i])
1772 for i in xrange(blo, bhi):
1777 for i in xrange(blo, bhi):
1773 yield ('+', b[i])
1778 yield ('+', b[i])
1774
1779
1775 def display(fn, ctx, pstates, states):
1780 def display(fn, ctx, pstates, states):
1776 rev = ctx.rev()
1781 rev = ctx.rev()
1777 datefunc = ui.quiet and util.shortdate or util.datestr
1782 datefunc = ui.quiet and util.shortdate or util.datestr
1778 found = False
1783 found = False
1779 filerevmatches = {}
1784 filerevmatches = {}
1780 if opts.get('all'):
1785 if opts.get('all'):
1781 iter = difflinestates(pstates, states)
1786 iter = difflinestates(pstates, states)
1782 else:
1787 else:
1783 iter = [('', l) for l in states]
1788 iter = [('', l) for l in states]
1784 for change, l in iter:
1789 for change, l in iter:
1785 cols = [fn, str(rev)]
1790 cols = [fn, str(rev)]
1786 before, match, after = None, None, None
1791 before, match, after = None, None, None
1787 if opts.get('line_number'):
1792 if opts.get('line_number'):
1788 cols.append(str(l.linenum))
1793 cols.append(str(l.linenum))
1789 if opts.get('all'):
1794 if opts.get('all'):
1790 cols.append(change)
1795 cols.append(change)
1791 if opts.get('user'):
1796 if opts.get('user'):
1792 cols.append(ui.shortuser(ctx.user()))
1797 cols.append(ui.shortuser(ctx.user()))
1793 if opts.get('date'):
1798 if opts.get('date'):
1794 cols.append(datefunc(ctx.date()))
1799 cols.append(datefunc(ctx.date()))
1795 if opts.get('files_with_matches'):
1800 if opts.get('files_with_matches'):
1796 c = (fn, rev)
1801 c = (fn, rev)
1797 if c in filerevmatches:
1802 if c in filerevmatches:
1798 continue
1803 continue
1799 filerevmatches[c] = 1
1804 filerevmatches[c] = 1
1800 else:
1805 else:
1801 before = l.line[:l.colstart]
1806 before = l.line[:l.colstart]
1802 match = l.line[l.colstart:l.colend]
1807 match = l.line[l.colstart:l.colend]
1803 after = l.line[l.colend:]
1808 after = l.line[l.colend:]
1804 ui.write(sep.join(cols))
1809 ui.write(sep.join(cols))
1805 if before is not None:
1810 if before is not None:
1806 ui.write(sep + before)
1811 ui.write(sep + before)
1807 ui.write(match, label='grep.match')
1812 ui.write(match, label='grep.match')
1808 ui.write(after)
1813 ui.write(after)
1809 ui.write(eol)
1814 ui.write(eol)
1810 found = True
1815 found = True
1811 return found
1816 return found
1812
1817
1813 skip = {}
1818 skip = {}
1814 revfiles = {}
1819 revfiles = {}
1815 matchfn = cmdutil.match(repo, pats, opts)
1820 matchfn = cmdutil.match(repo, pats, opts)
1816 found = False
1821 found = False
1817 follow = opts.get('follow')
1822 follow = opts.get('follow')
1818
1823
1819 def prep(ctx, fns):
1824 def prep(ctx, fns):
1820 rev = ctx.rev()
1825 rev = ctx.rev()
1821 pctx = ctx.parents()[0]
1826 pctx = ctx.parents()[0]
1822 parent = pctx.rev()
1827 parent = pctx.rev()
1823 matches.setdefault(rev, {})
1828 matches.setdefault(rev, {})
1824 matches.setdefault(parent, {})
1829 matches.setdefault(parent, {})
1825 files = revfiles.setdefault(rev, [])
1830 files = revfiles.setdefault(rev, [])
1826 for fn in fns:
1831 for fn in fns:
1827 flog = getfile(fn)
1832 flog = getfile(fn)
1828 try:
1833 try:
1829 fnode = ctx.filenode(fn)
1834 fnode = ctx.filenode(fn)
1830 except error.LookupError:
1835 except error.LookupError:
1831 continue
1836 continue
1832
1837
1833 copied = flog.renamed(fnode)
1838 copied = flog.renamed(fnode)
1834 copy = follow and copied and copied[0]
1839 copy = follow and copied and copied[0]
1835 if copy:
1840 if copy:
1836 copies.setdefault(rev, {})[fn] = copy
1841 copies.setdefault(rev, {})[fn] = copy
1837 if fn in skip:
1842 if fn in skip:
1838 if copy:
1843 if copy:
1839 skip[copy] = True
1844 skip[copy] = True
1840 continue
1845 continue
1841 files.append(fn)
1846 files.append(fn)
1842
1847
1843 if fn not in matches[rev]:
1848 if fn not in matches[rev]:
1844 grepbody(fn, rev, flog.read(fnode))
1849 grepbody(fn, rev, flog.read(fnode))
1845
1850
1846 pfn = copy or fn
1851 pfn = copy or fn
1847 if pfn not in matches[parent]:
1852 if pfn not in matches[parent]:
1848 try:
1853 try:
1849 fnode = pctx.filenode(pfn)
1854 fnode = pctx.filenode(pfn)
1850 grepbody(pfn, parent, flog.read(fnode))
1855 grepbody(pfn, parent, flog.read(fnode))
1851 except error.LookupError:
1856 except error.LookupError:
1852 pass
1857 pass
1853
1858
1854 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1859 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1855 rev = ctx.rev()
1860 rev = ctx.rev()
1856 parent = ctx.parents()[0].rev()
1861 parent = ctx.parents()[0].rev()
1857 for fn in sorted(revfiles.get(rev, [])):
1862 for fn in sorted(revfiles.get(rev, [])):
1858 states = matches[rev][fn]
1863 states = matches[rev][fn]
1859 copy = copies.get(rev, {}).get(fn)
1864 copy = copies.get(rev, {}).get(fn)
1860 if fn in skip:
1865 if fn in skip:
1861 if copy:
1866 if copy:
1862 skip[copy] = True
1867 skip[copy] = True
1863 continue
1868 continue
1864 pstates = matches.get(parent, {}).get(copy or fn, [])
1869 pstates = matches.get(parent, {}).get(copy or fn, [])
1865 if pstates or states:
1870 if pstates or states:
1866 r = display(fn, ctx, pstates, states)
1871 r = display(fn, ctx, pstates, states)
1867 found = found or r
1872 found = found or r
1868 if r and not opts.get('all'):
1873 if r and not opts.get('all'):
1869 skip[fn] = True
1874 skip[fn] = True
1870 if copy:
1875 if copy:
1871 skip[copy] = True
1876 skip[copy] = True
1872 del matches[rev]
1877 del matches[rev]
1873 del revfiles[rev]
1878 del revfiles[rev]
1874
1879
1875 return not found
1880 return not found
1876
1881
1877 def heads(ui, repo, *branchrevs, **opts):
1882 def heads(ui, repo, *branchrevs, **opts):
1878 """show current repository heads or show branch heads
1883 """show current repository heads or show branch heads
1879
1884
1880 With no arguments, show all repository branch heads.
1885 With no arguments, show all repository branch heads.
1881
1886
1882 Repository "heads" are changesets with no child changesets. They are
1887 Repository "heads" are changesets with no child changesets. They are
1883 where development generally takes place and are the usual targets
1888 where development generally takes place and are the usual targets
1884 for update and merge operations. Branch heads are changesets that have
1889 for update and merge operations. Branch heads are changesets that have
1885 no child changeset on the same branch.
1890 no child changeset on the same branch.
1886
1891
1887 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
1888 associated with the specified changesets are shown.
1893 associated with the specified changesets are shown.
1889
1894
1890 If -c/--closed is specified, also show branch heads marked closed
1895 If -c/--closed is specified, also show branch heads marked closed
1891 (see :hg:`commit --close-branch`).
1896 (see :hg:`commit --close-branch`).
1892
1897
1893 If STARTREV is specified, only those heads that are descendants of
1898 If STARTREV is specified, only those heads that are descendants of
1894 STARTREV will be displayed.
1899 STARTREV will be displayed.
1895
1900
1896 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
1897 changesets without children will be shown.
1902 changesets without children will be shown.
1898
1903
1899 Returns 0 if matching heads are found, 1 if not.
1904 Returns 0 if matching heads are found, 1 if not.
1900 """
1905 """
1901
1906
1902 start = None
1907 start = None
1903 if 'rev' in opts:
1908 if 'rev' in opts:
1904 start = cmdutil.revsingle(repo, opts['rev'], None).node()
1909 start = cmdutil.revsingle(repo, opts['rev'], None).node()
1905
1910
1906 if opts.get('topo'):
1911 if opts.get('topo'):
1907 heads = [repo[h] for h in repo.heads(start)]
1912 heads = [repo[h] for h in repo.heads(start)]
1908 else:
1913 else:
1909 heads = []
1914 heads = []
1910 for b, ls in repo.branchmap().iteritems():
1915 for b, ls in repo.branchmap().iteritems():
1911 if start is None:
1916 if start is None:
1912 heads += [repo[h] for h in ls]
1917 heads += [repo[h] for h in ls]
1913 continue
1918 continue
1914 startrev = repo.changelog.rev(start)
1919 startrev = repo.changelog.rev(start)
1915 descendants = set(repo.changelog.descendants(startrev))
1920 descendants = set(repo.changelog.descendants(startrev))
1916 descendants.add(startrev)
1921 descendants.add(startrev)
1917 rev = repo.changelog.rev
1922 rev = repo.changelog.rev
1918 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]
1919
1924
1920 if branchrevs:
1925 if branchrevs:
1921 branches = set(repo[br].branch() for br in branchrevs)
1926 branches = set(repo[br].branch() for br in branchrevs)
1922 heads = [h for h in heads if h.branch() in branches]
1927 heads = [h for h in heads if h.branch() in branches]
1923
1928
1924 if not opts.get('closed'):
1929 if not opts.get('closed'):
1925 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')]
1926
1931
1927 if opts.get('active') and branchrevs:
1932 if opts.get('active') and branchrevs:
1928 dagheads = repo.heads(start)
1933 dagheads = repo.heads(start)
1929 heads = [h for h in heads if h.node() in dagheads]
1934 heads = [h for h in heads if h.node() in dagheads]
1930
1935
1931 if branchrevs:
1936 if branchrevs:
1932 haveheads = set(h.branch() for h in heads)
1937 haveheads = set(h.branch() for h in heads)
1933 if branches - haveheads:
1938 if branches - haveheads:
1934 headless = ', '.join(b for b in branches - haveheads)
1939 headless = ', '.join(b for b in branches - haveheads)
1935 msg = _('no open branch heads found on branches %s')
1940 msg = _('no open branch heads found on branches %s')
1936 if opts.get('rev'):
1941 if opts.get('rev'):
1937 msg += _(' (started at %s)' % opts['rev'])
1942 msg += _(' (started at %s)' % opts['rev'])
1938 ui.warn((msg + '\n') % headless)
1943 ui.warn((msg + '\n') % headless)
1939
1944
1940 if not heads:
1945 if not heads:
1941 return 1
1946 return 1
1942
1947
1943 heads = sorted(heads, key=lambda x: -x.rev())
1948 heads = sorted(heads, key=lambda x: -x.rev())
1944 displayer = cmdutil.show_changeset(ui, repo, opts)
1949 displayer = cmdutil.show_changeset(ui, repo, opts)
1945 for ctx in heads:
1950 for ctx in heads:
1946 displayer.show(ctx)
1951 displayer.show(ctx)
1947 displayer.close()
1952 displayer.close()
1948
1953
1949 def help_(ui, name=None, with_version=False, unknowncmd=False):
1954 def help_(ui, name=None, with_version=False, unknowncmd=False):
1950 """show help for a given topic or a help overview
1955 """show help for a given topic or a help overview
1951
1956
1952 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.
1953
1958
1954 Given a topic, extension, or command name, print help for that
1959 Given a topic, extension, or command name, print help for that
1955 topic.
1960 topic.
1956
1961
1957 Returns 0 if successful.
1962 Returns 0 if successful.
1958 """
1963 """
1959 option_lists = []
1964 option_lists = []
1960 textwidth = ui.termwidth() - 2
1965 textwidth = ui.termwidth() - 2
1961
1966
1962 def addglobalopts(aliases):
1967 def addglobalopts(aliases):
1963 if ui.verbose:
1968 if ui.verbose:
1964 option_lists.append((_("global options:"), globalopts))
1969 option_lists.append((_("global options:"), globalopts))
1965 if name == 'shortlist':
1970 if name == 'shortlist':
1966 option_lists.append((_('use "hg help" for the full list '
1971 option_lists.append((_('use "hg help" for the full list '
1967 'of commands'), ()))
1972 'of commands'), ()))
1968 else:
1973 else:
1969 if name == 'shortlist':
1974 if name == 'shortlist':
1970 msg = _('use "hg help" for the full list of commands '
1975 msg = _('use "hg help" for the full list of commands '
1971 'or "hg -v" for details')
1976 'or "hg -v" for details')
1972 elif aliases:
1977 elif aliases:
1973 msg = _('use "hg -v help%s" to show builtin aliases and '
1978 msg = _('use "hg -v help%s" to show builtin aliases and '
1974 'global options') % (name and " " + name or "")
1979 'global options') % (name and " " + name or "")
1975 else:
1980 else:
1976 msg = _('use "hg -v help %s" to show global options') % name
1981 msg = _('use "hg -v help %s" to show global options') % name
1977 option_lists.append((msg, ()))
1982 option_lists.append((msg, ()))
1978
1983
1979 def helpcmd(name):
1984 def helpcmd(name):
1980 if with_version:
1985 if with_version:
1981 version_(ui)
1986 version_(ui)
1982 ui.write('\n')
1987 ui.write('\n')
1983
1988
1984 try:
1989 try:
1985 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1990 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1986 except error.AmbiguousCommand, inst:
1991 except error.AmbiguousCommand, inst:
1987 # 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
1988 # except block, nor can be used inside a lambda. python issue4617
1993 # except block, nor can be used inside a lambda. python issue4617
1989 prefix = inst.args[0]
1994 prefix = inst.args[0]
1990 select = lambda c: c.lstrip('^').startswith(prefix)
1995 select = lambda c: c.lstrip('^').startswith(prefix)
1991 helplist(_('list of commands:\n\n'), select)
1996 helplist(_('list of commands:\n\n'), select)
1992 return
1997 return
1993
1998
1994 # 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
1995 if getattr(entry[0], 'badalias', False):
2000 if getattr(entry[0], 'badalias', False):
1996 if not unknowncmd:
2001 if not unknowncmd:
1997 entry[0](ui)
2002 entry[0](ui)
1998 return
2003 return
1999
2004
2000 # synopsis
2005 # synopsis
2001 if len(entry) > 2:
2006 if len(entry) > 2:
2002 if entry[2].startswith('hg'):
2007 if entry[2].startswith('hg'):
2003 ui.write("%s\n" % entry[2])
2008 ui.write("%s\n" % entry[2])
2004 else:
2009 else:
2005 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2010 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2006 else:
2011 else:
2007 ui.write('hg %s\n' % aliases[0])
2012 ui.write('hg %s\n' % aliases[0])
2008
2013
2009 # aliases
2014 # aliases
2010 if not ui.quiet and len(aliases) > 1:
2015 if not ui.quiet and len(aliases) > 1:
2011 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2016 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2012
2017
2013 # description
2018 # description
2014 doc = gettext(entry[0].__doc__)
2019 doc = gettext(entry[0].__doc__)
2015 if not doc:
2020 if not doc:
2016 doc = _("(no help text available)")
2021 doc = _("(no help text available)")
2017 if hasattr(entry[0], 'definition'): # aliased command
2022 if hasattr(entry[0], 'definition'): # aliased command
2018 if entry[0].definition.startswith('!'): # shell alias
2023 if entry[0].definition.startswith('!'): # shell alias
2019 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2024 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2020 else:
2025 else:
2021 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)
2022 if ui.quiet:
2027 if ui.quiet:
2023 doc = doc.splitlines()[0]
2028 doc = doc.splitlines()[0]
2024 keep = ui.verbose and ['verbose'] or []
2029 keep = ui.verbose and ['verbose'] or []
2025 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2030 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2026 ui.write("\n%s\n" % formatted)
2031 ui.write("\n%s\n" % formatted)
2027 if pruned:
2032 if pruned:
2028 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)
2029
2034
2030 if not ui.quiet:
2035 if not ui.quiet:
2031 # options
2036 # options
2032 if entry[1]:
2037 if entry[1]:
2033 option_lists.append((_("options:\n"), entry[1]))
2038 option_lists.append((_("options:\n"), entry[1]))
2034
2039
2035 addglobalopts(False)
2040 addglobalopts(False)
2036
2041
2037 def helplist(header, select=None):
2042 def helplist(header, select=None):
2038 h = {}
2043 h = {}
2039 cmds = {}
2044 cmds = {}
2040 for c, e in table.iteritems():
2045 for c, e in table.iteritems():
2041 f = c.split("|", 1)[0]
2046 f = c.split("|", 1)[0]
2042 if select and not select(f):
2047 if select and not select(f):
2043 continue
2048 continue
2044 if (not select and name != 'shortlist' and
2049 if (not select and name != 'shortlist' and
2045 e[0].__module__ != __name__):
2050 e[0].__module__ != __name__):
2046 continue
2051 continue
2047 if name == "shortlist" and not f.startswith("^"):
2052 if name == "shortlist" and not f.startswith("^"):
2048 continue
2053 continue
2049 f = f.lstrip("^")
2054 f = f.lstrip("^")
2050 if not ui.debugflag and f.startswith("debug"):
2055 if not ui.debugflag and f.startswith("debug"):
2051 continue
2056 continue
2052 doc = e[0].__doc__
2057 doc = e[0].__doc__
2053 if doc and 'DEPRECATED' in doc and not ui.verbose:
2058 if doc and 'DEPRECATED' in doc and not ui.verbose:
2054 continue
2059 continue
2055 doc = gettext(doc)
2060 doc = gettext(doc)
2056 if not doc:
2061 if not doc:
2057 doc = _("(no help text available)")
2062 doc = _("(no help text available)")
2058 h[f] = doc.splitlines()[0].rstrip()
2063 h[f] = doc.splitlines()[0].rstrip()
2059 cmds[f] = c.lstrip("^")
2064 cmds[f] = c.lstrip("^")
2060
2065
2061 if not h:
2066 if not h:
2062 ui.status(_('no commands defined\n'))
2067 ui.status(_('no commands defined\n'))
2063 return
2068 return
2064
2069
2065 ui.status(header)
2070 ui.status(header)
2066 fns = sorted(h)
2071 fns = sorted(h)
2067 m = max(map(len, fns))
2072 m = max(map(len, fns))
2068 for f in fns:
2073 for f in fns:
2069 if ui.verbose:
2074 if ui.verbose:
2070 commands = cmds[f].replace("|",", ")
2075 commands = cmds[f].replace("|",", ")
2071 ui.write(" %s:\n %s\n"%(commands, h[f]))
2076 ui.write(" %s:\n %s\n"%(commands, h[f]))
2072 else:
2077 else:
2073 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2078 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2074 initindent=' %-*s ' % (m, f),
2079 initindent=' %-*s ' % (m, f),
2075 hangindent=' ' * (m + 4))))
2080 hangindent=' ' * (m + 4))))
2076
2081
2077 if not ui.quiet:
2082 if not ui.quiet:
2078 addglobalopts(True)
2083 addglobalopts(True)
2079
2084
2080 def helptopic(name):
2085 def helptopic(name):
2081 for names, header, doc in help.helptable:
2086 for names, header, doc in help.helptable:
2082 if name in names:
2087 if name in names:
2083 break
2088 break
2084 else:
2089 else:
2085 raise error.UnknownCommand(name)
2090 raise error.UnknownCommand(name)
2086
2091
2087 # description
2092 # description
2088 if not doc:
2093 if not doc:
2089 doc = _("(no help text available)")
2094 doc = _("(no help text available)")
2090 if hasattr(doc, '__call__'):
2095 if hasattr(doc, '__call__'):
2091 doc = doc()
2096 doc = doc()
2092
2097
2093 ui.write("%s\n\n" % header)
2098 ui.write("%s\n\n" % header)
2094 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2099 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2095
2100
2096 def helpext(name):
2101 def helpext(name):
2097 try:
2102 try:
2098 mod = extensions.find(name)
2103 mod = extensions.find(name)
2099 doc = gettext(mod.__doc__) or _('no help text available')
2104 doc = gettext(mod.__doc__) or _('no help text available')
2100 except KeyError:
2105 except KeyError:
2101 mod = None
2106 mod = None
2102 doc = extensions.disabledext(name)
2107 doc = extensions.disabledext(name)
2103 if not doc:
2108 if not doc:
2104 raise error.UnknownCommand(name)
2109 raise error.UnknownCommand(name)
2105
2110
2106 if '\n' not in doc:
2111 if '\n' not in doc:
2107 head, tail = doc, ""
2112 head, tail = doc, ""
2108 else:
2113 else:
2109 head, tail = doc.split('\n', 1)
2114 head, tail = doc.split('\n', 1)
2110 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2115 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2111 if tail:
2116 if tail:
2112 ui.write(minirst.format(tail, textwidth))
2117 ui.write(minirst.format(tail, textwidth))
2113 ui.status('\n\n')
2118 ui.status('\n\n')
2114
2119
2115 if mod:
2120 if mod:
2116 try:
2121 try:
2117 ct = mod.cmdtable
2122 ct = mod.cmdtable
2118 except AttributeError:
2123 except AttributeError:
2119 ct = {}
2124 ct = {}
2120 modcmds = set([c.split('|', 1)[0] for c in ct])
2125 modcmds = set([c.split('|', 1)[0] for c in ct])
2121 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2126 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2122 else:
2127 else:
2123 ui.write(_('use "hg help extensions" for information on enabling '
2128 ui.write(_('use "hg help extensions" for information on enabling '
2124 'extensions\n'))
2129 'extensions\n'))
2125
2130
2126 def helpextcmd(name):
2131 def helpextcmd(name):
2127 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2132 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2128 doc = gettext(mod.__doc__).splitlines()[0]
2133 doc = gettext(mod.__doc__).splitlines()[0]
2129
2134
2130 msg = help.listexts(_("'%s' is provided by the following "
2135 msg = help.listexts(_("'%s' is provided by the following "
2131 "extension:") % cmd, {ext: doc}, len(ext),
2136 "extension:") % cmd, {ext: doc}, len(ext),
2132 indent=4)
2137 indent=4)
2133 ui.write(minirst.format(msg, textwidth))
2138 ui.write(minirst.format(msg, textwidth))
2134 ui.write('\n\n')
2139 ui.write('\n\n')
2135 ui.write(_('use "hg help extensions" for information on enabling '
2140 ui.write(_('use "hg help extensions" for information on enabling '
2136 'extensions\n'))
2141 'extensions\n'))
2137
2142
2138 help.addtopichook('revsets', revset.makedoc)
2143 help.addtopichook('revsets', revset.makedoc)
2139
2144
2140 if name and name != 'shortlist':
2145 if name and name != 'shortlist':
2141 i = None
2146 i = None
2142 if unknowncmd:
2147 if unknowncmd:
2143 queries = (helpextcmd,)
2148 queries = (helpextcmd,)
2144 else:
2149 else:
2145 queries = (helptopic, helpcmd, helpext, helpextcmd)
2150 queries = (helptopic, helpcmd, helpext, helpextcmd)
2146 for f in queries:
2151 for f in queries:
2147 try:
2152 try:
2148 f(name)
2153 f(name)
2149 i = None
2154 i = None
2150 break
2155 break
2151 except error.UnknownCommand, inst:
2156 except error.UnknownCommand, inst:
2152 i = inst
2157 i = inst
2153 if i:
2158 if i:
2154 raise i
2159 raise i
2155
2160
2156 else:
2161 else:
2157 # program name
2162 # program name
2158 if ui.verbose or with_version:
2163 if ui.verbose or with_version:
2159 version_(ui)
2164 version_(ui)
2160 else:
2165 else:
2161 ui.status(_("Mercurial Distributed SCM\n"))
2166 ui.status(_("Mercurial Distributed SCM\n"))
2162 ui.status('\n')
2167 ui.status('\n')
2163
2168
2164 # list of commands
2169 # list of commands
2165 if name == "shortlist":
2170 if name == "shortlist":
2166 header = _('basic commands:\n\n')
2171 header = _('basic commands:\n\n')
2167 else:
2172 else:
2168 header = _('list of commands:\n\n')
2173 header = _('list of commands:\n\n')
2169
2174
2170 helplist(header)
2175 helplist(header)
2171 if name != 'shortlist':
2176 if name != 'shortlist':
2172 exts, maxlength = extensions.enabled()
2177 exts, maxlength = extensions.enabled()
2173 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2178 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2174 if text:
2179 if text:
2175 ui.write("\n%s\n" % minirst.format(text, textwidth))
2180 ui.write("\n%s\n" % minirst.format(text, textwidth))
2176
2181
2177 # list all option lists
2182 # list all option lists
2178 opt_output = []
2183 opt_output = []
2179 multioccur = False
2184 multioccur = False
2180 for title, options in option_lists:
2185 for title, options in option_lists:
2181 opt_output.append(("\n%s" % title, None))
2186 opt_output.append(("\n%s" % title, None))
2182 for option in options:
2187 for option in options:
2183 if len(option) == 5:
2188 if len(option) == 5:
2184 shortopt, longopt, default, desc, optlabel = option
2189 shortopt, longopt, default, desc, optlabel = option
2185 else:
2190 else:
2186 shortopt, longopt, default, desc = option
2191 shortopt, longopt, default, desc = option
2187 optlabel = _("VALUE") # default label
2192 optlabel = _("VALUE") # default label
2188
2193
2189 if _("DEPRECATED") in desc and not ui.verbose:
2194 if _("DEPRECATED") in desc and not ui.verbose:
2190 continue
2195 continue
2191 if isinstance(default, list):
2196 if isinstance(default, list):
2192 numqualifier = " %s [+]" % optlabel
2197 numqualifier = " %s [+]" % optlabel
2193 multioccur = True
2198 multioccur = True
2194 elif (default is not None) and not isinstance(default, bool):
2199 elif (default is not None) and not isinstance(default, bool):
2195 numqualifier = " %s" % optlabel
2200 numqualifier = " %s" % optlabel
2196 else:
2201 else:
2197 numqualifier = ""
2202 numqualifier = ""
2198 opt_output.append(("%2s%s" %
2203 opt_output.append(("%2s%s" %
2199 (shortopt and "-%s" % shortopt,
2204 (shortopt and "-%s" % shortopt,
2200 longopt and " --%s%s" %
2205 longopt and " --%s%s" %
2201 (longopt, numqualifier)),
2206 (longopt, numqualifier)),
2202 "%s%s" % (desc,
2207 "%s%s" % (desc,
2203 default
2208 default
2204 and _(" (default: %s)") % default
2209 and _(" (default: %s)") % default
2205 or "")))
2210 or "")))
2206 if multioccur:
2211 if multioccur:
2207 msg = _("\n[+] marked option can be specified multiple times")
2212 msg = _("\n[+] marked option can be specified multiple times")
2208 if ui.verbose and name != 'shortlist':
2213 if ui.verbose and name != 'shortlist':
2209 opt_output.append((msg, None))
2214 opt_output.append((msg, None))
2210 else:
2215 else:
2211 opt_output.insert(-1, (msg, None))
2216 opt_output.insert(-1, (msg, None))
2212
2217
2213 if not name:
2218 if not name:
2214 ui.write(_("\nadditional help topics:\n\n"))
2219 ui.write(_("\nadditional help topics:\n\n"))
2215 topics = []
2220 topics = []
2216 for names, header, doc in help.helptable:
2221 for names, header, doc in help.helptable:
2217 topics.append((sorted(names, key=len, reverse=True)[0], header))
2222 topics.append((sorted(names, key=len, reverse=True)[0], header))
2218 topics_len = max([len(s[0]) for s in topics])
2223 topics_len = max([len(s[0]) for s in topics])
2219 for t, desc in topics:
2224 for t, desc in topics:
2220 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2225 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2221
2226
2222 if opt_output:
2227 if opt_output:
2223 colwidth = encoding.colwidth
2228 colwidth = encoding.colwidth
2224 # normalize: (opt or message, desc or None, width of opt)
2229 # normalize: (opt or message, desc or None, width of opt)
2225 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2230 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2226 for opt, desc in opt_output]
2231 for opt, desc in opt_output]
2227 hanging = max([e[2] for e in entries])
2232 hanging = max([e[2] for e in entries])
2228 for opt, desc, width in entries:
2233 for opt, desc, width in entries:
2229 if desc:
2234 if desc:
2230 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2235 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2231 hangindent = ' ' * (hanging + 3)
2236 hangindent = ' ' * (hanging + 3)
2232 ui.write('%s\n' % (util.wrap(desc, textwidth,
2237 ui.write('%s\n' % (util.wrap(desc, textwidth,
2233 initindent=initindent,
2238 initindent=initindent,
2234 hangindent=hangindent)))
2239 hangindent=hangindent)))
2235 else:
2240 else:
2236 ui.write("%s\n" % opt)
2241 ui.write("%s\n" % opt)
2237
2242
2238 def identify(ui, repo, source=None,
2243 def identify(ui, repo, source=None,
2239 rev=None, num=None, id=None, branch=None, tags=None):
2244 rev=None, num=None, id=None, branch=None, tags=None):
2240 """identify the working copy or specified revision
2245 """identify the working copy or specified revision
2241
2246
2242 With no revision, print a summary of the current state of the
2247 With no revision, print a summary of the current state of the
2243 repository.
2248 repository.
2244
2249
2245 Specifying a path to a repository root or Mercurial bundle will
2250 Specifying a path to a repository root or Mercurial bundle will
2246 cause lookup to operate on that repository/bundle.
2251 cause lookup to operate on that repository/bundle.
2247
2252
2248 This summary identifies the repository state using one or two
2253 This summary identifies the repository state using one or two
2249 parent hash identifiers, followed by a "+" if there are
2254 parent hash identifiers, followed by a "+" if there are
2250 uncommitted changes in the working directory, a list of tags for
2255 uncommitted changes in the working directory, a list of tags for
2251 this revision and a branch name for non-default branches.
2256 this revision and a branch name for non-default branches.
2252
2257
2253 Returns 0 if successful.
2258 Returns 0 if successful.
2254 """
2259 """
2255
2260
2256 if not repo and not source:
2261 if not repo and not source:
2257 raise util.Abort(_("there is no Mercurial repository here "
2262 raise util.Abort(_("there is no Mercurial repository here "
2258 "(.hg not found)"))
2263 "(.hg not found)"))
2259
2264
2260 hexfunc = ui.debugflag and hex or short
2265 hexfunc = ui.debugflag and hex or short
2261 default = not (num or id or branch or tags)
2266 default = not (num or id or branch or tags)
2262 output = []
2267 output = []
2263
2268
2264 revs = []
2269 revs = []
2265 if source:
2270 if source:
2266 source, branches = hg.parseurl(ui.expandpath(source))
2271 source, branches = hg.parseurl(ui.expandpath(source))
2267 repo = hg.repository(ui, source)
2272 repo = hg.repository(ui, source)
2268 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2273 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2269
2274
2270 if not repo.local():
2275 if not repo.local():
2271 if not rev and revs:
2276 if not rev and revs:
2272 rev = revs[0]
2277 rev = revs[0]
2273 if not rev:
2278 if not rev:
2274 rev = "tip"
2279 rev = "tip"
2275 if num or branch or tags:
2280 if num or branch or tags:
2276 raise util.Abort(
2281 raise util.Abort(
2277 "can't query remote revision number, branch, or tags")
2282 "can't query remote revision number, branch, or tags")
2278 output = [hexfunc(repo.lookup(rev))]
2283 output = [hexfunc(repo.lookup(rev))]
2279 elif not rev:
2284 elif not rev:
2280 ctx = repo[None]
2285 ctx = repo[None]
2281 parents = ctx.parents()
2286 parents = ctx.parents()
2282 changed = False
2287 changed = False
2283 if default or id or num:
2288 if default or id or num:
2284 changed = util.any(repo.status())
2289 changed = util.any(repo.status())
2285 if default or id:
2290 if default or id:
2286 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2291 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2287 (changed) and "+" or "")]
2292 (changed) and "+" or "")]
2288 if num:
2293 if num:
2289 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]),
2290 (changed) and "+" or ""))
2295 (changed) and "+" or ""))
2291 else:
2296 else:
2292 ctx = cmdutil.revsingle(repo, rev)
2297 ctx = cmdutil.revsingle(repo, rev)
2293 if default or id:
2298 if default or id:
2294 output = [hexfunc(ctx.node())]
2299 output = [hexfunc(ctx.node())]
2295 if num:
2300 if num:
2296 output.append(str(ctx.rev()))
2301 output.append(str(ctx.rev()))
2297
2302
2298 if repo.local() and default and not ui.quiet:
2303 if repo.local() and default and not ui.quiet:
2299 b = ctx.branch()
2304 b = ctx.branch()
2300 if b != 'default':
2305 if b != 'default':
2301 output.append("(%s)" % b)
2306 output.append("(%s)" % b)
2302
2307
2303 # multiple tags for a single parent separated by '/'
2308 # multiple tags for a single parent separated by '/'
2304 t = "/".join(ctx.tags())
2309 t = "/".join(ctx.tags())
2305 if t:
2310 if t:
2306 output.append(t)
2311 output.append(t)
2307
2312
2308 if branch:
2313 if branch:
2309 output.append(ctx.branch())
2314 output.append(ctx.branch())
2310
2315
2311 if tags:
2316 if tags:
2312 output.extend(ctx.tags())
2317 output.extend(ctx.tags())
2313
2318
2314 ui.write("%s\n" % ' '.join(output))
2319 ui.write("%s\n" % ' '.join(output))
2315
2320
2316 def import_(ui, repo, patch1, *patches, **opts):
2321 def import_(ui, repo, patch1, *patches, **opts):
2317 """import an ordered set of patches
2322 """import an ordered set of patches
2318
2323
2319 Import a list of patches and commit them individually (unless
2324 Import a list of patches and commit them individually (unless
2320 --no-commit is specified).
2325 --no-commit is specified).
2321
2326
2322 If there are outstanding changes in the working directory, import
2327 If there are outstanding changes in the working directory, import
2323 will abort unless given the -f/--force flag.
2328 will abort unless given the -f/--force flag.
2324
2329
2325 You can import a patch straight from a mail message. Even patches
2330 You can import a patch straight from a mail message. Even patches
2326 as attachments work (to use the body part, it must have type
2331 as attachments work (to use the body part, it must have type
2327 text/plain or text/x-patch). From and Subject headers of email
2332 text/plain or text/x-patch). From and Subject headers of email
2328 message are used as default committer and commit message. All
2333 message are used as default committer and commit message. All
2329 text/plain body parts before first diff are added to commit
2334 text/plain body parts before first diff are added to commit
2330 message.
2335 message.
2331
2336
2332 If the imported patch was generated by :hg:`export`, user and
2337 If the imported patch was generated by :hg:`export`, user and
2333 description from patch override values from message headers and
2338 description from patch override values from message headers and
2334 body. Values given on command line with -m/--message and -u/--user
2339 body. Values given on command line with -m/--message and -u/--user
2335 override these.
2340 override these.
2336
2341
2337 If --exact is specified, import will set the working directory to
2342 If --exact is specified, import will set the working directory to
2338 the parent of each patch before applying it, and will abort if the
2343 the parent of each patch before applying it, and will abort if the
2339 resulting changeset has a different ID than the one recorded in
2344 resulting changeset has a different ID than the one recorded in
2340 the patch. This may happen due to character set problems or other
2345 the patch. This may happen due to character set problems or other
2341 deficiencies in the text patch format.
2346 deficiencies in the text patch format.
2342
2347
2343 With -s/--similarity, hg will attempt to discover renames and
2348 With -s/--similarity, hg will attempt to discover renames and
2344 copies in the patch in the same way as 'addremove'.
2349 copies in the patch in the same way as 'addremove'.
2345
2350
2346 To read a patch from standard input, use "-" as the patch name. If
2351 To read a patch from standard input, use "-" as the patch name. If
2347 a URL is specified, the patch will be downloaded from it.
2352 a URL is specified, the patch will be downloaded from it.
2348 See :hg:`help dates` for a list of formats valid for -d/--date.
2353 See :hg:`help dates` for a list of formats valid for -d/--date.
2349
2354
2350 Returns 0 on success.
2355 Returns 0 on success.
2351 """
2356 """
2352 patches = (patch1,) + patches
2357 patches = (patch1,) + patches
2353
2358
2354 date = opts.get('date')
2359 date = opts.get('date')
2355 if date:
2360 if date:
2356 opts['date'] = util.parsedate(date)
2361 opts['date'] = util.parsedate(date)
2357
2362
2358 try:
2363 try:
2359 sim = float(opts.get('similarity') or 0)
2364 sim = float(opts.get('similarity') or 0)
2360 except ValueError:
2365 except ValueError:
2361 raise util.Abort(_('similarity must be a number'))
2366 raise util.Abort(_('similarity must be a number'))
2362 if sim < 0 or sim > 100:
2367 if sim < 0 or sim > 100:
2363 raise util.Abort(_('similarity must be between 0 and 100'))
2368 raise util.Abort(_('similarity must be between 0 and 100'))
2364
2369
2365 if opts.get('exact') or not opts.get('force'):
2370 if opts.get('exact') or not opts.get('force'):
2366 cmdutil.bail_if_changed(repo)
2371 cmdutil.bail_if_changed(repo)
2367
2372
2368 d = opts["base"]
2373 d = opts["base"]
2369 strip = opts["strip"]
2374 strip = opts["strip"]
2370 wlock = lock = None
2375 wlock = lock = None
2371 msgs = []
2376 msgs = []
2372
2377
2373 def tryone(ui, hunk):
2378 def tryone(ui, hunk):
2374 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2379 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2375 patch.extract(ui, hunk)
2380 patch.extract(ui, hunk)
2376
2381
2377 if not tmpname:
2382 if not tmpname:
2378 return None
2383 return None
2379 commitid = _('to working directory')
2384 commitid = _('to working directory')
2380
2385
2381 try:
2386 try:
2382 cmdline_message = cmdutil.logmessage(opts)
2387 cmdline_message = cmdutil.logmessage(opts)
2383 if cmdline_message:
2388 if cmdline_message:
2384 # pickup the cmdline msg
2389 # pickup the cmdline msg
2385 message = cmdline_message
2390 message = cmdline_message
2386 elif message:
2391 elif message:
2387 # pickup the patch msg
2392 # pickup the patch msg
2388 message = message.strip()
2393 message = message.strip()
2389 else:
2394 else:
2390 # launch the editor
2395 # launch the editor
2391 message = None
2396 message = None
2392 ui.debug('message:\n%s\n' % message)
2397 ui.debug('message:\n%s\n' % message)
2393
2398
2394 wp = repo.parents()
2399 wp = repo.parents()
2395 if opts.get('exact'):
2400 if opts.get('exact'):
2396 if not nodeid or not p1:
2401 if not nodeid or not p1:
2397 raise util.Abort(_('not a Mercurial patch'))
2402 raise util.Abort(_('not a Mercurial patch'))
2398 p1 = repo.lookup(p1)
2403 p1 = repo.lookup(p1)
2399 p2 = repo.lookup(p2 or hex(nullid))
2404 p2 = repo.lookup(p2 or hex(nullid))
2400
2405
2401 if p1 != wp[0].node():
2406 if p1 != wp[0].node():
2402 hg.clean(repo, p1)
2407 hg.clean(repo, p1)
2403 repo.dirstate.setparents(p1, p2)
2408 repo.dirstate.setparents(p1, p2)
2404 elif p2:
2409 elif p2:
2405 try:
2410 try:
2406 p1 = repo.lookup(p1)
2411 p1 = repo.lookup(p1)
2407 p2 = repo.lookup(p2)
2412 p2 = repo.lookup(p2)
2408 if p1 == wp[0].node():
2413 if p1 == wp[0].node():
2409 repo.dirstate.setparents(p1, p2)
2414 repo.dirstate.setparents(p1, p2)
2410 except error.RepoError:
2415 except error.RepoError:
2411 pass
2416 pass
2412 if opts.get('exact') or opts.get('import_branch'):
2417 if opts.get('exact') or opts.get('import_branch'):
2413 repo.dirstate.setbranch(branch or 'default')
2418 repo.dirstate.setbranch(branch or 'default')
2414
2419
2415 files = {}
2420 files = {}
2416 try:
2421 try:
2417 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2422 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2418 files=files, eolmode=None)
2423 files=files, eolmode=None)
2419 finally:
2424 finally:
2420 files = cmdutil.updatedir(ui, repo, files,
2425 files = cmdutil.updatedir(ui, repo, files,
2421 similarity=sim / 100.0)
2426 similarity=sim / 100.0)
2422 if opts.get('no_commit'):
2427 if opts.get('no_commit'):
2423 if message:
2428 if message:
2424 msgs.append(message)
2429 msgs.append(message)
2425 else:
2430 else:
2426 if opts.get('exact'):
2431 if opts.get('exact'):
2427 m = None
2432 m = None
2428 else:
2433 else:
2429 m = cmdutil.matchfiles(repo, files or [])
2434 m = cmdutil.matchfiles(repo, files or [])
2430 n = repo.commit(message, opts.get('user') or user,
2435 n = repo.commit(message, opts.get('user') or user,
2431 opts.get('date') or date, match=m,
2436 opts.get('date') or date, match=m,
2432 editor=cmdutil.commiteditor)
2437 editor=cmdutil.commiteditor)
2433 if opts.get('exact'):
2438 if opts.get('exact'):
2434 if hex(n) != nodeid:
2439 if hex(n) != nodeid:
2435 repo.rollback()
2440 repo.rollback()
2436 raise util.Abort(_('patch is damaged'
2441 raise util.Abort(_('patch is damaged'
2437 ' or loses information'))
2442 ' or loses information'))
2438 # Force a dirstate write so that the next transaction
2443 # Force a dirstate write so that the next transaction
2439 # backups an up-do-date file.
2444 # backups an up-do-date file.
2440 repo.dirstate.write()
2445 repo.dirstate.write()
2441 if n:
2446 if n:
2442 commitid = short(n)
2447 commitid = short(n)
2443
2448
2444 return commitid
2449 return commitid
2445 finally:
2450 finally:
2446 os.unlink(tmpname)
2451 os.unlink(tmpname)
2447
2452
2448 try:
2453 try:
2449 wlock = repo.wlock()
2454 wlock = repo.wlock()
2450 lock = repo.lock()
2455 lock = repo.lock()
2451 lastcommit = None
2456 lastcommit = None
2452 for p in patches:
2457 for p in patches:
2453 pf = os.path.join(d, p)
2458 pf = os.path.join(d, p)
2454
2459
2455 if pf == '-':
2460 if pf == '-':
2456 ui.status(_("applying patch from stdin\n"))
2461 ui.status(_("applying patch from stdin\n"))
2457 pf = sys.stdin
2462 pf = sys.stdin
2458 else:
2463 else:
2459 ui.status(_("applying %s\n") % p)
2464 ui.status(_("applying %s\n") % p)
2460 pf = url.open(ui, pf)
2465 pf = url.open(ui, pf)
2461
2466
2462 haspatch = False
2467 haspatch = False
2463 for hunk in patch.split(pf):
2468 for hunk in patch.split(pf):
2464 commitid = tryone(ui, hunk)
2469 commitid = tryone(ui, hunk)
2465 if commitid:
2470 if commitid:
2466 haspatch = True
2471 haspatch = True
2467 if lastcommit:
2472 if lastcommit:
2468 ui.status(_('applied %s\n') % lastcommit)
2473 ui.status(_('applied %s\n') % lastcommit)
2469 lastcommit = commitid
2474 lastcommit = commitid
2470
2475
2471 if not haspatch:
2476 if not haspatch:
2472 raise util.Abort(_('no diffs found'))
2477 raise util.Abort(_('no diffs found'))
2473
2478
2474 if msgs:
2479 if msgs:
2475 repo.opener('last-message.txt', 'wb').write('\n* * *\n'.join(msgs))
2480 repo.opener('last-message.txt', 'wb').write('\n* * *\n'.join(msgs))
2476 finally:
2481 finally:
2477 release(lock, wlock)
2482 release(lock, wlock)
2478
2483
2479 def incoming(ui, repo, source="default", **opts):
2484 def incoming(ui, repo, source="default", **opts):
2480 """show new changesets found in source
2485 """show new changesets found in source
2481
2486
2482 Show new changesets found in the specified path/URL or the default
2487 Show new changesets found in the specified path/URL or the default
2483 pull location. These are the changesets that would have been pulled
2488 pull location. These are the changesets that would have been pulled
2484 if a pull at the time you issued this command.
2489 if a pull at the time you issued this command.
2485
2490
2486 For remote repository, using --bundle avoids downloading the
2491 For remote repository, using --bundle avoids downloading the
2487 changesets twice if the incoming is followed by a pull.
2492 changesets twice if the incoming is followed by a pull.
2488
2493
2489 See pull for valid source format details.
2494 See pull for valid source format details.
2490
2495
2491 Returns 0 if there are incoming changes, 1 otherwise.
2496 Returns 0 if there are incoming changes, 1 otherwise.
2492 """
2497 """
2493 if opts.get('bundle') and opts.get('subrepos'):
2498 if opts.get('bundle') and opts.get('subrepos'):
2494 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2499 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2495
2500
2496 if opts.get('bookmarks'):
2501 if opts.get('bookmarks'):
2497 source, branches = hg.parseurl(ui.expandpath(source),
2502 source, branches = hg.parseurl(ui.expandpath(source),
2498 opts.get('branch'))
2503 opts.get('branch'))
2499 other = hg.repository(hg.remoteui(repo, opts), source)
2504 other = hg.repository(hg.remoteui(repo, opts), source)
2500 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2505 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2501 return bookmarks.diff(ui, repo, other)
2506 return bookmarks.diff(ui, repo, other)
2502
2507
2503 ret = hg.incoming(ui, repo, source, opts)
2508 ret = hg.incoming(ui, repo, source, opts)
2504 return ret
2509 return ret
2505
2510
2506 def init(ui, dest=".", **opts):
2511 def init(ui, dest=".", **opts):
2507 """create a new repository in the given directory
2512 """create a new repository in the given directory
2508
2513
2509 Initialize a new repository in the given directory. If the given
2514 Initialize a new repository in the given directory. If the given
2510 directory does not exist, it will be created.
2515 directory does not exist, it will be created.
2511
2516
2512 If no directory is given, the current directory is used.
2517 If no directory is given, the current directory is used.
2513
2518
2514 It is possible to specify an ``ssh://`` URL as the destination.
2519 It is possible to specify an ``ssh://`` URL as the destination.
2515 See :hg:`help urls` for more information.
2520 See :hg:`help urls` for more information.
2516
2521
2517 Returns 0 on success.
2522 Returns 0 on success.
2518 """
2523 """
2519 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2524 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2520
2525
2521 def locate(ui, repo, *pats, **opts):
2526 def locate(ui, repo, *pats, **opts):
2522 """locate files matching specific patterns
2527 """locate files matching specific patterns
2523
2528
2524 Print files under Mercurial control in the working directory whose
2529 Print files under Mercurial control in the working directory whose
2525 names match the given patterns.
2530 names match the given patterns.
2526
2531
2527 By default, this command searches all directories in the working
2532 By default, this command searches all directories in the working
2528 directory. To search just the current directory and its
2533 directory. To search just the current directory and its
2529 subdirectories, use "--include .".
2534 subdirectories, use "--include .".
2530
2535
2531 If no patterns are given to match, this command prints the names
2536 If no patterns are given to match, this command prints the names
2532 of all files under Mercurial control in the working directory.
2537 of all files under Mercurial control in the working directory.
2533
2538
2534 If you want to feed the output of this command into the "xargs"
2539 If you want to feed the output of this command into the "xargs"
2535 command, use the -0 option to both this command and "xargs". This
2540 command, use the -0 option to both this command and "xargs". This
2536 will avoid the problem of "xargs" treating single filenames that
2541 will avoid the problem of "xargs" treating single filenames that
2537 contain whitespace as multiple filenames.
2542 contain whitespace as multiple filenames.
2538
2543
2539 Returns 0 if a match is found, 1 otherwise.
2544 Returns 0 if a match is found, 1 otherwise.
2540 """
2545 """
2541 end = opts.get('print0') and '\0' or '\n'
2546 end = opts.get('print0') and '\0' or '\n'
2542 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2547 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2543
2548
2544 ret = 1
2549 ret = 1
2545 m = cmdutil.match(repo, pats, opts, default='relglob')
2550 m = cmdutil.match(repo, pats, opts, default='relglob')
2546 m.bad = lambda x, y: False
2551 m.bad = lambda x, y: False
2547 for abs in repo[rev].walk(m):
2552 for abs in repo[rev].walk(m):
2548 if not rev and abs not in repo.dirstate:
2553 if not rev and abs not in repo.dirstate:
2549 continue
2554 continue
2550 if opts.get('fullpath'):
2555 if opts.get('fullpath'):
2551 ui.write(repo.wjoin(abs), end)
2556 ui.write(repo.wjoin(abs), end)
2552 else:
2557 else:
2553 ui.write(((pats and m.rel(abs)) or abs), end)
2558 ui.write(((pats and m.rel(abs)) or abs), end)
2554 ret = 0
2559 ret = 0
2555
2560
2556 return ret
2561 return ret
2557
2562
2558 def log(ui, repo, *pats, **opts):
2563 def log(ui, repo, *pats, **opts):
2559 """show revision history of entire repository or files
2564 """show revision history of entire repository or files
2560
2565
2561 Print the revision history of the specified files or the entire
2566 Print the revision history of the specified files or the entire
2562 project.
2567 project.
2563
2568
2564 File history is shown without following rename or copy history of
2569 File history is shown without following rename or copy history of
2565 files. Use -f/--follow with a filename to follow history across
2570 files. Use -f/--follow with a filename to follow history across
2566 renames and copies. --follow without a filename will only show
2571 renames and copies. --follow without a filename will only show
2567 ancestors or descendants of the starting revision. --follow-first
2572 ancestors or descendants of the starting revision. --follow-first
2568 only follows the first parent of merge revisions.
2573 only follows the first parent of merge revisions.
2569
2574
2570 If no revision range is specified, the default is ``tip:0`` unless
2575 If no revision range is specified, the default is ``tip:0`` unless
2571 --follow is set, in which case the working directory parent is
2576 --follow is set, in which case the working directory parent is
2572 used as the starting revision. You can specify a revision set for
2577 used as the starting revision. You can specify a revision set for
2573 log, see :hg:`help revsets` for more information.
2578 log, see :hg:`help revsets` for more information.
2574
2579
2575 See :hg:`help dates` for a list of formats valid for -d/--date.
2580 See :hg:`help dates` for a list of formats valid for -d/--date.
2576
2581
2577 By default this command prints revision number and changeset id,
2582 By default this command prints revision number and changeset id,
2578 tags, non-trivial parents, user, date and time, and a summary for
2583 tags, non-trivial parents, user, date and time, and a summary for
2579 each commit. When the -v/--verbose switch is used, the list of
2584 each commit. When the -v/--verbose switch is used, the list of
2580 changed files and full commit message are shown.
2585 changed files and full commit message are shown.
2581
2586
2582 .. note::
2587 .. note::
2583 log -p/--patch may generate unexpected diff output for merge
2588 log -p/--patch may generate unexpected diff output for merge
2584 changesets, as it will only compare the merge changeset against
2589 changesets, as it will only compare the merge changeset against
2585 its first parent. Also, only files different from BOTH parents
2590 its first parent. Also, only files different from BOTH parents
2586 will appear in files:.
2591 will appear in files:.
2587
2592
2588 Returns 0 on success.
2593 Returns 0 on success.
2589 """
2594 """
2590
2595
2591 matchfn = cmdutil.match(repo, pats, opts)
2596 matchfn = cmdutil.match(repo, pats, opts)
2592 limit = cmdutil.loglimit(opts)
2597 limit = cmdutil.loglimit(opts)
2593 count = 0
2598 count = 0
2594
2599
2595 endrev = None
2600 endrev = None
2596 if opts.get('copies') and opts.get('rev'):
2601 if opts.get('copies') and opts.get('rev'):
2597 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2602 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2598
2603
2599 df = False
2604 df = False
2600 if opts["date"]:
2605 if opts["date"]:
2601 df = util.matchdate(opts["date"])
2606 df = util.matchdate(opts["date"])
2602
2607
2603 branches = opts.get('branch', []) + opts.get('only_branch', [])
2608 branches = opts.get('branch', []) + opts.get('only_branch', [])
2604 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2609 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2605
2610
2606 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2611 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2607 def prep(ctx, fns):
2612 def prep(ctx, fns):
2608 rev = ctx.rev()
2613 rev = ctx.rev()
2609 parents = [p for p in repo.changelog.parentrevs(rev)
2614 parents = [p for p in repo.changelog.parentrevs(rev)
2610 if p != nullrev]
2615 if p != nullrev]
2611 if opts.get('no_merges') and len(parents) == 2:
2616 if opts.get('no_merges') and len(parents) == 2:
2612 return
2617 return
2613 if opts.get('only_merges') and len(parents) != 2:
2618 if opts.get('only_merges') and len(parents) != 2:
2614 return
2619 return
2615 if opts.get('branch') and ctx.branch() not in opts['branch']:
2620 if opts.get('branch') and ctx.branch() not in opts['branch']:
2616 return
2621 return
2617 if df and not df(ctx.date()[0]):
2622 if df and not df(ctx.date()[0]):
2618 return
2623 return
2619 if opts['user'] and not [k for k in opts['user']
2624 if opts['user'] and not [k for k in opts['user']
2620 if k.lower() in ctx.user().lower()]:
2625 if k.lower() in ctx.user().lower()]:
2621 return
2626 return
2622 if opts.get('keyword'):
2627 if opts.get('keyword'):
2623 for k in [kw.lower() for kw in opts['keyword']]:
2628 for k in [kw.lower() for kw in opts['keyword']]:
2624 if (k in ctx.user().lower() or
2629 if (k in ctx.user().lower() or
2625 k in ctx.description().lower() or
2630 k in ctx.description().lower() or
2626 k in " ".join(ctx.files()).lower()):
2631 k in " ".join(ctx.files()).lower()):
2627 break
2632 break
2628 else:
2633 else:
2629 return
2634 return
2630
2635
2631 copies = None
2636 copies = None
2632 if opts.get('copies') and rev:
2637 if opts.get('copies') and rev:
2633 copies = []
2638 copies = []
2634 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2639 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2635 for fn in ctx.files():
2640 for fn in ctx.files():
2636 rename = getrenamed(fn, rev)
2641 rename = getrenamed(fn, rev)
2637 if rename:
2642 if rename:
2638 copies.append((fn, rename[0]))
2643 copies.append((fn, rename[0]))
2639
2644
2640 revmatchfn = None
2645 revmatchfn = None
2641 if opts.get('patch') or opts.get('stat'):
2646 if opts.get('patch') or opts.get('stat'):
2642 if opts.get('follow') or opts.get('follow_first'):
2647 if opts.get('follow') or opts.get('follow_first'):
2643 # note: this might be wrong when following through merges
2648 # note: this might be wrong when following through merges
2644 revmatchfn = cmdutil.match(repo, fns, default='path')
2649 revmatchfn = cmdutil.match(repo, fns, default='path')
2645 else:
2650 else:
2646 revmatchfn = matchfn
2651 revmatchfn = matchfn
2647
2652
2648 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2653 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2649
2654
2650 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2655 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2651 if count == limit:
2656 if count == limit:
2652 break
2657 break
2653 if displayer.flush(ctx.rev()):
2658 if displayer.flush(ctx.rev()):
2654 count += 1
2659 count += 1
2655 displayer.close()
2660 displayer.close()
2656
2661
2657 def manifest(ui, repo, node=None, rev=None):
2662 def manifest(ui, repo, node=None, rev=None):
2658 """output the current or given revision of the project manifest
2663 """output the current or given revision of the project manifest
2659
2664
2660 Print a list of version controlled files for the given revision.
2665 Print a list of version controlled files for the given revision.
2661 If no revision is given, the first parent of the working directory
2666 If no revision is given, the first parent of the working directory
2662 is used, or the null revision if no revision is checked out.
2667 is used, or the null revision if no revision is checked out.
2663
2668
2664 With -v, print file permissions, symlink and executable bits.
2669 With -v, print file permissions, symlink and executable bits.
2665 With --debug, print file revision hashes.
2670 With --debug, print file revision hashes.
2666
2671
2667 Returns 0 on success.
2672 Returns 0 on success.
2668 """
2673 """
2669
2674
2670 if rev and node:
2675 if rev and node:
2671 raise util.Abort(_("please specify just one revision"))
2676 raise util.Abort(_("please specify just one revision"))
2672
2677
2673 if not node:
2678 if not node:
2674 node = rev
2679 node = rev
2675
2680
2676 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2681 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2677 ctx = cmdutil.revsingle(repo, node)
2682 ctx = cmdutil.revsingle(repo, node)
2678 for f in ctx:
2683 for f in ctx:
2679 if ui.debugflag:
2684 if ui.debugflag:
2680 ui.write("%40s " % hex(ctx.manifest()[f]))
2685 ui.write("%40s " % hex(ctx.manifest()[f]))
2681 if ui.verbose:
2686 if ui.verbose:
2682 ui.write(decor[ctx.flags(f)])
2687 ui.write(decor[ctx.flags(f)])
2683 ui.write("%s\n" % f)
2688 ui.write("%s\n" % f)
2684
2689
2685 def merge(ui, repo, node=None, **opts):
2690 def merge(ui, repo, node=None, **opts):
2686 """merge working directory with another revision
2691 """merge working directory with another revision
2687
2692
2688 The current working directory is updated with all changes made in
2693 The current working directory is updated with all changes made in
2689 the requested revision since the last common predecessor revision.
2694 the requested revision since the last common predecessor revision.
2690
2695
2691 Files that changed between either parent are marked as changed for
2696 Files that changed between either parent are marked as changed for
2692 the next commit and a commit must be performed before any further
2697 the next commit and a commit must be performed before any further
2693 updates to the repository are allowed. The next commit will have
2698 updates to the repository are allowed. The next commit will have
2694 two parents.
2699 two parents.
2695
2700
2696 ``--tool`` can be used to specify the merge tool used for file
2701 ``--tool`` can be used to specify the merge tool used for file
2697 merges. It overrides the HGMERGE environment variable and your
2702 merges. It overrides the HGMERGE environment variable and your
2698 configuration files.
2703 configuration files.
2699
2704
2700 If no revision is specified, the working directory's parent is a
2705 If no revision is specified, the working directory's parent is a
2701 head revision, and the current branch contains exactly one other
2706 head revision, and the current branch contains exactly one other
2702 head, the other head is merged with by default. Otherwise, an
2707 head, the other head is merged with by default. Otherwise, an
2703 explicit revision with which to merge with must be provided.
2708 explicit revision with which to merge with must be provided.
2704
2709
2705 :hg:`resolve` must be used to resolve unresolved files.
2710 :hg:`resolve` must be used to resolve unresolved files.
2706
2711
2707 To undo an uncommitted merge, use :hg:`update --clean .` which
2712 To undo an uncommitted merge, use :hg:`update --clean .` which
2708 will check out a clean copy of the original merge parent, losing
2713 will check out a clean copy of the original merge parent, losing
2709 all changes.
2714 all changes.
2710
2715
2711 Returns 0 on success, 1 if there are unresolved files.
2716 Returns 0 on success, 1 if there are unresolved files.
2712 """
2717 """
2713
2718
2714 if opts.get('rev') and node:
2719 if opts.get('rev') and node:
2715 raise util.Abort(_("please specify just one revision"))
2720 raise util.Abort(_("please specify just one revision"))
2716 if not node:
2721 if not node:
2717 node = opts.get('rev')
2722 node = opts.get('rev')
2718
2723
2719 if not node:
2724 if not node:
2720 branch = repo[None].branch()
2725 branch = repo[None].branch()
2721 bheads = repo.branchheads(branch)
2726 bheads = repo.branchheads(branch)
2722 if len(bheads) > 2:
2727 if len(bheads) > 2:
2723 raise util.Abort(_(
2728 raise util.Abort(_(
2724 'branch \'%s\' has %d heads - '
2729 'branch \'%s\' has %d heads - '
2725 'please merge with an explicit rev\n'
2730 'please merge with an explicit rev\n'
2726 '(run \'hg heads .\' to see heads)')
2731 '(run \'hg heads .\' to see heads)')
2727 % (branch, len(bheads)))
2732 % (branch, len(bheads)))
2728
2733
2729 parent = repo.dirstate.parents()[0]
2734 parent = repo.dirstate.parents()[0]
2730 if len(bheads) == 1:
2735 if len(bheads) == 1:
2731 if len(repo.heads()) > 1:
2736 if len(repo.heads()) > 1:
2732 raise util.Abort(_(
2737 raise util.Abort(_(
2733 'branch \'%s\' has one head - '
2738 'branch \'%s\' has one head - '
2734 'please merge with an explicit rev\n'
2739 'please merge with an explicit rev\n'
2735 '(run \'hg heads\' to see all heads)')
2740 '(run \'hg heads\' to see all heads)')
2736 % branch)
2741 % branch)
2737 msg = _('there is nothing to merge')
2742 msg = _('there is nothing to merge')
2738 if parent != repo.lookup(repo[None].branch()):
2743 if parent != repo.lookup(repo[None].branch()):
2739 msg = _('%s - use "hg update" instead') % msg
2744 msg = _('%s - use "hg update" instead') % msg
2740 raise util.Abort(msg)
2745 raise util.Abort(msg)
2741
2746
2742 if parent not in bheads:
2747 if parent not in bheads:
2743 raise util.Abort(_('working dir not at a head rev - '
2748 raise util.Abort(_('working dir not at a head rev - '
2744 'use "hg update" or merge with an explicit rev'))
2749 'use "hg update" or merge with an explicit rev'))
2745 node = parent == bheads[0] and bheads[-1] or bheads[0]
2750 node = parent == bheads[0] and bheads[-1] or bheads[0]
2746 else:
2751 else:
2747 node = cmdutil.revsingle(repo, node).node()
2752 node = cmdutil.revsingle(repo, node).node()
2748
2753
2749 if opts.get('preview'):
2754 if opts.get('preview'):
2750 # find nodes that are ancestors of p2 but not of p1
2755 # find nodes that are ancestors of p2 but not of p1
2751 p1 = repo.lookup('.')
2756 p1 = repo.lookup('.')
2752 p2 = repo.lookup(node)
2757 p2 = repo.lookup(node)
2753 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2758 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2754
2759
2755 displayer = cmdutil.show_changeset(ui, repo, opts)
2760 displayer = cmdutil.show_changeset(ui, repo, opts)
2756 for node in nodes:
2761 for node in nodes:
2757 displayer.show(repo[node])
2762 displayer.show(repo[node])
2758 displayer.close()
2763 displayer.close()
2759 return 0
2764 return 0
2760
2765
2761 try:
2766 try:
2762 # ui.forcemerge is an internal variable, do not document
2767 # ui.forcemerge is an internal variable, do not document
2763 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2768 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2764 return hg.merge(repo, node, force=opts.get('force'))
2769 return hg.merge(repo, node, force=opts.get('force'))
2765 finally:
2770 finally:
2766 ui.setconfig('ui', 'forcemerge', '')
2771 ui.setconfig('ui', 'forcemerge', '')
2767
2772
2768 def outgoing(ui, repo, dest=None, **opts):
2773 def outgoing(ui, repo, dest=None, **opts):
2769 """show changesets not found in the destination
2774 """show changesets not found in the destination
2770
2775
2771 Show changesets not found in the specified destination repository
2776 Show changesets not found in the specified destination repository
2772 or the default push location. These are the changesets that would
2777 or the default push location. These are the changesets that would
2773 be pushed if a push was requested.
2778 be pushed if a push was requested.
2774
2779
2775 See pull for details of valid destination formats.
2780 See pull for details of valid destination formats.
2776
2781
2777 Returns 0 if there are outgoing changes, 1 otherwise.
2782 Returns 0 if there are outgoing changes, 1 otherwise.
2778 """
2783 """
2779
2784
2780 if opts.get('bookmarks'):
2785 if opts.get('bookmarks'):
2781 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2786 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2782 dest, branches = hg.parseurl(dest, opts.get('branch'))
2787 dest, branches = hg.parseurl(dest, opts.get('branch'))
2783 other = hg.repository(hg.remoteui(repo, opts), dest)
2788 other = hg.repository(hg.remoteui(repo, opts), dest)
2784 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2789 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2785 return bookmarks.diff(ui, other, repo)
2790 return bookmarks.diff(ui, other, repo)
2786
2791
2787 ret = hg.outgoing(ui, repo, dest, opts)
2792 ret = hg.outgoing(ui, repo, dest, opts)
2788 return ret
2793 return ret
2789
2794
2790 def parents(ui, repo, file_=None, **opts):
2795 def parents(ui, repo, file_=None, **opts):
2791 """show the parents of the working directory or revision
2796 """show the parents of the working directory or revision
2792
2797
2793 Print the working directory's parent revisions. If a revision is
2798 Print the working directory's parent revisions. If a revision is
2794 given via -r/--rev, the parent of that revision will be printed.
2799 given via -r/--rev, the parent of that revision will be printed.
2795 If a file argument is given, the revision in which the file was
2800 If a file argument is given, the revision in which the file was
2796 last changed (before the working directory revision or the
2801 last changed (before the working directory revision or the
2797 argument to --rev if given) is printed.
2802 argument to --rev if given) is printed.
2798
2803
2799 Returns 0 on success.
2804 Returns 0 on success.
2800 """
2805 """
2801
2806
2802 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
2807 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
2803
2808
2804 if file_:
2809 if file_:
2805 m = cmdutil.match(repo, (file_,), opts)
2810 m = cmdutil.match(repo, (file_,), opts)
2806 if m.anypats() or len(m.files()) != 1:
2811 if m.anypats() or len(m.files()) != 1:
2807 raise util.Abort(_('can only specify an explicit filename'))
2812 raise util.Abort(_('can only specify an explicit filename'))
2808 file_ = m.files()[0]
2813 file_ = m.files()[0]
2809 filenodes = []
2814 filenodes = []
2810 for cp in ctx.parents():
2815 for cp in ctx.parents():
2811 if not cp:
2816 if not cp:
2812 continue
2817 continue
2813 try:
2818 try:
2814 filenodes.append(cp.filenode(file_))
2819 filenodes.append(cp.filenode(file_))
2815 except error.LookupError:
2820 except error.LookupError:
2816 pass
2821 pass
2817 if not filenodes:
2822 if not filenodes:
2818 raise util.Abort(_("'%s' not found in manifest!") % file_)
2823 raise util.Abort(_("'%s' not found in manifest!") % file_)
2819 fl = repo.file(file_)
2824 fl = repo.file(file_)
2820 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2825 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2821 else:
2826 else:
2822 p = [cp.node() for cp in ctx.parents()]
2827 p = [cp.node() for cp in ctx.parents()]
2823
2828
2824 displayer = cmdutil.show_changeset(ui, repo, opts)
2829 displayer = cmdutil.show_changeset(ui, repo, opts)
2825 for n in p:
2830 for n in p:
2826 if n != nullid:
2831 if n != nullid:
2827 displayer.show(repo[n])
2832 displayer.show(repo[n])
2828 displayer.close()
2833 displayer.close()
2829
2834
2830 def paths(ui, repo, search=None):
2835 def paths(ui, repo, search=None):
2831 """show aliases for remote repositories
2836 """show aliases for remote repositories
2832
2837
2833 Show definition of symbolic path name NAME. If no name is given,
2838 Show definition of symbolic path name NAME. If no name is given,
2834 show definition of all available names.
2839 show definition of all available names.
2835
2840
2836 Path names are defined in the [paths] section of your
2841 Path names are defined in the [paths] section of your
2837 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
2842 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
2838 repository, ``.hg/hgrc`` is used, too.
2843 repository, ``.hg/hgrc`` is used, too.
2839
2844
2840 The path names ``default`` and ``default-push`` have a special
2845 The path names ``default`` and ``default-push`` have a special
2841 meaning. When performing a push or pull operation, they are used
2846 meaning. When performing a push or pull operation, they are used
2842 as fallbacks if no location is specified on the command-line.
2847 as fallbacks if no location is specified on the command-line.
2843 When ``default-push`` is set, it will be used for push and
2848 When ``default-push`` is set, it will be used for push and
2844 ``default`` will be used for pull; otherwise ``default`` is used
2849 ``default`` will be used for pull; otherwise ``default`` is used
2845 as the fallback for both. When cloning a repository, the clone
2850 as the fallback for both. When cloning a repository, the clone
2846 source is written as ``default`` in ``.hg/hgrc``. Note that
2851 source is written as ``default`` in ``.hg/hgrc``. Note that
2847 ``default`` and ``default-push`` apply to all inbound (e.g.
2852 ``default`` and ``default-push`` apply to all inbound (e.g.
2848 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2853 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2849 :hg:`bundle`) operations.
2854 :hg:`bundle`) operations.
2850
2855
2851 See :hg:`help urls` for more information.
2856 See :hg:`help urls` for more information.
2852
2857
2853 Returns 0 on success.
2858 Returns 0 on success.
2854 """
2859 """
2855 if search:
2860 if search:
2856 for name, path in ui.configitems("paths"):
2861 for name, path in ui.configitems("paths"):
2857 if name == search:
2862 if name == search:
2858 ui.write("%s\n" % url.hidepassword(path))
2863 ui.write("%s\n" % url.hidepassword(path))
2859 return
2864 return
2860 ui.warn(_("not found!\n"))
2865 ui.warn(_("not found!\n"))
2861 return 1
2866 return 1
2862 else:
2867 else:
2863 for name, path in ui.configitems("paths"):
2868 for name, path in ui.configitems("paths"):
2864 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2869 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2865
2870
2866 def postincoming(ui, repo, modheads, optupdate, checkout):
2871 def postincoming(ui, repo, modheads, optupdate, checkout):
2867 if modheads == 0:
2872 if modheads == 0:
2868 return
2873 return
2869 if optupdate:
2874 if optupdate:
2870 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2875 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2871 return hg.update(repo, checkout)
2876 return hg.update(repo, checkout)
2872 else:
2877 else:
2873 ui.status(_("not updating, since new heads added\n"))
2878 ui.status(_("not updating, since new heads added\n"))
2874 if modheads > 1:
2879 if modheads > 1:
2875 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2880 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2876 else:
2881 else:
2877 ui.status(_("(run 'hg update' to get a working copy)\n"))
2882 ui.status(_("(run 'hg update' to get a working copy)\n"))
2878
2883
2879 def pull(ui, repo, source="default", **opts):
2884 def pull(ui, repo, source="default", **opts):
2880 """pull changes from the specified source
2885 """pull changes from the specified source
2881
2886
2882 Pull changes from a remote repository to a local one.
2887 Pull changes from a remote repository to a local one.
2883
2888
2884 This finds all changes from the repository at the specified path
2889 This finds all changes from the repository at the specified path
2885 or URL and adds them to a local repository (the current one unless
2890 or URL and adds them to a local repository (the current one unless
2886 -R is specified). By default, this does not update the copy of the
2891 -R is specified). By default, this does not update the copy of the
2887 project in the working directory.
2892 project in the working directory.
2888
2893
2889 Use :hg:`incoming` if you want to see what would have been added
2894 Use :hg:`incoming` if you want to see what would have been added
2890 by a pull at the time you issued this command. If you then decide
2895 by a pull at the time you issued this command. If you then decide
2891 to add those changes to the repository, you should use :hg:`pull
2896 to add those changes to the repository, you should use :hg:`pull
2892 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2897 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2893
2898
2894 If SOURCE is omitted, the 'default' path will be used.
2899 If SOURCE is omitted, the 'default' path will be used.
2895 See :hg:`help urls` for more information.
2900 See :hg:`help urls` for more information.
2896
2901
2897 Returns 0 on success, 1 if an update had unresolved files.
2902 Returns 0 on success, 1 if an update had unresolved files.
2898 """
2903 """
2899 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2904 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2900 other = hg.repository(hg.remoteui(repo, opts), source)
2905 other = hg.repository(hg.remoteui(repo, opts), source)
2901 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2906 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2902 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2907 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2903
2908
2904 if opts.get('bookmark'):
2909 if opts.get('bookmark'):
2905 if not revs:
2910 if not revs:
2906 revs = []
2911 revs = []
2907 rb = other.listkeys('bookmarks')
2912 rb = other.listkeys('bookmarks')
2908 for b in opts['bookmark']:
2913 for b in opts['bookmark']:
2909 if b not in rb:
2914 if b not in rb:
2910 raise util.Abort(_('remote bookmark %s not found!') % b)
2915 raise util.Abort(_('remote bookmark %s not found!') % b)
2911 revs.append(rb[b])
2916 revs.append(rb[b])
2912
2917
2913 if revs:
2918 if revs:
2914 try:
2919 try:
2915 revs = [other.lookup(rev) for rev in revs]
2920 revs = [other.lookup(rev) for rev in revs]
2916 except error.CapabilityError:
2921 except error.CapabilityError:
2917 err = _("other repository doesn't support revision lookup, "
2922 err = _("other repository doesn't support revision lookup, "
2918 "so a rev cannot be specified.")
2923 "so a rev cannot be specified.")
2919 raise util.Abort(err)
2924 raise util.Abort(err)
2920
2925
2921 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2926 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2922 if checkout:
2927 if checkout:
2923 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2928 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2924 repo._subtoppath = source
2929 repo._subtoppath = source
2925 try:
2930 try:
2926 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
2931 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
2927
2932
2928 finally:
2933 finally:
2929 del repo._subtoppath
2934 del repo._subtoppath
2930
2935
2931 # update specified bookmarks
2936 # update specified bookmarks
2932 if opts.get('bookmark'):
2937 if opts.get('bookmark'):
2933 for b in opts['bookmark']:
2938 for b in opts['bookmark']:
2934 # explicit pull overrides local bookmark if any
2939 # explicit pull overrides local bookmark if any
2935 ui.status(_("importing bookmark %s\n") % b)
2940 ui.status(_("importing bookmark %s\n") % b)
2936 repo._bookmarks[b] = repo[rb[b]].node()
2941 repo._bookmarks[b] = repo[rb[b]].node()
2937 bookmarks.write(repo)
2942 bookmarks.write(repo)
2938
2943
2939 return ret
2944 return ret
2940
2945
2941 def push(ui, repo, dest=None, **opts):
2946 def push(ui, repo, dest=None, **opts):
2942 """push changes to the specified destination
2947 """push changes to the specified destination
2943
2948
2944 Push changesets from the local repository to the specified
2949 Push changesets from the local repository to the specified
2945 destination.
2950 destination.
2946
2951
2947 This operation is symmetrical to pull: it is identical to a pull
2952 This operation is symmetrical to pull: it is identical to a pull
2948 in the destination repository from the current one.
2953 in the destination repository from the current one.
2949
2954
2950 By default, push will not allow creation of new heads at the
2955 By default, push will not allow creation of new heads at the
2951 destination, since multiple heads would make it unclear which head
2956 destination, since multiple heads would make it unclear which head
2952 to use. In this situation, it is recommended to pull and merge
2957 to use. In this situation, it is recommended to pull and merge
2953 before pushing.
2958 before pushing.
2954
2959
2955 Use --new-branch if you want to allow push to create a new named
2960 Use --new-branch if you want to allow push to create a new named
2956 branch that is not present at the destination. This allows you to
2961 branch that is not present at the destination. This allows you to
2957 only create a new branch without forcing other changes.
2962 only create a new branch without forcing other changes.
2958
2963
2959 Use -f/--force to override the default behavior and push all
2964 Use -f/--force to override the default behavior and push all
2960 changesets on all branches.
2965 changesets on all branches.
2961
2966
2962 If -r/--rev is used, the specified revision and all its ancestors
2967 If -r/--rev is used, the specified revision and all its ancestors
2963 will be pushed to the remote repository.
2968 will be pushed to the remote repository.
2964
2969
2965 Please see :hg:`help urls` for important details about ``ssh://``
2970 Please see :hg:`help urls` for important details about ``ssh://``
2966 URLs. If DESTINATION is omitted, a default path will be used.
2971 URLs. If DESTINATION is omitted, a default path will be used.
2967
2972
2968 Returns 0 if push was successful, 1 if nothing to push.
2973 Returns 0 if push was successful, 1 if nothing to push.
2969 """
2974 """
2970
2975
2971 if opts.get('bookmark'):
2976 if opts.get('bookmark'):
2972 for b in opts['bookmark']:
2977 for b in opts['bookmark']:
2973 # translate -B options to -r so changesets get pushed
2978 # translate -B options to -r so changesets get pushed
2974 if b in repo._bookmarks:
2979 if b in repo._bookmarks:
2975 opts.setdefault('rev', []).append(b)
2980 opts.setdefault('rev', []).append(b)
2976 else:
2981 else:
2977 # if we try to push a deleted bookmark, translate it to null
2982 # if we try to push a deleted bookmark, translate it to null
2978 # this lets simultaneous -r, -b options continue working
2983 # this lets simultaneous -r, -b options continue working
2979 opts.setdefault('rev', []).append("null")
2984 opts.setdefault('rev', []).append("null")
2980
2985
2981 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2986 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2982 dest, branches = hg.parseurl(dest, opts.get('branch'))
2987 dest, branches = hg.parseurl(dest, opts.get('branch'))
2983 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2988 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2984 other = hg.repository(hg.remoteui(repo, opts), dest)
2989 other = hg.repository(hg.remoteui(repo, opts), dest)
2985 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2990 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2986 if revs:
2991 if revs:
2987 revs = [repo.lookup(rev) for rev in revs]
2992 revs = [repo.lookup(rev) for rev in revs]
2988
2993
2989 repo._subtoppath = dest
2994 repo._subtoppath = dest
2990 try:
2995 try:
2991 # push subrepos depth-first for coherent ordering
2996 # push subrepos depth-first for coherent ordering
2992 c = repo['']
2997 c = repo['']
2993 subs = c.substate # only repos that are committed
2998 subs = c.substate # only repos that are committed
2994 for s in sorted(subs):
2999 for s in sorted(subs):
2995 if not c.sub(s).push(opts.get('force')):
3000 if not c.sub(s).push(opts.get('force')):
2996 return False
3001 return False
2997 finally:
3002 finally:
2998 del repo._subtoppath
3003 del repo._subtoppath
2999 result = repo.push(other, opts.get('force'), revs=revs,
3004 result = repo.push(other, opts.get('force'), revs=revs,
3000 newbranch=opts.get('new_branch'))
3005 newbranch=opts.get('new_branch'))
3001
3006
3002 result = (result == 0)
3007 result = (result == 0)
3003
3008
3004 if opts.get('bookmark'):
3009 if opts.get('bookmark'):
3005 rb = other.listkeys('bookmarks')
3010 rb = other.listkeys('bookmarks')
3006 for b in opts['bookmark']:
3011 for b in opts['bookmark']:
3007 # explicit push overrides remote bookmark if any
3012 # explicit push overrides remote bookmark if any
3008 if b in repo._bookmarks:
3013 if b in repo._bookmarks:
3009 ui.status(_("exporting bookmark %s\n") % b)
3014 ui.status(_("exporting bookmark %s\n") % b)
3010 new = repo[b].hex()
3015 new = repo[b].hex()
3011 elif b in rb:
3016 elif b in rb:
3012 ui.status(_("deleting remote bookmark %s\n") % b)
3017 ui.status(_("deleting remote bookmark %s\n") % b)
3013 new = '' # delete
3018 new = '' # delete
3014 else:
3019 else:
3015 ui.warn(_('bookmark %s does not exist on the local '
3020 ui.warn(_('bookmark %s does not exist on the local '
3016 'or remote repository!\n') % b)
3021 'or remote repository!\n') % b)
3017 return 2
3022 return 2
3018 old = rb.get(b, '')
3023 old = rb.get(b, '')
3019 r = other.pushkey('bookmarks', b, old, new)
3024 r = other.pushkey('bookmarks', b, old, new)
3020 if not r:
3025 if not r:
3021 ui.warn(_('updating bookmark %s failed!\n') % b)
3026 ui.warn(_('updating bookmark %s failed!\n') % b)
3022 if not result:
3027 if not result:
3023 result = 2
3028 result = 2
3024
3029
3025 return result
3030 return result
3026
3031
3027 def recover(ui, repo):
3032 def recover(ui, repo):
3028 """roll back an interrupted transaction
3033 """roll back an interrupted transaction
3029
3034
3030 Recover from an interrupted commit or pull.
3035 Recover from an interrupted commit or pull.
3031
3036
3032 This command tries to fix the repository status after an
3037 This command tries to fix the repository status after an
3033 interrupted operation. It should only be necessary when Mercurial
3038 interrupted operation. It should only be necessary when Mercurial
3034 suggests it.
3039 suggests it.
3035
3040
3036 Returns 0 if successful, 1 if nothing to recover or verify fails.
3041 Returns 0 if successful, 1 if nothing to recover or verify fails.
3037 """
3042 """
3038 if repo.recover():
3043 if repo.recover():
3039 return hg.verify(repo)
3044 return hg.verify(repo)
3040 return 1
3045 return 1
3041
3046
3042 def remove(ui, repo, *pats, **opts):
3047 def remove(ui, repo, *pats, **opts):
3043 """remove the specified files on the next commit
3048 """remove the specified files on the next commit
3044
3049
3045 Schedule the indicated files for removal from the repository.
3050 Schedule the indicated files for removal from the repository.
3046
3051
3047 This only removes files from the current branch, not from the
3052 This only removes files from the current branch, not from the
3048 entire project history. -A/--after can be used to remove only
3053 entire project history. -A/--after can be used to remove only
3049 files that have already been deleted, -f/--force can be used to
3054 files that have already been deleted, -f/--force can be used to
3050 force deletion, and -Af can be used to remove files from the next
3055 force deletion, and -Af can be used to remove files from the next
3051 revision without deleting them from the working directory.
3056 revision without deleting them from the working directory.
3052
3057
3053 The following table details the behavior of remove for different
3058 The following table details the behavior of remove for different
3054 file states (columns) and option combinations (rows). The file
3059 file states (columns) and option combinations (rows). The file
3055 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3060 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3056 reported by :hg:`status`). The actions are Warn, Remove (from
3061 reported by :hg:`status`). The actions are Warn, Remove (from
3057 branch) and Delete (from disk)::
3062 branch) and Delete (from disk)::
3058
3063
3059 A C M !
3064 A C M !
3060 none W RD W R
3065 none W RD W R
3061 -f R RD RD R
3066 -f R RD RD R
3062 -A W W W R
3067 -A W W W R
3063 -Af R R R R
3068 -Af R R R R
3064
3069
3065 This command schedules the files to be removed at the next commit.
3070 This command schedules the files to be removed at the next commit.
3066 To undo a remove before that, see :hg:`revert`.
3071 To undo a remove before that, see :hg:`revert`.
3067
3072
3068 Returns 0 on success, 1 if any warnings encountered.
3073 Returns 0 on success, 1 if any warnings encountered.
3069 """
3074 """
3070
3075
3071 ret = 0
3076 ret = 0
3072 after, force = opts.get('after'), opts.get('force')
3077 after, force = opts.get('after'), opts.get('force')
3073 if not pats and not after:
3078 if not pats and not after:
3074 raise util.Abort(_('no files specified'))
3079 raise util.Abort(_('no files specified'))
3075
3080
3076 m = cmdutil.match(repo, pats, opts)
3081 m = cmdutil.match(repo, pats, opts)
3077 s = repo.status(match=m, clean=True)
3082 s = repo.status(match=m, clean=True)
3078 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3083 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3079
3084
3080 for f in m.files():
3085 for f in m.files():
3081 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3086 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3082 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3087 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3083 ret = 1
3088 ret = 1
3084
3089
3085 if force:
3090 if force:
3086 remove, forget = modified + deleted + clean, added
3091 remove, forget = modified + deleted + clean, added
3087 elif after:
3092 elif after:
3088 remove, forget = deleted, []
3093 remove, forget = deleted, []
3089 for f in modified + added + clean:
3094 for f in modified + added + clean:
3090 ui.warn(_('not removing %s: file still exists (use -f'
3095 ui.warn(_('not removing %s: file still exists (use -f'
3091 ' to force removal)\n') % m.rel(f))
3096 ' to force removal)\n') % m.rel(f))
3092 ret = 1
3097 ret = 1
3093 else:
3098 else:
3094 remove, forget = deleted + clean, []
3099 remove, forget = deleted + clean, []
3095 for f in modified:
3100 for f in modified:
3096 ui.warn(_('not removing %s: file is modified (use -f'
3101 ui.warn(_('not removing %s: file is modified (use -f'
3097 ' to force removal)\n') % m.rel(f))
3102 ' to force removal)\n') % m.rel(f))
3098 ret = 1
3103 ret = 1
3099 for f in added:
3104 for f in added:
3100 ui.warn(_('not removing %s: file has been marked for add (use -f'
3105 ui.warn(_('not removing %s: file has been marked for add (use -f'
3101 ' to force removal)\n') % m.rel(f))
3106 ' to force removal)\n') % m.rel(f))
3102 ret = 1
3107 ret = 1
3103
3108
3104 for f in sorted(remove + forget):
3109 for f in sorted(remove + forget):
3105 if ui.verbose or not m.exact(f):
3110 if ui.verbose or not m.exact(f):
3106 ui.status(_('removing %s\n') % m.rel(f))
3111 ui.status(_('removing %s\n') % m.rel(f))
3107
3112
3108 repo[None].forget(forget)
3113 repo[None].forget(forget)
3109 repo[None].remove(remove, unlink=not after)
3114 repo[None].remove(remove, unlink=not after)
3110 return ret
3115 return ret
3111
3116
3112 def rename(ui, repo, *pats, **opts):
3117 def rename(ui, repo, *pats, **opts):
3113 """rename files; equivalent of copy + remove
3118 """rename files; equivalent of copy + remove
3114
3119
3115 Mark dest as copies of sources; mark sources for deletion. If dest
3120 Mark dest as copies of sources; mark sources for deletion. If dest
3116 is a directory, copies are put in that directory. If dest is a
3121 is a directory, copies are put in that directory. If dest is a
3117 file, there can only be one source.
3122 file, there can only be one source.
3118
3123
3119 By default, this command copies the contents of files as they
3124 By default, this command copies the contents of files as they
3120 exist in the working directory. If invoked with -A/--after, the
3125 exist in the working directory. If invoked with -A/--after, the
3121 operation is recorded, but no copying is performed.
3126 operation is recorded, but no copying is performed.
3122
3127
3123 This command takes effect at the next commit. To undo a rename
3128 This command takes effect at the next commit. To undo a rename
3124 before that, see :hg:`revert`.
3129 before that, see :hg:`revert`.
3125
3130
3126 Returns 0 on success, 1 if errors are encountered.
3131 Returns 0 on success, 1 if errors are encountered.
3127 """
3132 """
3128 wlock = repo.wlock(False)
3133 wlock = repo.wlock(False)
3129 try:
3134 try:
3130 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3135 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3131 finally:
3136 finally:
3132 wlock.release()
3137 wlock.release()
3133
3138
3134 def resolve(ui, repo, *pats, **opts):
3139 def resolve(ui, repo, *pats, **opts):
3135 """redo merges or set/view the merge status of files
3140 """redo merges or set/view the merge status of files
3136
3141
3137 Merges with unresolved conflicts are often the result of
3142 Merges with unresolved conflicts are often the result of
3138 non-interactive merging using the ``internal:merge`` configuration
3143 non-interactive merging using the ``internal:merge`` configuration
3139 setting, or a command-line merge tool like ``diff3``. The resolve
3144 setting, or a command-line merge tool like ``diff3``. The resolve
3140 command is used to manage the files involved in a merge, after
3145 command is used to manage the files involved in a merge, after
3141 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3146 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3142 working directory must have two parents).
3147 working directory must have two parents).
3143
3148
3144 The resolve command can be used in the following ways:
3149 The resolve command can be used in the following ways:
3145
3150
3146 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3151 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3147 files, discarding any previous merge attempts. Re-merging is not
3152 files, discarding any previous merge attempts. Re-merging is not
3148 performed for files already marked as resolved. Use ``--all/-a``
3153 performed for files already marked as resolved. Use ``--all/-a``
3149 to selects all unresolved files. ``--tool`` can be used to specify
3154 to selects all unresolved files. ``--tool`` can be used to specify
3150 the merge tool used for the given files. It overrides the HGMERGE
3155 the merge tool used for the given files. It overrides the HGMERGE
3151 environment variable and your configuration files.
3156 environment variable and your configuration files.
3152
3157
3153 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3158 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3154 (e.g. after having manually fixed-up the files). The default is
3159 (e.g. after having manually fixed-up the files). The default is
3155 to mark all unresolved files.
3160 to mark all unresolved files.
3156
3161
3157 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3162 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3158 default is to mark all resolved files.
3163 default is to mark all resolved files.
3159
3164
3160 - :hg:`resolve -l`: list files which had or still have conflicts.
3165 - :hg:`resolve -l`: list files which had or still have conflicts.
3161 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3166 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3162
3167
3163 Note that Mercurial will not let you commit files with unresolved
3168 Note that Mercurial will not let you commit files with unresolved
3164 merge conflicts. You must use :hg:`resolve -m ...` before you can
3169 merge conflicts. You must use :hg:`resolve -m ...` before you can
3165 commit after a conflicting merge.
3170 commit after a conflicting merge.
3166
3171
3167 Returns 0 on success, 1 if any files fail a resolve attempt.
3172 Returns 0 on success, 1 if any files fail a resolve attempt.
3168 """
3173 """
3169
3174
3170 all, mark, unmark, show, nostatus = \
3175 all, mark, unmark, show, nostatus = \
3171 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3176 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3172
3177
3173 if (show and (mark or unmark)) or (mark and unmark):
3178 if (show and (mark or unmark)) or (mark and unmark):
3174 raise util.Abort(_("too many options specified"))
3179 raise util.Abort(_("too many options specified"))
3175 if pats and all:
3180 if pats and all:
3176 raise util.Abort(_("can't specify --all and patterns"))
3181 raise util.Abort(_("can't specify --all and patterns"))
3177 if not (all or pats or show or mark or unmark):
3182 if not (all or pats or show or mark or unmark):
3178 raise util.Abort(_('no files or directories specified; '
3183 raise util.Abort(_('no files or directories specified; '
3179 'use --all to remerge all files'))
3184 'use --all to remerge all files'))
3180
3185
3181 ms = mergemod.mergestate(repo)
3186 ms = mergemod.mergestate(repo)
3182 m = cmdutil.match(repo, pats, opts)
3187 m = cmdutil.match(repo, pats, opts)
3183 ret = 0
3188 ret = 0
3184
3189
3185 for f in ms:
3190 for f in ms:
3186 if m(f):
3191 if m(f):
3187 if show:
3192 if show:
3188 if nostatus:
3193 if nostatus:
3189 ui.write("%s\n" % f)
3194 ui.write("%s\n" % f)
3190 else:
3195 else:
3191 ui.write("%s %s\n" % (ms[f].upper(), f),
3196 ui.write("%s %s\n" % (ms[f].upper(), f),
3192 label='resolve.' +
3197 label='resolve.' +
3193 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3198 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3194 elif mark:
3199 elif mark:
3195 ms.mark(f, "r")
3200 ms.mark(f, "r")
3196 elif unmark:
3201 elif unmark:
3197 ms.mark(f, "u")
3202 ms.mark(f, "u")
3198 else:
3203 else:
3199 wctx = repo[None]
3204 wctx = repo[None]
3200 mctx = wctx.parents()[-1]
3205 mctx = wctx.parents()[-1]
3201
3206
3202 # backup pre-resolve (merge uses .orig for its own purposes)
3207 # backup pre-resolve (merge uses .orig for its own purposes)
3203 a = repo.wjoin(f)
3208 a = repo.wjoin(f)
3204 util.copyfile(a, a + ".resolve")
3209 util.copyfile(a, a + ".resolve")
3205
3210
3206 try:
3211 try:
3207 # resolve file
3212 # resolve file
3208 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3213 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3209 if ms.resolve(f, wctx, mctx):
3214 if ms.resolve(f, wctx, mctx):
3210 ret = 1
3215 ret = 1
3211 finally:
3216 finally:
3212 ui.setconfig('ui', 'forcemerge', '')
3217 ui.setconfig('ui', 'forcemerge', '')
3213
3218
3214 # replace filemerge's .orig file with our resolve file
3219 # replace filemerge's .orig file with our resolve file
3215 util.rename(a + ".resolve", a + ".orig")
3220 util.rename(a + ".resolve", a + ".orig")
3216
3221
3217 ms.commit()
3222 ms.commit()
3218 return ret
3223 return ret
3219
3224
3220 def revert(ui, repo, *pats, **opts):
3225 def revert(ui, repo, *pats, **opts):
3221 """restore individual files or directories to an earlier state
3226 """restore individual files or directories to an earlier state
3222
3227
3223 .. note::
3228 .. note::
3224 This command is most likely not what you are looking for.
3229 This command is most likely not what you are looking for.
3225 Revert will partially overwrite content in the working
3230 Revert will partially overwrite content in the working
3226 directory without changing the working directory parents. Use
3231 directory without changing the working directory parents. Use
3227 :hg:`update -r rev` to check out earlier revisions, or
3232 :hg:`update -r rev` to check out earlier revisions, or
3228 :hg:`update --clean .` to undo a merge which has added another
3233 :hg:`update --clean .` to undo a merge which has added another
3229 parent.
3234 parent.
3230
3235
3231 With no revision specified, revert the named files or directories
3236 With no revision specified, revert the named files or directories
3232 to the contents they had in the parent of the working directory.
3237 to the contents they had in the parent of the working directory.
3233 This restores the contents of the affected files to an unmodified
3238 This restores the contents of the affected files to an unmodified
3234 state and unschedules adds, removes, copies, and renames. If the
3239 state and unschedules adds, removes, copies, and renames. If the
3235 working directory has two parents, you must explicitly specify a
3240 working directory has two parents, you must explicitly specify a
3236 revision.
3241 revision.
3237
3242
3238 Using the -r/--rev option, revert the given files or directories
3243 Using the -r/--rev option, revert the given files or directories
3239 to their contents as of a specific revision. This can be helpful
3244 to their contents as of a specific revision. This can be helpful
3240 to "roll back" some or all of an earlier change. See :hg:`help
3245 to "roll back" some or all of an earlier change. See :hg:`help
3241 dates` for a list of formats valid for -d/--date.
3246 dates` for a list of formats valid for -d/--date.
3242
3247
3243 Revert modifies the working directory. It does not commit any
3248 Revert modifies the working directory. It does not commit any
3244 changes, or change the parent of the working directory. If you
3249 changes, or change the parent of the working directory. If you
3245 revert to a revision other than the parent of the working
3250 revert to a revision other than the parent of the working
3246 directory, the reverted files will thus appear modified
3251 directory, the reverted files will thus appear modified
3247 afterwards.
3252 afterwards.
3248
3253
3249 If a file has been deleted, it is restored. If the executable mode
3254 If a file has been deleted, it is restored. If the executable mode
3250 of a file was changed, it is reset.
3255 of a file was changed, it is reset.
3251
3256
3252 If names are given, all files matching the names are reverted.
3257 If names are given, all files matching the names are reverted.
3253 If no arguments are given, no files are reverted.
3258 If no arguments are given, no files are reverted.
3254
3259
3255 Modified files are saved with a .orig suffix before reverting.
3260 Modified files are saved with a .orig suffix before reverting.
3256 To disable these backups, use --no-backup.
3261 To disable these backups, use --no-backup.
3257
3262
3258 Returns 0 on success.
3263 Returns 0 on success.
3259 """
3264 """
3260
3265
3261 if opts.get("date"):
3266 if opts.get("date"):
3262 if opts.get("rev"):
3267 if opts.get("rev"):
3263 raise util.Abort(_("you can't specify a revision and a date"))
3268 raise util.Abort(_("you can't specify a revision and a date"))
3264 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3269 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3265
3270
3266 parent, p2 = repo.dirstate.parents()
3271 parent, p2 = repo.dirstate.parents()
3267 if not opts.get('rev') and p2 != nullid:
3272 if not opts.get('rev') and p2 != nullid:
3268 raise util.Abort(_('uncommitted merge - '
3273 raise util.Abort(_('uncommitted merge - '
3269 'use "hg update", see "hg help revert"'))
3274 'use "hg update", see "hg help revert"'))
3270
3275
3271 if not pats and not opts.get('all'):
3276 if not pats and not opts.get('all'):
3272 raise util.Abort(_('no files or directories specified; '
3277 raise util.Abort(_('no files or directories specified; '
3273 'use --all to revert the whole repo'))
3278 'use --all to revert the whole repo'))
3274
3279
3275 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3280 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3276 node = ctx.node()
3281 node = ctx.node()
3277 mf = ctx.manifest()
3282 mf = ctx.manifest()
3278 if node == parent:
3283 if node == parent:
3279 pmf = mf
3284 pmf = mf
3280 else:
3285 else:
3281 pmf = None
3286 pmf = None
3282
3287
3283 # need all matching names in dirstate and manifest of target rev,
3288 # need all matching names in dirstate and manifest of target rev,
3284 # so have to walk both. do not print errors if files exist in one
3289 # so have to walk both. do not print errors if files exist in one
3285 # but not other.
3290 # but not other.
3286
3291
3287 names = {}
3292 names = {}
3288
3293
3289 wlock = repo.wlock()
3294 wlock = repo.wlock()
3290 try:
3295 try:
3291 # walk dirstate.
3296 # walk dirstate.
3292
3297
3293 m = cmdutil.match(repo, pats, opts)
3298 m = cmdutil.match(repo, pats, opts)
3294 m.bad = lambda x, y: False
3299 m.bad = lambda x, y: False
3295 for abs in repo.walk(m):
3300 for abs in repo.walk(m):
3296 names[abs] = m.rel(abs), m.exact(abs)
3301 names[abs] = m.rel(abs), m.exact(abs)
3297
3302
3298 # walk target manifest.
3303 # walk target manifest.
3299
3304
3300 def badfn(path, msg):
3305 def badfn(path, msg):
3301 if path in names:
3306 if path in names:
3302 return
3307 return
3303 path_ = path + '/'
3308 path_ = path + '/'
3304 for f in names:
3309 for f in names:
3305 if f.startswith(path_):
3310 if f.startswith(path_):
3306 return
3311 return
3307 ui.warn("%s: %s\n" % (m.rel(path), msg))
3312 ui.warn("%s: %s\n" % (m.rel(path), msg))
3308
3313
3309 m = cmdutil.match(repo, pats, opts)
3314 m = cmdutil.match(repo, pats, opts)
3310 m.bad = badfn
3315 m.bad = badfn
3311 for abs in repo[node].walk(m):
3316 for abs in repo[node].walk(m):
3312 if abs not in names:
3317 if abs not in names:
3313 names[abs] = m.rel(abs), m.exact(abs)
3318 names[abs] = m.rel(abs), m.exact(abs)
3314
3319
3315 m = cmdutil.matchfiles(repo, names)
3320 m = cmdutil.matchfiles(repo, names)
3316 changes = repo.status(match=m)[:4]
3321 changes = repo.status(match=m)[:4]
3317 modified, added, removed, deleted = map(set, changes)
3322 modified, added, removed, deleted = map(set, changes)
3318
3323
3319 # if f is a rename, also revert the source
3324 # if f is a rename, also revert the source
3320 cwd = repo.getcwd()
3325 cwd = repo.getcwd()
3321 for f in added:
3326 for f in added:
3322 src = repo.dirstate.copied(f)
3327 src = repo.dirstate.copied(f)
3323 if src and src not in names and repo.dirstate[src] == 'r':
3328 if src and src not in names and repo.dirstate[src] == 'r':
3324 removed.add(src)
3329 removed.add(src)
3325 names[src] = (repo.pathto(src, cwd), True)
3330 names[src] = (repo.pathto(src, cwd), True)
3326
3331
3327 def removeforget(abs):
3332 def removeforget(abs):
3328 if repo.dirstate[abs] == 'a':
3333 if repo.dirstate[abs] == 'a':
3329 return _('forgetting %s\n')
3334 return _('forgetting %s\n')
3330 return _('removing %s\n')
3335 return _('removing %s\n')
3331
3336
3332 revert = ([], _('reverting %s\n'))
3337 revert = ([], _('reverting %s\n'))
3333 add = ([], _('adding %s\n'))
3338 add = ([], _('adding %s\n'))
3334 remove = ([], removeforget)
3339 remove = ([], removeforget)
3335 undelete = ([], _('undeleting %s\n'))
3340 undelete = ([], _('undeleting %s\n'))
3336
3341
3337 disptable = (
3342 disptable = (
3338 # dispatch table:
3343 # dispatch table:
3339 # file state
3344 # file state
3340 # action if in target manifest
3345 # action if in target manifest
3341 # action if not in target manifest
3346 # action if not in target manifest
3342 # make backup if in target manifest
3347 # make backup if in target manifest
3343 # make backup if not in target manifest
3348 # make backup if not in target manifest
3344 (modified, revert, remove, True, True),
3349 (modified, revert, remove, True, True),
3345 (added, revert, remove, True, False),
3350 (added, revert, remove, True, False),
3346 (removed, undelete, None, False, False),
3351 (removed, undelete, None, False, False),
3347 (deleted, revert, remove, False, False),
3352 (deleted, revert, remove, False, False),
3348 )
3353 )
3349
3354
3350 for abs, (rel, exact) in sorted(names.items()):
3355 for abs, (rel, exact) in sorted(names.items()):
3351 mfentry = mf.get(abs)
3356 mfentry = mf.get(abs)
3352 target = repo.wjoin(abs)
3357 target = repo.wjoin(abs)
3353 def handle(xlist, dobackup):
3358 def handle(xlist, dobackup):
3354 xlist[0].append(abs)
3359 xlist[0].append(abs)
3355 if (dobackup and not opts.get('no_backup') and
3360 if (dobackup and not opts.get('no_backup') and
3356 os.path.lexists(target)):
3361 os.path.lexists(target)):
3357 bakname = "%s.orig" % rel
3362 bakname = "%s.orig" % rel
3358 ui.note(_('saving current version of %s as %s\n') %
3363 ui.note(_('saving current version of %s as %s\n') %
3359 (rel, bakname))
3364 (rel, bakname))
3360 if not opts.get('dry_run'):
3365 if not opts.get('dry_run'):
3361 util.rename(target, bakname)
3366 util.rename(target, bakname)
3362 if ui.verbose or not exact:
3367 if ui.verbose or not exact:
3363 msg = xlist[1]
3368 msg = xlist[1]
3364 if not isinstance(msg, basestring):
3369 if not isinstance(msg, basestring):
3365 msg = msg(abs)
3370 msg = msg(abs)
3366 ui.status(msg % rel)
3371 ui.status(msg % rel)
3367 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3372 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3368 if abs not in table:
3373 if abs not in table:
3369 continue
3374 continue
3370 # file has changed in dirstate
3375 # file has changed in dirstate
3371 if mfentry:
3376 if mfentry:
3372 handle(hitlist, backuphit)
3377 handle(hitlist, backuphit)
3373 elif misslist is not None:
3378 elif misslist is not None:
3374 handle(misslist, backupmiss)
3379 handle(misslist, backupmiss)
3375 break
3380 break
3376 else:
3381 else:
3377 if abs not in repo.dirstate:
3382 if abs not in repo.dirstate:
3378 if mfentry:
3383 if mfentry:
3379 handle(add, True)
3384 handle(add, True)
3380 elif exact:
3385 elif exact:
3381 ui.warn(_('file not managed: %s\n') % rel)
3386 ui.warn(_('file not managed: %s\n') % rel)
3382 continue
3387 continue
3383 # file has not changed in dirstate
3388 # file has not changed in dirstate
3384 if node == parent:
3389 if node == parent:
3385 if exact:
3390 if exact:
3386 ui.warn(_('no changes needed to %s\n') % rel)
3391 ui.warn(_('no changes needed to %s\n') % rel)
3387 continue
3392 continue
3388 if pmf is None:
3393 if pmf is None:
3389 # only need parent manifest in this unlikely case,
3394 # only need parent manifest in this unlikely case,
3390 # so do not read by default
3395 # so do not read by default
3391 pmf = repo[parent].manifest()
3396 pmf = repo[parent].manifest()
3392 if abs in pmf:
3397 if abs in pmf:
3393 if mfentry:
3398 if mfentry:
3394 # if version of file is same in parent and target
3399 # if version of file is same in parent and target
3395 # manifests, do nothing
3400 # manifests, do nothing
3396 if (pmf[abs] != mfentry or
3401 if (pmf[abs] != mfentry or
3397 pmf.flags(abs) != mf.flags(abs)):
3402 pmf.flags(abs) != mf.flags(abs)):
3398 handle(revert, False)
3403 handle(revert, False)
3399 else:
3404 else:
3400 handle(remove, False)
3405 handle(remove, False)
3401
3406
3402 if not opts.get('dry_run'):
3407 if not opts.get('dry_run'):
3403 def checkout(f):
3408 def checkout(f):
3404 fc = ctx[f]
3409 fc = ctx[f]
3405 repo.wwrite(f, fc.data(), fc.flags())
3410 repo.wwrite(f, fc.data(), fc.flags())
3406
3411
3407 audit_path = util.path_auditor(repo.root)
3412 audit_path = util.path_auditor(repo.root)
3408 for f in remove[0]:
3413 for f in remove[0]:
3409 if repo.dirstate[f] == 'a':
3414 if repo.dirstate[f] == 'a':
3410 repo.dirstate.forget(f)
3415 repo.dirstate.forget(f)
3411 continue
3416 continue
3412 audit_path(f)
3417 audit_path(f)
3413 try:
3418 try:
3414 util.unlinkpath(repo.wjoin(f))
3419 util.unlinkpath(repo.wjoin(f))
3415 except OSError:
3420 except OSError:
3416 pass
3421 pass
3417 repo.dirstate.remove(f)
3422 repo.dirstate.remove(f)
3418
3423
3419 normal = None
3424 normal = None
3420 if node == parent:
3425 if node == parent:
3421 # We're reverting to our parent. If possible, we'd like status
3426 # We're reverting to our parent. If possible, we'd like status
3422 # to report the file as clean. We have to use normallookup for
3427 # to report the file as clean. We have to use normallookup for
3423 # merges to avoid losing information about merged/dirty files.
3428 # merges to avoid losing information about merged/dirty files.
3424 if p2 != nullid:
3429 if p2 != nullid:
3425 normal = repo.dirstate.normallookup
3430 normal = repo.dirstate.normallookup
3426 else:
3431 else:
3427 normal = repo.dirstate.normal
3432 normal = repo.dirstate.normal
3428 for f in revert[0]:
3433 for f in revert[0]:
3429 checkout(f)
3434 checkout(f)
3430 if normal:
3435 if normal:
3431 normal(f)
3436 normal(f)
3432
3437
3433 for f in add[0]:
3438 for f in add[0]:
3434 checkout(f)
3439 checkout(f)
3435 repo.dirstate.add(f)
3440 repo.dirstate.add(f)
3436
3441
3437 normal = repo.dirstate.normallookup
3442 normal = repo.dirstate.normallookup
3438 if node == parent and p2 == nullid:
3443 if node == parent and p2 == nullid:
3439 normal = repo.dirstate.normal
3444 normal = repo.dirstate.normal
3440 for f in undelete[0]:
3445 for f in undelete[0]:
3441 checkout(f)
3446 checkout(f)
3442 normal(f)
3447 normal(f)
3443
3448
3444 finally:
3449 finally:
3445 wlock.release()
3450 wlock.release()
3446
3451
3447 def rollback(ui, repo, **opts):
3452 def rollback(ui, repo, **opts):
3448 """roll back the last transaction (dangerous)
3453 """roll back the last transaction (dangerous)
3449
3454
3450 This command should be used with care. There is only one level of
3455 This command should be used with care. There is only one level of
3451 rollback, and there is no way to undo a rollback. It will also
3456 rollback, and there is no way to undo a rollback. It will also
3452 restore the dirstate at the time of the last transaction, losing
3457 restore the dirstate at the time of the last transaction, losing
3453 any dirstate changes since that time. This command does not alter
3458 any dirstate changes since that time. This command does not alter
3454 the working directory.
3459 the working directory.
3455
3460
3456 Transactions are used to encapsulate the effects of all commands
3461 Transactions are used to encapsulate the effects of all commands
3457 that create new changesets or propagate existing changesets into a
3462 that create new changesets or propagate existing changesets into a
3458 repository. For example, the following commands are transactional,
3463 repository. For example, the following commands are transactional,
3459 and their effects can be rolled back:
3464 and their effects can be rolled back:
3460
3465
3461 - commit
3466 - commit
3462 - import
3467 - import
3463 - pull
3468 - pull
3464 - push (with this repository as the destination)
3469 - push (with this repository as the destination)
3465 - unbundle
3470 - unbundle
3466
3471
3467 This command is not intended for use on public repositories. Once
3472 This command is not intended for use on public repositories. Once
3468 changes are visible for pull by other users, rolling a transaction
3473 changes are visible for pull by other users, rolling a transaction
3469 back locally is ineffective (someone else may already have pulled
3474 back locally is ineffective (someone else may already have pulled
3470 the changes). Furthermore, a race is possible with readers of the
3475 the changes). Furthermore, a race is possible with readers of the
3471 repository; for example an in-progress pull from the repository
3476 repository; for example an in-progress pull from the repository
3472 may fail if a rollback is performed.
3477 may fail if a rollback is performed.
3473
3478
3474 Returns 0 on success, 1 if no rollback data is available.
3479 Returns 0 on success, 1 if no rollback data is available.
3475 """
3480 """
3476 return repo.rollback(opts.get('dry_run'))
3481 return repo.rollback(opts.get('dry_run'))
3477
3482
3478 def root(ui, repo):
3483 def root(ui, repo):
3479 """print the root (top) of the current working directory
3484 """print the root (top) of the current working directory
3480
3485
3481 Print the root directory of the current repository.
3486 Print the root directory of the current repository.
3482
3487
3483 Returns 0 on success.
3488 Returns 0 on success.
3484 """
3489 """
3485 ui.write(repo.root + "\n")
3490 ui.write(repo.root + "\n")
3486
3491
3487 def serve(ui, repo, **opts):
3492 def serve(ui, repo, **opts):
3488 """start stand-alone webserver
3493 """start stand-alone webserver
3489
3494
3490 Start a local HTTP repository browser and pull server. You can use
3495 Start a local HTTP repository browser and pull server. You can use
3491 this for ad-hoc sharing and browsing of repositories. It is
3496 this for ad-hoc sharing and browsing of repositories. It is
3492 recommended to use a real web server to serve a repository for
3497 recommended to use a real web server to serve a repository for
3493 longer periods of time.
3498 longer periods of time.
3494
3499
3495 Please note that the server does not implement access control.
3500 Please note that the server does not implement access control.
3496 This means that, by default, anybody can read from the server and
3501 This means that, by default, anybody can read from the server and
3497 nobody can write to it by default. Set the ``web.allow_push``
3502 nobody can write to it by default. Set the ``web.allow_push``
3498 option to ``*`` to allow everybody to push to the server. You
3503 option to ``*`` to allow everybody to push to the server. You
3499 should use a real web server if you need to authenticate users.
3504 should use a real web server if you need to authenticate users.
3500
3505
3501 By default, the server logs accesses to stdout and errors to
3506 By default, the server logs accesses to stdout and errors to
3502 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3507 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3503 files.
3508 files.
3504
3509
3505 To have the server choose a free port number to listen on, specify
3510 To have the server choose a free port number to listen on, specify
3506 a port number of 0; in this case, the server will print the port
3511 a port number of 0; in this case, the server will print the port
3507 number it uses.
3512 number it uses.
3508
3513
3509 Returns 0 on success.
3514 Returns 0 on success.
3510 """
3515 """
3511
3516
3512 if opts["stdio"]:
3517 if opts["stdio"]:
3513 if repo is None:
3518 if repo is None:
3514 raise error.RepoError(_("There is no Mercurial repository here"
3519 raise error.RepoError(_("There is no Mercurial repository here"
3515 " (.hg not found)"))
3520 " (.hg not found)"))
3516 s = sshserver.sshserver(ui, repo)
3521 s = sshserver.sshserver(ui, repo)
3517 s.serve_forever()
3522 s.serve_forever()
3518
3523
3519 # this way we can check if something was given in the command-line
3524 # this way we can check if something was given in the command-line
3520 if opts.get('port'):
3525 if opts.get('port'):
3521 opts['port'] = util.getport(opts.get('port'))
3526 opts['port'] = util.getport(opts.get('port'))
3522
3527
3523 baseui = repo and repo.baseui or ui
3528 baseui = repo and repo.baseui or ui
3524 optlist = ("name templates style address port prefix ipv6"
3529 optlist = ("name templates style address port prefix ipv6"
3525 " accesslog errorlog certificate encoding")
3530 " accesslog errorlog certificate encoding")
3526 for o in optlist.split():
3531 for o in optlist.split():
3527 val = opts.get(o, '')
3532 val = opts.get(o, '')
3528 if val in (None, ''): # should check against default options instead
3533 if val in (None, ''): # should check against default options instead
3529 continue
3534 continue
3530 baseui.setconfig("web", o, val)
3535 baseui.setconfig("web", o, val)
3531 if repo and repo.ui != baseui:
3536 if repo and repo.ui != baseui:
3532 repo.ui.setconfig("web", o, val)
3537 repo.ui.setconfig("web", o, val)
3533
3538
3534 o = opts.get('web_conf') or opts.get('webdir_conf')
3539 o = opts.get('web_conf') or opts.get('webdir_conf')
3535 if not o:
3540 if not o:
3536 if not repo:
3541 if not repo:
3537 raise error.RepoError(_("There is no Mercurial repository"
3542 raise error.RepoError(_("There is no Mercurial repository"
3538 " here (.hg not found)"))
3543 " here (.hg not found)"))
3539 o = repo.root
3544 o = repo.root
3540
3545
3541 app = hgweb.hgweb(o, baseui=ui)
3546 app = hgweb.hgweb(o, baseui=ui)
3542
3547
3543 class service(object):
3548 class service(object):
3544 def init(self):
3549 def init(self):
3545 util.set_signal_handler()
3550 util.set_signal_handler()
3546 self.httpd = hgweb.server.create_server(ui, app)
3551 self.httpd = hgweb.server.create_server(ui, app)
3547
3552
3548 if opts['port'] and not ui.verbose:
3553 if opts['port'] and not ui.verbose:
3549 return
3554 return
3550
3555
3551 if self.httpd.prefix:
3556 if self.httpd.prefix:
3552 prefix = self.httpd.prefix.strip('/') + '/'
3557 prefix = self.httpd.prefix.strip('/') + '/'
3553 else:
3558 else:
3554 prefix = ''
3559 prefix = ''
3555
3560
3556 port = ':%d' % self.httpd.port
3561 port = ':%d' % self.httpd.port
3557 if port == ':80':
3562 if port == ':80':
3558 port = ''
3563 port = ''
3559
3564
3560 bindaddr = self.httpd.addr
3565 bindaddr = self.httpd.addr
3561 if bindaddr == '0.0.0.0':
3566 if bindaddr == '0.0.0.0':
3562 bindaddr = '*'
3567 bindaddr = '*'
3563 elif ':' in bindaddr: # IPv6
3568 elif ':' in bindaddr: # IPv6
3564 bindaddr = '[%s]' % bindaddr
3569 bindaddr = '[%s]' % bindaddr
3565
3570
3566 fqaddr = self.httpd.fqaddr
3571 fqaddr = self.httpd.fqaddr
3567 if ':' in fqaddr:
3572 if ':' in fqaddr:
3568 fqaddr = '[%s]' % fqaddr
3573 fqaddr = '[%s]' % fqaddr
3569 if opts['port']:
3574 if opts['port']:
3570 write = ui.status
3575 write = ui.status
3571 else:
3576 else:
3572 write = ui.write
3577 write = ui.write
3573 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3578 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3574 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3579 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3575
3580
3576 def run(self):
3581 def run(self):
3577 self.httpd.serve_forever()
3582 self.httpd.serve_forever()
3578
3583
3579 service = service()
3584 service = service()
3580
3585
3581 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3586 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3582
3587
3583 def status(ui, repo, *pats, **opts):
3588 def status(ui, repo, *pats, **opts):
3584 """show changed files in the working directory
3589 """show changed files in the working directory
3585
3590
3586 Show status of files in the repository. If names are given, only
3591 Show status of files in the repository. If names are given, only
3587 files that match are shown. Files that are clean or ignored or
3592 files that match are shown. Files that are clean or ignored or
3588 the source of a copy/move operation, are not listed unless
3593 the source of a copy/move operation, are not listed unless
3589 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3594 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3590 Unless options described with "show only ..." are given, the
3595 Unless options described with "show only ..." are given, the
3591 options -mardu are used.
3596 options -mardu are used.
3592
3597
3593 Option -q/--quiet hides untracked (unknown and ignored) files
3598 Option -q/--quiet hides untracked (unknown and ignored) files
3594 unless explicitly requested with -u/--unknown or -i/--ignored.
3599 unless explicitly requested with -u/--unknown or -i/--ignored.
3595
3600
3596 .. note::
3601 .. note::
3597 status may appear to disagree with diff if permissions have
3602 status may appear to disagree with diff if permissions have
3598 changed or a merge has occurred. The standard diff format does
3603 changed or a merge has occurred. The standard diff format does
3599 not report permission changes and diff only reports changes
3604 not report permission changes and diff only reports changes
3600 relative to one merge parent.
3605 relative to one merge parent.
3601
3606
3602 If one revision is given, it is used as the base revision.
3607 If one revision is given, it is used as the base revision.
3603 If two revisions are given, the differences between them are
3608 If two revisions are given, the differences between them are
3604 shown. The --change option can also be used as a shortcut to list
3609 shown. The --change option can also be used as a shortcut to list
3605 the changed files of a revision from its first parent.
3610 the changed files of a revision from its first parent.
3606
3611
3607 The codes used to show the status of files are::
3612 The codes used to show the status of files are::
3608
3613
3609 M = modified
3614 M = modified
3610 A = added
3615 A = added
3611 R = removed
3616 R = removed
3612 C = clean
3617 C = clean
3613 ! = missing (deleted by non-hg command, but still tracked)
3618 ! = missing (deleted by non-hg command, but still tracked)
3614 ? = not tracked
3619 ? = not tracked
3615 I = ignored
3620 I = ignored
3616 = origin of the previous file listed as A (added)
3621 = origin of the previous file listed as A (added)
3617
3622
3618 Returns 0 on success.
3623 Returns 0 on success.
3619 """
3624 """
3620
3625
3621 revs = opts.get('rev')
3626 revs = opts.get('rev')
3622 change = opts.get('change')
3627 change = opts.get('change')
3623
3628
3624 if revs and change:
3629 if revs and change:
3625 msg = _('cannot specify --rev and --change at the same time')
3630 msg = _('cannot specify --rev and --change at the same time')
3626 raise util.Abort(msg)
3631 raise util.Abort(msg)
3627 elif change:
3632 elif change:
3628 node2 = repo.lookup(change)
3633 node2 = repo.lookup(change)
3629 node1 = repo[node2].parents()[0].node()
3634 node1 = repo[node2].parents()[0].node()
3630 else:
3635 else:
3631 node1, node2 = cmdutil.revpair(repo, revs)
3636 node1, node2 = cmdutil.revpair(repo, revs)
3632
3637
3633 cwd = (pats and repo.getcwd()) or ''
3638 cwd = (pats and repo.getcwd()) or ''
3634 end = opts.get('print0') and '\0' or '\n'
3639 end = opts.get('print0') and '\0' or '\n'
3635 copy = {}
3640 copy = {}
3636 states = 'modified added removed deleted unknown ignored clean'.split()
3641 states = 'modified added removed deleted unknown ignored clean'.split()
3637 show = [k for k in states if opts.get(k)]
3642 show = [k for k in states if opts.get(k)]
3638 if opts.get('all'):
3643 if opts.get('all'):
3639 show += ui.quiet and (states[:4] + ['clean']) or states
3644 show += ui.quiet and (states[:4] + ['clean']) or states
3640 if not show:
3645 if not show:
3641 show = ui.quiet and states[:4] or states[:5]
3646 show = ui.quiet and states[:4] or states[:5]
3642
3647
3643 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3648 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3644 'ignored' in show, 'clean' in show, 'unknown' in show,
3649 'ignored' in show, 'clean' in show, 'unknown' in show,
3645 opts.get('subrepos'))
3650 opts.get('subrepos'))
3646 changestates = zip(states, 'MAR!?IC', stat)
3651 changestates = zip(states, 'MAR!?IC', stat)
3647
3652
3648 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3653 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3649 ctxn = repo[nullid]
3654 ctxn = repo[nullid]
3650 ctx1 = repo[node1]
3655 ctx1 = repo[node1]
3651 ctx2 = repo[node2]
3656 ctx2 = repo[node2]
3652 added = stat[1]
3657 added = stat[1]
3653 if node2 is None:
3658 if node2 is None:
3654 added = stat[0] + stat[1] # merged?
3659 added = stat[0] + stat[1] # merged?
3655
3660
3656 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3661 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3657 if k in added:
3662 if k in added:
3658 copy[k] = v
3663 copy[k] = v
3659 elif v in added:
3664 elif v in added:
3660 copy[v] = k
3665 copy[v] = k
3661
3666
3662 for state, char, files in changestates:
3667 for state, char, files in changestates:
3663 if state in show:
3668 if state in show:
3664 format = "%s %%s%s" % (char, end)
3669 format = "%s %%s%s" % (char, end)
3665 if opts.get('no_status'):
3670 if opts.get('no_status'):
3666 format = "%%s%s" % end
3671 format = "%%s%s" % end
3667
3672
3668 for f in files:
3673 for f in files:
3669 ui.write(format % repo.pathto(f, cwd),
3674 ui.write(format % repo.pathto(f, cwd),
3670 label='status.' + state)
3675 label='status.' + state)
3671 if f in copy:
3676 if f in copy:
3672 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3677 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3673 label='status.copied')
3678 label='status.copied')
3674
3679
3675 def summary(ui, repo, **opts):
3680 def summary(ui, repo, **opts):
3676 """summarize working directory state
3681 """summarize working directory state
3677
3682
3678 This generates a brief summary of the working directory state,
3683 This generates a brief summary of the working directory state,
3679 including parents, branch, commit status, and available updates.
3684 including parents, branch, commit status, and available updates.
3680
3685
3681 With the --remote option, this will check the default paths for
3686 With the --remote option, this will check the default paths for
3682 incoming and outgoing changes. This can be time-consuming.
3687 incoming and outgoing changes. This can be time-consuming.
3683
3688
3684 Returns 0 on success.
3689 Returns 0 on success.
3685 """
3690 """
3686
3691
3687 ctx = repo[None]
3692 ctx = repo[None]
3688 parents = ctx.parents()
3693 parents = ctx.parents()
3689 pnode = parents[0].node()
3694 pnode = parents[0].node()
3690
3695
3691 for p in parents:
3696 for p in parents:
3692 # label with log.changeset (instead of log.parent) since this
3697 # label with log.changeset (instead of log.parent) since this
3693 # shows a working directory parent *changeset*:
3698 # shows a working directory parent *changeset*:
3694 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3699 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3695 label='log.changeset')
3700 label='log.changeset')
3696 ui.write(' '.join(p.tags()), label='log.tag')
3701 ui.write(' '.join(p.tags()), label='log.tag')
3697 if p.rev() == -1:
3702 if p.rev() == -1:
3698 if not len(repo):
3703 if not len(repo):
3699 ui.write(_(' (empty repository)'))
3704 ui.write(_(' (empty repository)'))
3700 else:
3705 else:
3701 ui.write(_(' (no revision checked out)'))
3706 ui.write(_(' (no revision checked out)'))
3702 ui.write('\n')
3707 ui.write('\n')
3703 if p.description():
3708 if p.description():
3704 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3709 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3705 label='log.summary')
3710 label='log.summary')
3706
3711
3707 branch = ctx.branch()
3712 branch = ctx.branch()
3708 bheads = repo.branchheads(branch)
3713 bheads = repo.branchheads(branch)
3709 m = _('branch: %s\n') % branch
3714 m = _('branch: %s\n') % branch
3710 if branch != 'default':
3715 if branch != 'default':
3711 ui.write(m, label='log.branch')
3716 ui.write(m, label='log.branch')
3712 else:
3717 else:
3713 ui.status(m, label='log.branch')
3718 ui.status(m, label='log.branch')
3714
3719
3715 st = list(repo.status(unknown=True))[:6]
3720 st = list(repo.status(unknown=True))[:6]
3716
3721
3717 c = repo.dirstate.copies()
3722 c = repo.dirstate.copies()
3718 copied, renamed = [], []
3723 copied, renamed = [], []
3719 for d, s in c.iteritems():
3724 for d, s in c.iteritems():
3720 if s in st[2]:
3725 if s in st[2]:
3721 st[2].remove(s)
3726 st[2].remove(s)
3722 renamed.append(d)
3727 renamed.append(d)
3723 else:
3728 else:
3724 copied.append(d)
3729 copied.append(d)
3725 if d in st[1]:
3730 if d in st[1]:
3726 st[1].remove(d)
3731 st[1].remove(d)
3727 st.insert(3, renamed)
3732 st.insert(3, renamed)
3728 st.insert(4, copied)
3733 st.insert(4, copied)
3729
3734
3730 ms = mergemod.mergestate(repo)
3735 ms = mergemod.mergestate(repo)
3731 st.append([f for f in ms if ms[f] == 'u'])
3736 st.append([f for f in ms if ms[f] == 'u'])
3732
3737
3733 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3738 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3734 st.append(subs)
3739 st.append(subs)
3735
3740
3736 labels = [ui.label(_('%d modified'), 'status.modified'),
3741 labels = [ui.label(_('%d modified'), 'status.modified'),
3737 ui.label(_('%d added'), 'status.added'),
3742 ui.label(_('%d added'), 'status.added'),
3738 ui.label(_('%d removed'), 'status.removed'),
3743 ui.label(_('%d removed'), 'status.removed'),
3739 ui.label(_('%d renamed'), 'status.copied'),
3744 ui.label(_('%d renamed'), 'status.copied'),
3740 ui.label(_('%d copied'), 'status.copied'),
3745 ui.label(_('%d copied'), 'status.copied'),
3741 ui.label(_('%d deleted'), 'status.deleted'),
3746 ui.label(_('%d deleted'), 'status.deleted'),
3742 ui.label(_('%d unknown'), 'status.unknown'),
3747 ui.label(_('%d unknown'), 'status.unknown'),
3743 ui.label(_('%d ignored'), 'status.ignored'),
3748 ui.label(_('%d ignored'), 'status.ignored'),
3744 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3749 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3745 ui.label(_('%d subrepos'), 'status.modified')]
3750 ui.label(_('%d subrepos'), 'status.modified')]
3746 t = []
3751 t = []
3747 for s, l in zip(st, labels):
3752 for s, l in zip(st, labels):
3748 if s:
3753 if s:
3749 t.append(l % len(s))
3754 t.append(l % len(s))
3750
3755
3751 t = ', '.join(t)
3756 t = ', '.join(t)
3752 cleanworkdir = False
3757 cleanworkdir = False
3753
3758
3754 if len(parents) > 1:
3759 if len(parents) > 1:
3755 t += _(' (merge)')
3760 t += _(' (merge)')
3756 elif branch != parents[0].branch():
3761 elif branch != parents[0].branch():
3757 t += _(' (new branch)')
3762 t += _(' (new branch)')
3758 elif (parents[0].extra().get('close') and
3763 elif (parents[0].extra().get('close') and
3759 pnode in repo.branchheads(branch, closed=True)):
3764 pnode in repo.branchheads(branch, closed=True)):
3760 t += _(' (head closed)')
3765 t += _(' (head closed)')
3761 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3766 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3762 t += _(' (clean)')
3767 t += _(' (clean)')
3763 cleanworkdir = True
3768 cleanworkdir = True
3764 elif pnode not in bheads:
3769 elif pnode not in bheads:
3765 t += _(' (new branch head)')
3770 t += _(' (new branch head)')
3766
3771
3767 if cleanworkdir:
3772 if cleanworkdir:
3768 ui.status(_('commit: %s\n') % t.strip())
3773 ui.status(_('commit: %s\n') % t.strip())
3769 else:
3774 else:
3770 ui.write(_('commit: %s\n') % t.strip())
3775 ui.write(_('commit: %s\n') % t.strip())
3771
3776
3772 # all ancestors of branch heads - all ancestors of parent = new csets
3777 # all ancestors of branch heads - all ancestors of parent = new csets
3773 new = [0] * len(repo)
3778 new = [0] * len(repo)
3774 cl = repo.changelog
3779 cl = repo.changelog
3775 for a in [cl.rev(n) for n in bheads]:
3780 for a in [cl.rev(n) for n in bheads]:
3776 new[a] = 1
3781 new[a] = 1
3777 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3782 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3778 new[a] = 1
3783 new[a] = 1
3779 for a in [p.rev() for p in parents]:
3784 for a in [p.rev() for p in parents]:
3780 if a >= 0:
3785 if a >= 0:
3781 new[a] = 0
3786 new[a] = 0
3782 for a in cl.ancestors(*[p.rev() for p in parents]):
3787 for a in cl.ancestors(*[p.rev() for p in parents]):
3783 new[a] = 0
3788 new[a] = 0
3784 new = sum(new)
3789 new = sum(new)
3785
3790
3786 if new == 0:
3791 if new == 0:
3787 ui.status(_('update: (current)\n'))
3792 ui.status(_('update: (current)\n'))
3788 elif pnode not in bheads:
3793 elif pnode not in bheads:
3789 ui.write(_('update: %d new changesets (update)\n') % new)
3794 ui.write(_('update: %d new changesets (update)\n') % new)
3790 else:
3795 else:
3791 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3796 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3792 (new, len(bheads)))
3797 (new, len(bheads)))
3793
3798
3794 if opts.get('remote'):
3799 if opts.get('remote'):
3795 t = []
3800 t = []
3796 source, branches = hg.parseurl(ui.expandpath('default'))
3801 source, branches = hg.parseurl(ui.expandpath('default'))
3797 other = hg.repository(hg.remoteui(repo, {}), source)
3802 other = hg.repository(hg.remoteui(repo, {}), source)
3798 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3803 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3799 ui.debug('comparing with %s\n' % url.hidepassword(source))
3804 ui.debug('comparing with %s\n' % url.hidepassword(source))
3800 repo.ui.pushbuffer()
3805 repo.ui.pushbuffer()
3801 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3806 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3802 repo.ui.popbuffer()
3807 repo.ui.popbuffer()
3803 if incoming:
3808 if incoming:
3804 t.append(_('1 or more incoming'))
3809 t.append(_('1 or more incoming'))
3805
3810
3806 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3811 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3807 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3812 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3808 other = hg.repository(hg.remoteui(repo, {}), dest)
3813 other = hg.repository(hg.remoteui(repo, {}), dest)
3809 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3814 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3810 repo.ui.pushbuffer()
3815 repo.ui.pushbuffer()
3811 o = discovery.findoutgoing(repo, other)
3816 o = discovery.findoutgoing(repo, other)
3812 repo.ui.popbuffer()
3817 repo.ui.popbuffer()
3813 o = repo.changelog.nodesbetween(o, None)[0]
3818 o = repo.changelog.nodesbetween(o, None)[0]
3814 if o:
3819 if o:
3815 t.append(_('%d outgoing') % len(o))
3820 t.append(_('%d outgoing') % len(o))
3816
3821
3817 if t:
3822 if t:
3818 ui.write(_('remote: %s\n') % (', '.join(t)))
3823 ui.write(_('remote: %s\n') % (', '.join(t)))
3819 else:
3824 else:
3820 ui.status(_('remote: (synced)\n'))
3825 ui.status(_('remote: (synced)\n'))
3821
3826
3822 def tag(ui, repo, name1, *names, **opts):
3827 def tag(ui, repo, name1, *names, **opts):
3823 """add one or more tags for the current or given revision
3828 """add one or more tags for the current or given revision
3824
3829
3825 Name a particular revision using <name>.
3830 Name a particular revision using <name>.
3826
3831
3827 Tags are used to name particular revisions of the repository and are
3832 Tags are used to name particular revisions of the repository and are
3828 very useful to compare different revisions, to go back to significant
3833 very useful to compare different revisions, to go back to significant
3829 earlier versions or to mark branch points as releases, etc. Changing
3834 earlier versions or to mark branch points as releases, etc. Changing
3830 an existing tag is normally disallowed; use -f/--force to override.
3835 an existing tag is normally disallowed; use -f/--force to override.
3831
3836
3832 If no revision is given, the parent of the working directory is
3837 If no revision is given, the parent of the working directory is
3833 used, or tip if no revision is checked out.
3838 used, or tip if no revision is checked out.
3834
3839
3835 To facilitate version control, distribution, and merging of tags,
3840 To facilitate version control, distribution, and merging of tags,
3836 they are stored as a file named ".hgtags" which is managed similarly
3841 they are stored as a file named ".hgtags" which is managed similarly
3837 to other project files and can be hand-edited if necessary. This
3842 to other project files and can be hand-edited if necessary. This
3838 also means that tagging creates a new commit. The file
3843 also means that tagging creates a new commit. The file
3839 ".hg/localtags" is used for local tags (not shared among
3844 ".hg/localtags" is used for local tags (not shared among
3840 repositories).
3845 repositories).
3841
3846
3842 Tag commits are usually made at the head of a branch. If the parent
3847 Tag commits are usually made at the head of a branch. If the parent
3843 of the working directory is not a branch head, :hg:`tag` aborts; use
3848 of the working directory is not a branch head, :hg:`tag` aborts; use
3844 -f/--force to force the tag commit to be based on a non-head
3849 -f/--force to force the tag commit to be based on a non-head
3845 changeset.
3850 changeset.
3846
3851
3847 See :hg:`help dates` for a list of formats valid for -d/--date.
3852 See :hg:`help dates` for a list of formats valid for -d/--date.
3848
3853
3849 Since tag names have priority over branch names during revision
3854 Since tag names have priority over branch names during revision
3850 lookup, using an existing branch name as a tag name is discouraged.
3855 lookup, using an existing branch name as a tag name is discouraged.
3851
3856
3852 Returns 0 on success.
3857 Returns 0 on success.
3853 """
3858 """
3854
3859
3855 rev_ = "."
3860 rev_ = "."
3856 names = [t.strip() for t in (name1,) + names]
3861 names = [t.strip() for t in (name1,) + names]
3857 if len(names) != len(set(names)):
3862 if len(names) != len(set(names)):
3858 raise util.Abort(_('tag names must be unique'))
3863 raise util.Abort(_('tag names must be unique'))
3859 for n in names:
3864 for n in names:
3860 if n in ['tip', '.', 'null']:
3865 if n in ['tip', '.', 'null']:
3861 raise util.Abort(_('the name \'%s\' is reserved') % n)
3866 raise util.Abort(_('the name \'%s\' is reserved') % n)
3862 if not n:
3867 if not n:
3863 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
3868 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
3864 if opts.get('rev') and opts.get('remove'):
3869 if opts.get('rev') and opts.get('remove'):
3865 raise util.Abort(_("--rev and --remove are incompatible"))
3870 raise util.Abort(_("--rev and --remove are incompatible"))
3866 if opts.get('rev'):
3871 if opts.get('rev'):
3867 rev_ = opts['rev']
3872 rev_ = opts['rev']
3868 message = opts.get('message')
3873 message = opts.get('message')
3869 if opts.get('remove'):
3874 if opts.get('remove'):
3870 expectedtype = opts.get('local') and 'local' or 'global'
3875 expectedtype = opts.get('local') and 'local' or 'global'
3871 for n in names:
3876 for n in names:
3872 if not repo.tagtype(n):
3877 if not repo.tagtype(n):
3873 raise util.Abort(_('tag \'%s\' does not exist') % n)
3878 raise util.Abort(_('tag \'%s\' does not exist') % n)
3874 if repo.tagtype(n) != expectedtype:
3879 if repo.tagtype(n) != expectedtype:
3875 if expectedtype == 'global':
3880 if expectedtype == 'global':
3876 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3881 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3877 else:
3882 else:
3878 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3883 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3879 rev_ = nullid
3884 rev_ = nullid
3880 if not message:
3885 if not message:
3881 # we don't translate commit messages
3886 # we don't translate commit messages
3882 message = 'Removed tag %s' % ', '.join(names)
3887 message = 'Removed tag %s' % ', '.join(names)
3883 elif not opts.get('force'):
3888 elif not opts.get('force'):
3884 for n in names:
3889 for n in names:
3885 if n in repo.tags():
3890 if n in repo.tags():
3886 raise util.Abort(_('tag \'%s\' already exists '
3891 raise util.Abort(_('tag \'%s\' already exists '
3887 '(use -f to force)') % n)
3892 '(use -f to force)') % n)
3888 if not opts.get('local'):
3893 if not opts.get('local'):
3889 p1, p2 = repo.dirstate.parents()
3894 p1, p2 = repo.dirstate.parents()
3890 if p2 != nullid:
3895 if p2 != nullid:
3891 raise util.Abort(_('uncommitted merge'))
3896 raise util.Abort(_('uncommitted merge'))
3892 bheads = repo.branchheads()
3897 bheads = repo.branchheads()
3893 if not opts.get('force') and bheads and p1 not in bheads:
3898 if not opts.get('force') and bheads and p1 not in bheads:
3894 raise util.Abort(_('not at a branch head (use -f to force)'))
3899 raise util.Abort(_('not at a branch head (use -f to force)'))
3895 r = cmdutil.revsingle(repo, rev_).node()
3900 r = cmdutil.revsingle(repo, rev_).node()
3896
3901
3897 if not message:
3902 if not message:
3898 # we don't translate commit messages
3903 # we don't translate commit messages
3899 message = ('Added tag %s for changeset %s' %
3904 message = ('Added tag %s for changeset %s' %
3900 (', '.join(names), short(r)))
3905 (', '.join(names), short(r)))
3901
3906
3902 date = opts.get('date')
3907 date = opts.get('date')
3903 if date:
3908 if date:
3904 date = util.parsedate(date)
3909 date = util.parsedate(date)
3905
3910
3906 if opts.get('edit'):
3911 if opts.get('edit'):
3907 message = ui.edit(message, ui.username())
3912 message = ui.edit(message, ui.username())
3908
3913
3909 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3914 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3910
3915
3911 def tags(ui, repo):
3916 def tags(ui, repo):
3912 """list repository tags
3917 """list repository tags
3913
3918
3914 This lists both regular and local tags. When the -v/--verbose
3919 This lists both regular and local tags. When the -v/--verbose
3915 switch is used, a third column "local" is printed for local tags.
3920 switch is used, a third column "local" is printed for local tags.
3916
3921
3917 Returns 0 on success.
3922 Returns 0 on success.
3918 """
3923 """
3919
3924
3920 hexfunc = ui.debugflag and hex or short
3925 hexfunc = ui.debugflag and hex or short
3921 tagtype = ""
3926 tagtype = ""
3922
3927
3923 for t, n in reversed(repo.tagslist()):
3928 for t, n in reversed(repo.tagslist()):
3924 if ui.quiet:
3929 if ui.quiet:
3925 ui.write("%s\n" % t)
3930 ui.write("%s\n" % t)
3926 continue
3931 continue
3927
3932
3928 try:
3933 try:
3929 hn = hexfunc(n)
3934 hn = hexfunc(n)
3930 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3935 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3931 except error.LookupError:
3936 except error.LookupError:
3932 r = " ?:%s" % hn
3937 r = " ?:%s" % hn
3933 else:
3938 else:
3934 spaces = " " * (30 - encoding.colwidth(t))
3939 spaces = " " * (30 - encoding.colwidth(t))
3935 if ui.verbose:
3940 if ui.verbose:
3936 if repo.tagtype(t) == 'local':
3941 if repo.tagtype(t) == 'local':
3937 tagtype = " local"
3942 tagtype = " local"
3938 else:
3943 else:
3939 tagtype = ""
3944 tagtype = ""
3940 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3945 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3941
3946
3942 def tip(ui, repo, **opts):
3947 def tip(ui, repo, **opts):
3943 """show the tip revision
3948 """show the tip revision
3944
3949
3945 The tip revision (usually just called the tip) is the changeset
3950 The tip revision (usually just called the tip) is the changeset
3946 most recently added to the repository (and therefore the most
3951 most recently added to the repository (and therefore the most
3947 recently changed head).
3952 recently changed head).
3948
3953
3949 If you have just made a commit, that commit will be the tip. If
3954 If you have just made a commit, that commit will be the tip. If
3950 you have just pulled changes from another repository, the tip of
3955 you have just pulled changes from another repository, the tip of
3951 that repository becomes the current tip. The "tip" tag is special
3956 that repository becomes the current tip. The "tip" tag is special
3952 and cannot be renamed or assigned to a different changeset.
3957 and cannot be renamed or assigned to a different changeset.
3953
3958
3954 Returns 0 on success.
3959 Returns 0 on success.
3955 """
3960 """
3956 displayer = cmdutil.show_changeset(ui, repo, opts)
3961 displayer = cmdutil.show_changeset(ui, repo, opts)
3957 displayer.show(repo[len(repo) - 1])
3962 displayer.show(repo[len(repo) - 1])
3958 displayer.close()
3963 displayer.close()
3959
3964
3960 def unbundle(ui, repo, fname1, *fnames, **opts):
3965 def unbundle(ui, repo, fname1, *fnames, **opts):
3961 """apply one or more changegroup files
3966 """apply one or more changegroup files
3962
3967
3963 Apply one or more compressed changegroup files generated by the
3968 Apply one or more compressed changegroup files generated by the
3964 bundle command.
3969 bundle command.
3965
3970
3966 Returns 0 on success, 1 if an update has unresolved files.
3971 Returns 0 on success, 1 if an update has unresolved files.
3967 """
3972 """
3968 fnames = (fname1,) + fnames
3973 fnames = (fname1,) + fnames
3969
3974
3970 lock = repo.lock()
3975 lock = repo.lock()
3971 try:
3976 try:
3972 for fname in fnames:
3977 for fname in fnames:
3973 f = url.open(ui, fname)
3978 f = url.open(ui, fname)
3974 gen = changegroup.readbundle(f, fname)
3979 gen = changegroup.readbundle(f, fname)
3975 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3980 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3976 lock=lock)
3981 lock=lock)
3977 finally:
3982 finally:
3978 lock.release()
3983 lock.release()
3979
3984
3980 return postincoming(ui, repo, modheads, opts.get('update'), None)
3985 return postincoming(ui, repo, modheads, opts.get('update'), None)
3981
3986
3982 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3987 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3983 """update working directory (or switch revisions)
3988 """update working directory (or switch revisions)
3984
3989
3985 Update the repository's working directory to the specified
3990 Update the repository's working directory to the specified
3986 changeset. If no changeset is specified, update to the tip of the
3991 changeset. If no changeset is specified, update to the tip of the
3987 current named branch.
3992 current named branch.
3988
3993
3989 If the changeset is not a descendant of the working directory's
3994 If the changeset is not a descendant of the working directory's
3990 parent, the update is aborted. With the -c/--check option, the
3995 parent, the update is aborted. With the -c/--check option, the
3991 working directory is checked for uncommitted changes; if none are
3996 working directory is checked for uncommitted changes; if none are
3992 found, the working directory is updated to the specified
3997 found, the working directory is updated to the specified
3993 changeset.
3998 changeset.
3994
3999
3995 The following rules apply when the working directory contains
4000 The following rules apply when the working directory contains
3996 uncommitted changes:
4001 uncommitted changes:
3997
4002
3998 1. If neither -c/--check nor -C/--clean is specified, and if
4003 1. If neither -c/--check nor -C/--clean is specified, and if
3999 the requested changeset is an ancestor or descendant of
4004 the requested changeset is an ancestor or descendant of
4000 the working directory's parent, the uncommitted changes
4005 the working directory's parent, the uncommitted changes
4001 are merged into the requested changeset and the merged
4006 are merged into the requested changeset and the merged
4002 result is left uncommitted. If the requested changeset is
4007 result is left uncommitted. If the requested changeset is
4003 not an ancestor or descendant (that is, it is on another
4008 not an ancestor or descendant (that is, it is on another
4004 branch), the update is aborted and the uncommitted changes
4009 branch), the update is aborted and the uncommitted changes
4005 are preserved.
4010 are preserved.
4006
4011
4007 2. With the -c/--check option, the update is aborted and the
4012 2. With the -c/--check option, the update is aborted and the
4008 uncommitted changes are preserved.
4013 uncommitted changes are preserved.
4009
4014
4010 3. With the -C/--clean option, uncommitted changes are discarded and
4015 3. With the -C/--clean option, uncommitted changes are discarded and
4011 the working directory is updated to the requested changeset.
4016 the working directory is updated to the requested changeset.
4012
4017
4013 Use null as the changeset to remove the working directory (like
4018 Use null as the changeset to remove the working directory (like
4014 :hg:`clone -U`).
4019 :hg:`clone -U`).
4015
4020
4016 If you want to update just one file to an older changeset, use
4021 If you want to update just one file to an older changeset, use
4017 :hg:`revert`.
4022 :hg:`revert`.
4018
4023
4019 See :hg:`help dates` for a list of formats valid for -d/--date.
4024 See :hg:`help dates` for a list of formats valid for -d/--date.
4020
4025
4021 Returns 0 on success, 1 if there are unresolved files.
4026 Returns 0 on success, 1 if there are unresolved files.
4022 """
4027 """
4023 if rev and node:
4028 if rev and node:
4024 raise util.Abort(_("please specify just one revision"))
4029 raise util.Abort(_("please specify just one revision"))
4025
4030
4026 if not rev:
4031 if not rev:
4027 rev = node
4032 rev = node
4028
4033
4029 rev = cmdutil.revsingle(repo, rev, rev).rev()
4034 rev = cmdutil.revsingle(repo, rev, rev).rev()
4030
4035
4031 if check and clean:
4036 if check and clean:
4032 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4037 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4033
4038
4034 if check:
4039 if check:
4035 # we could use dirty() but we can ignore merge and branch trivia
4040 # we could use dirty() but we can ignore merge and branch trivia
4036 c = repo[None]
4041 c = repo[None]
4037 if c.modified() or c.added() or c.removed():
4042 if c.modified() or c.added() or c.removed():
4038 raise util.Abort(_("uncommitted local changes"))
4043 raise util.Abort(_("uncommitted local changes"))
4039
4044
4040 if date:
4045 if date:
4041 if rev:
4046 if rev:
4042 raise util.Abort(_("you can't specify a revision and a date"))
4047 raise util.Abort(_("you can't specify a revision and a date"))
4043 rev = cmdutil.finddate(ui, repo, date)
4048 rev = cmdutil.finddate(ui, repo, date)
4044
4049
4045 if clean or check:
4050 if clean or check:
4046 ret = hg.clean(repo, rev)
4051 ret = hg.clean(repo, rev)
4047 else:
4052 else:
4048 ret = hg.update(repo, rev)
4053 ret = hg.update(repo, rev)
4049
4054
4050 if repo.ui.configbool('bookmarks', 'track.current'):
4055 if repo.ui.configbool('bookmarks', 'track.current'):
4051 bookmarks.setcurrent(repo, rev)
4056 bookmarks.setcurrent(repo, rev)
4052
4057
4053 return ret
4058 return ret
4054
4059
4055 def verify(ui, repo):
4060 def verify(ui, repo):
4056 """verify the integrity of the repository
4061 """verify the integrity of the repository
4057
4062
4058 Verify the integrity of the current repository.
4063 Verify the integrity of the current repository.
4059
4064
4060 This will perform an extensive check of the repository's
4065 This will perform an extensive check of the repository's
4061 integrity, validating the hashes and checksums of each entry in
4066 integrity, validating the hashes and checksums of each entry in
4062 the changelog, manifest, and tracked files, as well as the
4067 the changelog, manifest, and tracked files, as well as the
4063 integrity of their crosslinks and indices.
4068 integrity of their crosslinks and indices.
4064
4069
4065 Returns 0 on success, 1 if errors are encountered.
4070 Returns 0 on success, 1 if errors are encountered.
4066 """
4071 """
4067 return hg.verify(repo)
4072 return hg.verify(repo)
4068
4073
4069 def version_(ui):
4074 def version_(ui):
4070 """output version and copyright information"""
4075 """output version and copyright information"""
4071 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4076 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4072 % util.version())
4077 % util.version())
4073 ui.status(_(
4078 ui.status(_(
4074 "(see http://mercurial.selenic.com for more information)\n"
4079 "(see http://mercurial.selenic.com for more information)\n"
4075 "\nCopyright (C) 2005-2010 Matt Mackall and others\n"
4080 "\nCopyright (C) 2005-2010 Matt Mackall and others\n"
4076 "This is free software; see the source for copying conditions. "
4081 "This is free software; see the source for copying conditions. "
4077 "There is NO\nwarranty; "
4082 "There is NO\nwarranty; "
4078 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4083 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4079 ))
4084 ))
4080
4085
4081 # Command options and aliases are listed here, alphabetically
4086 # Command options and aliases are listed here, alphabetically
4082
4087
4083 globalopts = [
4088 globalopts = [
4084 ('R', 'repository', '',
4089 ('R', 'repository', '',
4085 _('repository root directory or name of overlay bundle file'),
4090 _('repository root directory or name of overlay bundle file'),
4086 _('REPO')),
4091 _('REPO')),
4087 ('', 'cwd', '',
4092 ('', 'cwd', '',
4088 _('change working directory'), _('DIR')),
4093 _('change working directory'), _('DIR')),
4089 ('y', 'noninteractive', None,
4094 ('y', 'noninteractive', None,
4090 _('do not prompt, assume \'yes\' for any required answers')),
4095 _('do not prompt, assume \'yes\' for any required answers')),
4091 ('q', 'quiet', None, _('suppress output')),
4096 ('q', 'quiet', None, _('suppress output')),
4092 ('v', 'verbose', None, _('enable additional output')),
4097 ('v', 'verbose', None, _('enable additional output')),
4093 ('', 'config', [],
4098 ('', 'config', [],
4094 _('set/override config option (use \'section.name=value\')'),
4099 _('set/override config option (use \'section.name=value\')'),
4095 _('CONFIG')),
4100 _('CONFIG')),
4096 ('', 'debug', None, _('enable debugging output')),
4101 ('', 'debug', None, _('enable debugging output')),
4097 ('', 'debugger', None, _('start debugger')),
4102 ('', 'debugger', None, _('start debugger')),
4098 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4103 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4099 _('ENCODE')),
4104 _('ENCODE')),
4100 ('', 'encodingmode', encoding.encodingmode,
4105 ('', 'encodingmode', encoding.encodingmode,
4101 _('set the charset encoding mode'), _('MODE')),
4106 _('set the charset encoding mode'), _('MODE')),
4102 ('', 'traceback', None, _('always print a traceback on exception')),
4107 ('', 'traceback', None, _('always print a traceback on exception')),
4103 ('', 'time', None, _('time how long the command takes')),
4108 ('', 'time', None, _('time how long the command takes')),
4104 ('', 'profile', None, _('print command execution profile')),
4109 ('', 'profile', None, _('print command execution profile')),
4105 ('', 'version', None, _('output version information and exit')),
4110 ('', 'version', None, _('output version information and exit')),
4106 ('h', 'help', None, _('display help and exit')),
4111 ('h', 'help', None, _('display help and exit')),
4107 ]
4112 ]
4108
4113
4109 dryrunopts = [('n', 'dry-run', None,
4114 dryrunopts = [('n', 'dry-run', None,
4110 _('do not perform actions, just print output'))]
4115 _('do not perform actions, just print output'))]
4111
4116
4112 remoteopts = [
4117 remoteopts = [
4113 ('e', 'ssh', '',
4118 ('e', 'ssh', '',
4114 _('specify ssh command to use'), _('CMD')),
4119 _('specify ssh command to use'), _('CMD')),
4115 ('', 'remotecmd', '',
4120 ('', 'remotecmd', '',
4116 _('specify hg command to run on the remote side'), _('CMD')),
4121 _('specify hg command to run on the remote side'), _('CMD')),
4117 ('', 'insecure', None,
4122 ('', 'insecure', None,
4118 _('do not verify server certificate (ignoring web.cacerts config)')),
4123 _('do not verify server certificate (ignoring web.cacerts config)')),
4119 ]
4124 ]
4120
4125
4121 walkopts = [
4126 walkopts = [
4122 ('I', 'include', [],
4127 ('I', 'include', [],
4123 _('include names matching the given patterns'), _('PATTERN')),
4128 _('include names matching the given patterns'), _('PATTERN')),
4124 ('X', 'exclude', [],
4129 ('X', 'exclude', [],
4125 _('exclude names matching the given patterns'), _('PATTERN')),
4130 _('exclude names matching the given patterns'), _('PATTERN')),
4126 ]
4131 ]
4127
4132
4128 commitopts = [
4133 commitopts = [
4129 ('m', 'message', '',
4134 ('m', 'message', '',
4130 _('use text as commit message'), _('TEXT')),
4135 _('use text as commit message'), _('TEXT')),
4131 ('l', 'logfile', '',
4136 ('l', 'logfile', '',
4132 _('read commit message from file'), _('FILE')),
4137 _('read commit message from file'), _('FILE')),
4133 ]
4138 ]
4134
4139
4135 commitopts2 = [
4140 commitopts2 = [
4136 ('d', 'date', '',
4141 ('d', 'date', '',
4137 _('record datecode as commit date'), _('DATE')),
4142 _('record datecode as commit date'), _('DATE')),
4138 ('u', 'user', '',
4143 ('u', 'user', '',
4139 _('record the specified user as committer'), _('USER')),
4144 _('record the specified user as committer'), _('USER')),
4140 ]
4145 ]
4141
4146
4142 templateopts = [
4147 templateopts = [
4143 ('', 'style', '',
4148 ('', 'style', '',
4144 _('display using template map file'), _('STYLE')),
4149 _('display using template map file'), _('STYLE')),
4145 ('', 'template', '',
4150 ('', 'template', '',
4146 _('display with template'), _('TEMPLATE')),
4151 _('display with template'), _('TEMPLATE')),
4147 ]
4152 ]
4148
4153
4149 logopts = [
4154 logopts = [
4150 ('p', 'patch', None, _('show patch')),
4155 ('p', 'patch', None, _('show patch')),
4151 ('g', 'git', None, _('use git extended diff format')),
4156 ('g', 'git', None, _('use git extended diff format')),
4152 ('l', 'limit', '',
4157 ('l', 'limit', '',
4153 _('limit number of changes displayed'), _('NUM')),
4158 _('limit number of changes displayed'), _('NUM')),
4154 ('M', 'no-merges', None, _('do not show merges')),
4159 ('M', 'no-merges', None, _('do not show merges')),
4155 ('', 'stat', None, _('output diffstat-style summary of changes')),
4160 ('', 'stat', None, _('output diffstat-style summary of changes')),
4156 ] + templateopts
4161 ] + templateopts
4157
4162
4158 diffopts = [
4163 diffopts = [
4159 ('a', 'text', None, _('treat all files as text')),
4164 ('a', 'text', None, _('treat all files as text')),
4160 ('g', 'git', None, _('use git extended diff format')),
4165 ('g', 'git', None, _('use git extended diff format')),
4161 ('', 'nodates', None, _('omit dates from diff headers'))
4166 ('', 'nodates', None, _('omit dates from diff headers'))
4162 ]
4167 ]
4163
4168
4164 diffopts2 = [
4169 diffopts2 = [
4165 ('p', 'show-function', None, _('show which function each change is in')),
4170 ('p', 'show-function', None, _('show which function each change is in')),
4166 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4171 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4167 ('w', 'ignore-all-space', None,
4172 ('w', 'ignore-all-space', None,
4168 _('ignore white space when comparing lines')),
4173 _('ignore white space when comparing lines')),
4169 ('b', 'ignore-space-change', None,
4174 ('b', 'ignore-space-change', None,
4170 _('ignore changes in the amount of white space')),
4175 _('ignore changes in the amount of white space')),
4171 ('B', 'ignore-blank-lines', None,
4176 ('B', 'ignore-blank-lines', None,
4172 _('ignore changes whose lines are all blank')),
4177 _('ignore changes whose lines are all blank')),
4173 ('U', 'unified', '',
4178 ('U', 'unified', '',
4174 _('number of lines of context to show'), _('NUM')),
4179 _('number of lines of context to show'), _('NUM')),
4175 ('', 'stat', None, _('output diffstat-style summary of changes')),
4180 ('', 'stat', None, _('output diffstat-style summary of changes')),
4176 ]
4181 ]
4177
4182
4178 similarityopts = [
4183 similarityopts = [
4179 ('s', 'similarity', '',
4184 ('s', 'similarity', '',
4180 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4185 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4181 ]
4186 ]
4182
4187
4183 subrepoopts = [
4188 subrepoopts = [
4184 ('S', 'subrepos', None,
4189 ('S', 'subrepos', None,
4185 _('recurse into subrepositories'))
4190 _('recurse into subrepositories'))
4186 ]
4191 ]
4187
4192
4188 table = {
4193 table = {
4189 "^add": (add, walkopts + subrepoopts + dryrunopts,
4194 "^add": (add, walkopts + subrepoopts + dryrunopts,
4190 _('[OPTION]... [FILE]...')),
4195 _('[OPTION]... [FILE]...')),
4191 "addremove":
4196 "addremove":
4192 (addremove, similarityopts + walkopts + dryrunopts,
4197 (addremove, similarityopts + walkopts + dryrunopts,
4193 _('[OPTION]... [FILE]...')),
4198 _('[OPTION]... [FILE]...')),
4194 "^annotate|blame":
4199 "^annotate|blame":
4195 (annotate,
4200 (annotate,
4196 [('r', 'rev', '',
4201 [('r', 'rev', '',
4197 _('annotate the specified revision'), _('REV')),
4202 _('annotate the specified revision'), _('REV')),
4198 ('', 'follow', None,
4203 ('', 'follow', None,
4199 _('follow copies/renames and list the filename (DEPRECATED)')),
4204 _('follow copies/renames and list the filename (DEPRECATED)')),
4200 ('', 'no-follow', None, _("don't follow copies and renames")),
4205 ('', 'no-follow', None, _("don't follow copies and renames")),
4201 ('a', 'text', None, _('treat all files as text')),
4206 ('a', 'text', None, _('treat all files as text')),
4202 ('u', 'user', None, _('list the author (long with -v)')),
4207 ('u', 'user', None, _('list the author (long with -v)')),
4203 ('f', 'file', None, _('list the filename')),
4208 ('f', 'file', None, _('list the filename')),
4204 ('d', 'date', None, _('list the date (short with -q)')),
4209 ('d', 'date', None, _('list the date (short with -q)')),
4205 ('n', 'number', None, _('list the revision number (default)')),
4210 ('n', 'number', None, _('list the revision number (default)')),
4206 ('c', 'changeset', None, _('list the changeset')),
4211 ('c', 'changeset', None, _('list the changeset')),
4207 ('l', 'line-number', None,
4212 ('l', 'line-number', None,
4208 _('show line number at the first appearance'))
4213 _('show line number at the first appearance'))
4209 ] + walkopts,
4214 ] + walkopts,
4210 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4215 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4211 "archive":
4216 "archive":
4212 (archive,
4217 (archive,
4213 [('', 'no-decode', None, _('do not pass files through decoders')),
4218 [('', 'no-decode', None, _('do not pass files through decoders')),
4214 ('p', 'prefix', '',
4219 ('p', 'prefix', '',
4215 _('directory prefix for files in archive'), _('PREFIX')),
4220 _('directory prefix for files in archive'), _('PREFIX')),
4216 ('r', 'rev', '',
4221 ('r', 'rev', '',
4217 _('revision to distribute'), _('REV')),
4222 _('revision to distribute'), _('REV')),
4218 ('t', 'type', '',
4223 ('t', 'type', '',
4219 _('type of distribution to create'), _('TYPE')),
4224 _('type of distribution to create'), _('TYPE')),
4220 ] + subrepoopts + walkopts,
4225 ] + subrepoopts + walkopts,
4221 _('[OPTION]... DEST')),
4226 _('[OPTION]... DEST')),
4222 "backout":
4227 "backout":
4223 (backout,
4228 (backout,
4224 [('', 'merge', None,
4229 [('', 'merge', None,
4225 _('merge with old dirstate parent after backout')),
4230 _('merge with old dirstate parent after backout')),
4226 ('', 'parent', '',
4231 ('', 'parent', '',
4227 _('parent to choose when backing out merge'), _('REV')),
4232 _('parent to choose when backing out merge'), _('REV')),
4228 ('t', 'tool', '',
4233 ('t', 'tool', '',
4229 _('specify merge tool')),
4234 _('specify merge tool')),
4230 ('r', 'rev', '',
4235 ('r', 'rev', '',
4231 _('revision to backout'), _('REV')),
4236 _('revision to backout'), _('REV')),
4232 ] + walkopts + commitopts + commitopts2,
4237 ] + walkopts + commitopts + commitopts2,
4233 _('[OPTION]... [-r] REV')),
4238 _('[OPTION]... [-r] REV')),
4234 "bisect":
4239 "bisect":
4235 (bisect,
4240 (bisect,
4236 [('r', 'reset', False, _('reset bisect state')),
4241 [('r', 'reset', False, _('reset bisect state')),
4237 ('g', 'good', False, _('mark changeset good')),
4242 ('g', 'good', False, _('mark changeset good')),
4238 ('b', 'bad', False, _('mark changeset bad')),
4243 ('b', 'bad', False, _('mark changeset bad')),
4239 ('s', 'skip', False, _('skip testing changeset')),
4244 ('s', 'skip', False, _('skip testing changeset')),
4240 ('c', 'command', '',
4245 ('c', 'command', '',
4241 _('use command to check changeset state'), _('CMD')),
4246 _('use command to check changeset state'), _('CMD')),
4242 ('U', 'noupdate', False, _('do not update to target'))],
4247 ('U', 'noupdate', False, _('do not update to target'))],
4243 _("[-gbsr] [-U] [-c CMD] [REV]")),
4248 _("[-gbsr] [-U] [-c CMD] [REV]")),
4244 "bookmarks":
4249 "bookmarks":
4245 (bookmark,
4250 (bookmark,
4246 [('f', 'force', False, _('force')),
4251 [('f', 'force', False, _('force')),
4247 ('r', 'rev', '', _('revision'), _('REV')),
4252 ('r', 'rev', '', _('revision'), _('REV')),
4248 ('d', 'delete', False, _('delete a given bookmark')),
4253 ('d', 'delete', False, _('delete a given bookmark')),
4249 ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
4254 ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
4250 _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
4255 _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
4251 "branch":
4256 "branch":
4252 (branch,
4257 (branch,
4253 [('f', 'force', None,
4258 [('f', 'force', None,
4254 _('set branch name even if it shadows an existing branch')),
4259 _('set branch name even if it shadows an existing branch')),
4255 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4260 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4256 _('[-fC] [NAME]')),
4261 _('[-fC] [NAME]')),
4257 "branches":
4262 "branches":
4258 (branches,
4263 (branches,
4259 [('a', 'active', False,
4264 [('a', 'active', False,
4260 _('show only branches that have unmerged heads')),
4265 _('show only branches that have unmerged heads')),
4261 ('c', 'closed', False,
4266 ('c', 'closed', False,
4262 _('show normal and closed branches'))],
4267 _('show normal and closed branches'))],
4263 _('[-ac]')),
4268 _('[-ac]')),
4264 "bundle":
4269 "bundle":
4265 (bundle,
4270 (bundle,
4266 [('f', 'force', None,
4271 [('f', 'force', None,
4267 _('run even when the destination is unrelated')),
4272 _('run even when the destination is unrelated')),
4268 ('r', 'rev', [],
4273 ('r', 'rev', [],
4269 _('a changeset intended to be added to the destination'),
4274 _('a changeset intended to be added to the destination'),
4270 _('REV')),
4275 _('REV')),
4271 ('b', 'branch', [],
4276 ('b', 'branch', [],
4272 _('a specific branch you would like to bundle'),
4277 _('a specific branch you would like to bundle'),
4273 _('BRANCH')),
4278 _('BRANCH')),
4274 ('', 'base', [],
4279 ('', 'base', [],
4275 _('a base changeset assumed to be available at the destination'),
4280 _('a base changeset assumed to be available at the destination'),
4276 _('REV')),
4281 _('REV')),
4277 ('a', 'all', None, _('bundle all changesets in the repository')),
4282 ('a', 'all', None, _('bundle all changesets in the repository')),
4278 ('t', 'type', 'bzip2',
4283 ('t', 'type', 'bzip2',
4279 _('bundle compression type to use'), _('TYPE')),
4284 _('bundle compression type to use'), _('TYPE')),
4280 ] + remoteopts,
4285 ] + remoteopts,
4281 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4286 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4282 "cat":
4287 "cat":
4283 (cat,
4288 (cat,
4284 [('o', 'output', '',
4289 [('o', 'output', '',
4285 _('print output to file with formatted name'), _('FORMAT')),
4290 _('print output to file with formatted name'), _('FORMAT')),
4286 ('r', 'rev', '',
4291 ('r', 'rev', '',
4287 _('print the given revision'), _('REV')),
4292 _('print the given revision'), _('REV')),
4288 ('', 'decode', None, _('apply any matching decode filter')),
4293 ('', 'decode', None, _('apply any matching decode filter')),
4289 ] + walkopts,
4294 ] + walkopts,
4290 _('[OPTION]... FILE...')),
4295 _('[OPTION]... FILE...')),
4291 "^clone":
4296 "^clone":
4292 (clone,
4297 (clone,
4293 [('U', 'noupdate', None,
4298 [('U', 'noupdate', None,
4294 _('the clone will include an empty working copy (only a repository)')),
4299 _('the clone will include an empty working copy (only a repository)')),
4295 ('u', 'updaterev', '',
4300 ('u', 'updaterev', '',
4296 _('revision, tag or branch to check out'), _('REV')),
4301 _('revision, tag or branch to check out'), _('REV')),
4297 ('r', 'rev', [],
4302 ('r', 'rev', [],
4298 _('include the specified changeset'), _('REV')),
4303 _('include the specified changeset'), _('REV')),
4299 ('b', 'branch', [],
4304 ('b', 'branch', [],
4300 _('clone only the specified branch'), _('BRANCH')),
4305 _('clone only the specified branch'), _('BRANCH')),
4301 ('', 'pull', None, _('use pull protocol to copy metadata')),
4306 ('', 'pull', None, _('use pull protocol to copy metadata')),
4302 ('', 'uncompressed', None,
4307 ('', 'uncompressed', None,
4303 _('use uncompressed transfer (fast over LAN)')),
4308 _('use uncompressed transfer (fast over LAN)')),
4304 ] + remoteopts,
4309 ] + remoteopts,
4305 _('[OPTION]... SOURCE [DEST]')),
4310 _('[OPTION]... SOURCE [DEST]')),
4306 "^commit|ci":
4311 "^commit|ci":
4307 (commit,
4312 (commit,
4308 [('A', 'addremove', None,
4313 [('A', 'addremove', None,
4309 _('mark new/missing files as added/removed before committing')),
4314 _('mark new/missing files as added/removed before committing')),
4310 ('', 'close-branch', None,
4315 ('', 'close-branch', None,
4311 _('mark a branch as closed, hiding it from the branch list')),
4316 _('mark a branch as closed, hiding it from the branch list')),
4312 ] + walkopts + commitopts + commitopts2,
4317 ] + walkopts + commitopts + commitopts2,
4313 _('[OPTION]... [FILE]...')),
4318 _('[OPTION]... [FILE]...')),
4314 "copy|cp":
4319 "copy|cp":
4315 (copy,
4320 (copy,
4316 [('A', 'after', None, _('record a copy that has already occurred')),
4321 [('A', 'after', None, _('record a copy that has already occurred')),
4317 ('f', 'force', None,
4322 ('f', 'force', None,
4318 _('forcibly copy over an existing managed file')),
4323 _('forcibly copy over an existing managed file')),
4319 ] + walkopts + dryrunopts,
4324 ] + walkopts + dryrunopts,
4320 _('[OPTION]... [SOURCE]... DEST')),
4325 _('[OPTION]... [SOURCE]... DEST')),
4321 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4326 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4322 "debugbuilddag":
4327 "debugbuilddag":
4323 (debugbuilddag,
4328 (debugbuilddag,
4324 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4329 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4325 ('a', 'appended-file', None, _('add single file all revs append to')),
4330 ('a', 'appended-file', None, _('add single file all revs append to')),
4326 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4331 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4327 ('n', 'new-file', None, _('add new file at each rev')),
4332 ('n', 'new-file', None, _('add new file at each rev')),
4328 ],
4333 ],
4329 _('[OPTION]... TEXT')),
4334 _('[OPTION]... TEXT')),
4330 "debugcheckstate": (debugcheckstate, [], ''),
4335 "debugcheckstate": (debugcheckstate, [], ''),
4331 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4336 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4332 "debugcomplete":
4337 "debugcomplete":
4333 (debugcomplete,
4338 (debugcomplete,
4334 [('o', 'options', None, _('show the command options'))],
4339 [('o', 'options', None, _('show the command options'))],
4335 _('[-o] CMD')),
4340 _('[-o] CMD')),
4336 "debugdag":
4341 "debugdag":
4337 (debugdag,
4342 (debugdag,
4338 [('t', 'tags', None, _('use tags as labels')),
4343 [('t', 'tags', None, _('use tags as labels')),
4339 ('b', 'branches', None, _('annotate with branch names')),
4344 ('b', 'branches', None, _('annotate with branch names')),
4340 ('', 'dots', None, _('use dots for runs')),
4345 ('', 'dots', None, _('use dots for runs')),
4341 ('s', 'spaces', None, _('separate elements by spaces')),
4346 ('s', 'spaces', None, _('separate elements by spaces')),
4342 ],
4347 ],
4343 _('[OPTION]... [FILE [REV]...]')),
4348 _('[OPTION]... [FILE [REV]...]')),
4344 "debugdate":
4349 "debugdate":
4345 (debugdate,
4350 (debugdate,
4346 [('e', 'extended', None, _('try extended date formats'))],
4351 [('e', 'extended', None, _('try extended date formats'))],
4347 _('[-e] DATE [RANGE]')),
4352 _('[-e] DATE [RANGE]')),
4348 "debugdata": (debugdata, [], _('FILE REV')),
4353 "debugdata": (debugdata, [], _('FILE REV')),
4349 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4354 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4355 "debugignore": (debugignore, [], ''),
4350 "debugindex": (debugindex,
4356 "debugindex": (debugindex,
4351 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4357 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4352 _('FILE')),
4358 _('FILE')),
4353 "debugindexdot": (debugindexdot, [], _('FILE')),
4359 "debugindexdot": (debugindexdot, [], _('FILE')),
4354 "debuginstall": (debuginstall, [], ''),
4360 "debuginstall": (debuginstall, [], ''),
4355 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4361 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4356 "debugrebuildstate":
4362 "debugrebuildstate":
4357 (debugrebuildstate,
4363 (debugrebuildstate,
4358 [('r', 'rev', '',
4364 [('r', 'rev', '',
4359 _('revision to rebuild to'), _('REV'))],
4365 _('revision to rebuild to'), _('REV'))],
4360 _('[-r REV] [REV]')),
4366 _('[-r REV] [REV]')),
4361 "debugrename":
4367 "debugrename":
4362 (debugrename,
4368 (debugrename,
4363 [('r', 'rev', '',
4369 [('r', 'rev', '',
4364 _('revision to debug'), _('REV'))],
4370 _('revision to debug'), _('REV'))],
4365 _('[-r REV] FILE')),
4371 _('[-r REV] FILE')),
4366 "debugrevspec":
4372 "debugrevspec":
4367 (debugrevspec, [], ('REVSPEC')),
4373 (debugrevspec, [], ('REVSPEC')),
4368 "debugsetparents":
4374 "debugsetparents":
4369 (debugsetparents, [], _('REV1 [REV2]')),
4375 (debugsetparents, [], _('REV1 [REV2]')),
4370 "debugstate":
4376 "debugstate":
4371 (debugstate,
4377 (debugstate,
4372 [('', 'nodates', None, _('do not display the saved mtime'))],
4378 [('', 'nodates', None, _('do not display the saved mtime'))],
4373 _('[OPTION]...')),
4379 _('[OPTION]...')),
4374 "debugsub":
4380 "debugsub":
4375 (debugsub,
4381 (debugsub,
4376 [('r', 'rev', '',
4382 [('r', 'rev', '',
4377 _('revision to check'), _('REV'))],
4383 _('revision to check'), _('REV'))],
4378 _('[-r REV] [REV]')),
4384 _('[-r REV] [REV]')),
4379 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4385 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4380 "^diff":
4386 "^diff":
4381 (diff,
4387 (diff,
4382 [('r', 'rev', [],
4388 [('r', 'rev', [],
4383 _('revision'), _('REV')),
4389 _('revision'), _('REV')),
4384 ('c', 'change', '',
4390 ('c', 'change', '',
4385 _('change made by revision'), _('REV'))
4391 _('change made by revision'), _('REV'))
4386 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4392 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4387 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4393 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4388 "^export":
4394 "^export":
4389 (export,
4395 (export,
4390 [('o', 'output', '',
4396 [('o', 'output', '',
4391 _('print output to file with formatted name'), _('FORMAT')),
4397 _('print output to file with formatted name'), _('FORMAT')),
4392 ('', 'switch-parent', None, _('diff against the second parent')),
4398 ('', 'switch-parent', None, _('diff against the second parent')),
4393 ('r', 'rev', [],
4399 ('r', 'rev', [],
4394 _('revisions to export'), _('REV')),
4400 _('revisions to export'), _('REV')),
4395 ] + diffopts,
4401 ] + diffopts,
4396 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4402 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4397 "^forget":
4403 "^forget":
4398 (forget,
4404 (forget,
4399 [] + walkopts,
4405 [] + walkopts,
4400 _('[OPTION]... FILE...')),
4406 _('[OPTION]... FILE...')),
4401 "grep":
4407 "grep":
4402 (grep,
4408 (grep,
4403 [('0', 'print0', None, _('end fields with NUL')),
4409 [('0', 'print0', None, _('end fields with NUL')),
4404 ('', 'all', None, _('print all revisions that match')),
4410 ('', 'all', None, _('print all revisions that match')),
4405 ('f', 'follow', None,
4411 ('f', 'follow', None,
4406 _('follow changeset history,'
4412 _('follow changeset history,'
4407 ' or file history across copies and renames')),
4413 ' or file history across copies and renames')),
4408 ('i', 'ignore-case', None, _('ignore case when matching')),
4414 ('i', 'ignore-case', None, _('ignore case when matching')),
4409 ('l', 'files-with-matches', None,
4415 ('l', 'files-with-matches', None,
4410 _('print only filenames and revisions that match')),
4416 _('print only filenames and revisions that match')),
4411 ('n', 'line-number', None, _('print matching line numbers')),
4417 ('n', 'line-number', None, _('print matching line numbers')),
4412 ('r', 'rev', [],
4418 ('r', 'rev', [],
4413 _('only search files changed within revision range'), _('REV')),
4419 _('only search files changed within revision range'), _('REV')),
4414 ('u', 'user', None, _('list the author (long with -v)')),
4420 ('u', 'user', None, _('list the author (long with -v)')),
4415 ('d', 'date', None, _('list the date (short with -q)')),
4421 ('d', 'date', None, _('list the date (short with -q)')),
4416 ] + walkopts,
4422 ] + walkopts,
4417 _('[OPTION]... PATTERN [FILE]...')),
4423 _('[OPTION]... PATTERN [FILE]...')),
4418 "heads":
4424 "heads":
4419 (heads,
4425 (heads,
4420 [('r', 'rev', '',
4426 [('r', 'rev', '',
4421 _('show only heads which are descendants of STARTREV'),
4427 _('show only heads which are descendants of STARTREV'),
4422 _('STARTREV')),
4428 _('STARTREV')),
4423 ('t', 'topo', False, _('show topological heads only')),
4429 ('t', 'topo', False, _('show topological heads only')),
4424 ('a', 'active', False,
4430 ('a', 'active', False,
4425 _('show active branchheads only (DEPRECATED)')),
4431 _('show active branchheads only (DEPRECATED)')),
4426 ('c', 'closed', False,
4432 ('c', 'closed', False,
4427 _('show normal and closed branch heads')),
4433 _('show normal and closed branch heads')),
4428 ] + templateopts,
4434 ] + templateopts,
4429 _('[-ac] [-r STARTREV] [REV]...')),
4435 _('[-ac] [-r STARTREV] [REV]...')),
4430 "help": (help_, [], _('[TOPIC]')),
4436 "help": (help_, [], _('[TOPIC]')),
4431 "identify|id":
4437 "identify|id":
4432 (identify,
4438 (identify,
4433 [('r', 'rev', '',
4439 [('r', 'rev', '',
4434 _('identify the specified revision'), _('REV')),
4440 _('identify the specified revision'), _('REV')),
4435 ('n', 'num', None, _('show local revision number')),
4441 ('n', 'num', None, _('show local revision number')),
4436 ('i', 'id', None, _('show global revision id')),
4442 ('i', 'id', None, _('show global revision id')),
4437 ('b', 'branch', None, _('show branch')),
4443 ('b', 'branch', None, _('show branch')),
4438 ('t', 'tags', None, _('show tags'))],
4444 ('t', 'tags', None, _('show tags'))],
4439 _('[-nibt] [-r REV] [SOURCE]')),
4445 _('[-nibt] [-r REV] [SOURCE]')),
4440 "import|patch":
4446 "import|patch":
4441 (import_,
4447 (import_,
4442 [('p', 'strip', 1,
4448 [('p', 'strip', 1,
4443 _('directory strip option for patch. This has the same '
4449 _('directory strip option for patch. This has the same '
4444 'meaning as the corresponding patch option'),
4450 'meaning as the corresponding patch option'),
4445 _('NUM')),
4451 _('NUM')),
4446 ('b', 'base', '',
4452 ('b', 'base', '',
4447 _('base path'), _('PATH')),
4453 _('base path'), _('PATH')),
4448 ('f', 'force', None,
4454 ('f', 'force', None,
4449 _('skip check for outstanding uncommitted changes')),
4455 _('skip check for outstanding uncommitted changes')),
4450 ('', 'no-commit', None,
4456 ('', 'no-commit', None,
4451 _("don't commit, just update the working directory")),
4457 _("don't commit, just update the working directory")),
4452 ('', 'exact', None,
4458 ('', 'exact', None,
4453 _('apply patch to the nodes from which it was generated')),
4459 _('apply patch to the nodes from which it was generated')),
4454 ('', 'import-branch', None,
4460 ('', 'import-branch', None,
4455 _('use any branch information in patch (implied by --exact)'))] +
4461 _('use any branch information in patch (implied by --exact)'))] +
4456 commitopts + commitopts2 + similarityopts,
4462 commitopts + commitopts2 + similarityopts,
4457 _('[OPTION]... PATCH...')),
4463 _('[OPTION]... PATCH...')),
4458 "incoming|in":
4464 "incoming|in":
4459 (incoming,
4465 (incoming,
4460 [('f', 'force', None,
4466 [('f', 'force', None,
4461 _('run even if remote repository is unrelated')),
4467 _('run even if remote repository is unrelated')),
4462 ('n', 'newest-first', None, _('show newest record first')),
4468 ('n', 'newest-first', None, _('show newest record first')),
4463 ('', 'bundle', '',
4469 ('', 'bundle', '',
4464 _('file to store the bundles into'), _('FILE')),
4470 _('file to store the bundles into'), _('FILE')),
4465 ('r', 'rev', [],
4471 ('r', 'rev', [],
4466 _('a remote changeset intended to be added'), _('REV')),
4472 _('a remote changeset intended to be added'), _('REV')),
4467 ('B', 'bookmarks', False, _("compare bookmarks")),
4473 ('B', 'bookmarks', False, _("compare bookmarks")),
4468 ('b', 'branch', [],
4474 ('b', 'branch', [],
4469 _('a specific branch you would like to pull'), _('BRANCH')),
4475 _('a specific branch you would like to pull'), _('BRANCH')),
4470 ] + logopts + remoteopts + subrepoopts,
4476 ] + logopts + remoteopts + subrepoopts,
4471 _('[-p] [-n] [-M] [-f] [-r REV]...'
4477 _('[-p] [-n] [-M] [-f] [-r REV]...'
4472 ' [--bundle FILENAME] [SOURCE]')),
4478 ' [--bundle FILENAME] [SOURCE]')),
4473 "^init":
4479 "^init":
4474 (init,
4480 (init,
4475 remoteopts,
4481 remoteopts,
4476 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4482 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4477 "locate":
4483 "locate":
4478 (locate,
4484 (locate,
4479 [('r', 'rev', '',
4485 [('r', 'rev', '',
4480 _('search the repository as it is in REV'), _('REV')),
4486 _('search the repository as it is in REV'), _('REV')),
4481 ('0', 'print0', None,
4487 ('0', 'print0', None,
4482 _('end filenames with NUL, for use with xargs')),
4488 _('end filenames with NUL, for use with xargs')),
4483 ('f', 'fullpath', None,
4489 ('f', 'fullpath', None,
4484 _('print complete paths from the filesystem root')),
4490 _('print complete paths from the filesystem root')),
4485 ] + walkopts,
4491 ] + walkopts,
4486 _('[OPTION]... [PATTERN]...')),
4492 _('[OPTION]... [PATTERN]...')),
4487 "^log|history":
4493 "^log|history":
4488 (log,
4494 (log,
4489 [('f', 'follow', None,
4495 [('f', 'follow', None,
4490 _('follow changeset history,'
4496 _('follow changeset history,'
4491 ' or file history across copies and renames')),
4497 ' or file history across copies and renames')),
4492 ('', 'follow-first', None,
4498 ('', 'follow-first', None,
4493 _('only follow the first parent of merge changesets')),
4499 _('only follow the first parent of merge changesets')),
4494 ('d', 'date', '',
4500 ('d', 'date', '',
4495 _('show revisions matching date spec'), _('DATE')),
4501 _('show revisions matching date spec'), _('DATE')),
4496 ('C', 'copies', None, _('show copied files')),
4502 ('C', 'copies', None, _('show copied files')),
4497 ('k', 'keyword', [],
4503 ('k', 'keyword', [],
4498 _('do case-insensitive search for a given text'), _('TEXT')),
4504 _('do case-insensitive search for a given text'), _('TEXT')),
4499 ('r', 'rev', [],
4505 ('r', 'rev', [],
4500 _('show the specified revision or range'), _('REV')),
4506 _('show the specified revision or range'), _('REV')),
4501 ('', 'removed', None, _('include revisions where files were removed')),
4507 ('', 'removed', None, _('include revisions where files were removed')),
4502 ('m', 'only-merges', None, _('show only merges')),
4508 ('m', 'only-merges', None, _('show only merges')),
4503 ('u', 'user', [],
4509 ('u', 'user', [],
4504 _('revisions committed by user'), _('USER')),
4510 _('revisions committed by user'), _('USER')),
4505 ('', 'only-branch', [],
4511 ('', 'only-branch', [],
4506 _('show only changesets within the given named branch (DEPRECATED)'),
4512 _('show only changesets within the given named branch (DEPRECATED)'),
4507 _('BRANCH')),
4513 _('BRANCH')),
4508 ('b', 'branch', [],
4514 ('b', 'branch', [],
4509 _('show changesets within the given named branch'), _('BRANCH')),
4515 _('show changesets within the given named branch'), _('BRANCH')),
4510 ('P', 'prune', [],
4516 ('P', 'prune', [],
4511 _('do not display revision or any of its ancestors'), _('REV')),
4517 _('do not display revision or any of its ancestors'), _('REV')),
4512 ] + logopts + walkopts,
4518 ] + logopts + walkopts,
4513 _('[OPTION]... [FILE]')),
4519 _('[OPTION]... [FILE]')),
4514 "manifest":
4520 "manifest":
4515 (manifest,
4521 (manifest,
4516 [('r', 'rev', '',
4522 [('r', 'rev', '',
4517 _('revision to display'), _('REV'))],
4523 _('revision to display'), _('REV'))],
4518 _('[-r REV]')),
4524 _('[-r REV]')),
4519 "^merge":
4525 "^merge":
4520 (merge,
4526 (merge,
4521 [('f', 'force', None, _('force a merge with outstanding changes')),
4527 [('f', 'force', None, _('force a merge with outstanding changes')),
4522 ('t', 'tool', '', _('specify merge tool')),
4528 ('t', 'tool', '', _('specify merge tool')),
4523 ('r', 'rev', '',
4529 ('r', 'rev', '',
4524 _('revision to merge'), _('REV')),
4530 _('revision to merge'), _('REV')),
4525 ('P', 'preview', None,
4531 ('P', 'preview', None,
4526 _('review revisions to merge (no merge is performed)'))],
4532 _('review revisions to merge (no merge is performed)'))],
4527 _('[-P] [-f] [[-r] REV]')),
4533 _('[-P] [-f] [[-r] REV]')),
4528 "outgoing|out":
4534 "outgoing|out":
4529 (outgoing,
4535 (outgoing,
4530 [('f', 'force', None,
4536 [('f', 'force', None,
4531 _('run even when the destination is unrelated')),
4537 _('run even when the destination is unrelated')),
4532 ('r', 'rev', [],
4538 ('r', 'rev', [],
4533 _('a changeset intended to be included in the destination'),
4539 _('a changeset intended to be included in the destination'),
4534 _('REV')),
4540 _('REV')),
4535 ('n', 'newest-first', None, _('show newest record first')),
4541 ('n', 'newest-first', None, _('show newest record first')),
4536 ('B', 'bookmarks', False, _("compare bookmarks")),
4542 ('B', 'bookmarks', False, _("compare bookmarks")),
4537 ('b', 'branch', [],
4543 ('b', 'branch', [],
4538 _('a specific branch you would like to push'), _('BRANCH')),
4544 _('a specific branch you would like to push'), _('BRANCH')),
4539 ] + logopts + remoteopts + subrepoopts,
4545 ] + logopts + remoteopts + subrepoopts,
4540 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4546 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4541 "parents":
4547 "parents":
4542 (parents,
4548 (parents,
4543 [('r', 'rev', '',
4549 [('r', 'rev', '',
4544 _('show parents of the specified revision'), _('REV')),
4550 _('show parents of the specified revision'), _('REV')),
4545 ] + templateopts,
4551 ] + templateopts,
4546 _('[-r REV] [FILE]')),
4552 _('[-r REV] [FILE]')),
4547 "paths": (paths, [], _('[NAME]')),
4553 "paths": (paths, [], _('[NAME]')),
4548 "^pull":
4554 "^pull":
4549 (pull,
4555 (pull,
4550 [('u', 'update', None,
4556 [('u', 'update', None,
4551 _('update to new branch head if changesets were pulled')),
4557 _('update to new branch head if changesets were pulled')),
4552 ('f', 'force', None,
4558 ('f', 'force', None,
4553 _('run even when remote repository is unrelated')),
4559 _('run even when remote repository is unrelated')),
4554 ('r', 'rev', [],
4560 ('r', 'rev', [],
4555 _('a remote changeset intended to be added'), _('REV')),
4561 _('a remote changeset intended to be added'), _('REV')),
4556 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4562 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4557 ('b', 'branch', [],
4563 ('b', 'branch', [],
4558 _('a specific branch you would like to pull'), _('BRANCH')),
4564 _('a specific branch you would like to pull'), _('BRANCH')),
4559 ] + remoteopts,
4565 ] + remoteopts,
4560 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4566 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4561 "^push":
4567 "^push":
4562 (push,
4568 (push,
4563 [('f', 'force', None, _('force push')),
4569 [('f', 'force', None, _('force push')),
4564 ('r', 'rev', [],
4570 ('r', 'rev', [],
4565 _('a changeset intended to be included in the destination'),
4571 _('a changeset intended to be included in the destination'),
4566 _('REV')),
4572 _('REV')),
4567 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4573 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4568 ('b', 'branch', [],
4574 ('b', 'branch', [],
4569 _('a specific branch you would like to push'), _('BRANCH')),
4575 _('a specific branch you would like to push'), _('BRANCH')),
4570 ('', 'new-branch', False, _('allow pushing a new branch')),
4576 ('', 'new-branch', False, _('allow pushing a new branch')),
4571 ] + remoteopts,
4577 ] + remoteopts,
4572 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4578 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4573 "recover": (recover, []),
4579 "recover": (recover, []),
4574 "^remove|rm":
4580 "^remove|rm":
4575 (remove,
4581 (remove,
4576 [('A', 'after', None, _('record delete for missing files')),
4582 [('A', 'after', None, _('record delete for missing files')),
4577 ('f', 'force', None,
4583 ('f', 'force', None,
4578 _('remove (and delete) file even if added or modified')),
4584 _('remove (and delete) file even if added or modified')),
4579 ] + walkopts,
4585 ] + walkopts,
4580 _('[OPTION]... FILE...')),
4586 _('[OPTION]... FILE...')),
4581 "rename|move|mv":
4587 "rename|move|mv":
4582 (rename,
4588 (rename,
4583 [('A', 'after', None, _('record a rename that has already occurred')),
4589 [('A', 'after', None, _('record a rename that has already occurred')),
4584 ('f', 'force', None,
4590 ('f', 'force', None,
4585 _('forcibly copy over an existing managed file')),
4591 _('forcibly copy over an existing managed file')),
4586 ] + walkopts + dryrunopts,
4592 ] + walkopts + dryrunopts,
4587 _('[OPTION]... SOURCE... DEST')),
4593 _('[OPTION]... SOURCE... DEST')),
4588 "resolve":
4594 "resolve":
4589 (resolve,
4595 (resolve,
4590 [('a', 'all', None, _('select all unresolved files')),
4596 [('a', 'all', None, _('select all unresolved files')),
4591 ('l', 'list', None, _('list state of files needing merge')),
4597 ('l', 'list', None, _('list state of files needing merge')),
4592 ('m', 'mark', None, _('mark files as resolved')),
4598 ('m', 'mark', None, _('mark files as resolved')),
4593 ('u', 'unmark', None, _('mark files as unresolved')),
4599 ('u', 'unmark', None, _('mark files as unresolved')),
4594 ('t', 'tool', '', _('specify merge tool')),
4600 ('t', 'tool', '', _('specify merge tool')),
4595 ('n', 'no-status', None, _('hide status prefix'))]
4601 ('n', 'no-status', None, _('hide status prefix'))]
4596 + walkopts,
4602 + walkopts,
4597 _('[OPTION]... [FILE]...')),
4603 _('[OPTION]... [FILE]...')),
4598 "revert":
4604 "revert":
4599 (revert,
4605 (revert,
4600 [('a', 'all', None, _('revert all changes when no arguments given')),
4606 [('a', 'all', None, _('revert all changes when no arguments given')),
4601 ('d', 'date', '',
4607 ('d', 'date', '',
4602 _('tipmost revision matching date'), _('DATE')),
4608 _('tipmost revision matching date'), _('DATE')),
4603 ('r', 'rev', '',
4609 ('r', 'rev', '',
4604 _('revert to the specified revision'), _('REV')),
4610 _('revert to the specified revision'), _('REV')),
4605 ('', 'no-backup', None, _('do not save backup copies of files')),
4611 ('', 'no-backup', None, _('do not save backup copies of files')),
4606 ] + walkopts + dryrunopts,
4612 ] + walkopts + dryrunopts,
4607 _('[OPTION]... [-r REV] [NAME]...')),
4613 _('[OPTION]... [-r REV] [NAME]...')),
4608 "rollback": (rollback, dryrunopts),
4614 "rollback": (rollback, dryrunopts),
4609 "root": (root, []),
4615 "root": (root, []),
4610 "^serve":
4616 "^serve":
4611 (serve,
4617 (serve,
4612 [('A', 'accesslog', '',
4618 [('A', 'accesslog', '',
4613 _('name of access log file to write to'), _('FILE')),
4619 _('name of access log file to write to'), _('FILE')),
4614 ('d', 'daemon', None, _('run server in background')),
4620 ('d', 'daemon', None, _('run server in background')),
4615 ('', 'daemon-pipefds', '',
4621 ('', 'daemon-pipefds', '',
4616 _('used internally by daemon mode'), _('NUM')),
4622 _('used internally by daemon mode'), _('NUM')),
4617 ('E', 'errorlog', '',
4623 ('E', 'errorlog', '',
4618 _('name of error log file to write to'), _('FILE')),
4624 _('name of error log file to write to'), _('FILE')),
4619 # use string type, then we can check if something was passed
4625 # use string type, then we can check if something was passed
4620 ('p', 'port', '',
4626 ('p', 'port', '',
4621 _('port to listen on (default: 8000)'), _('PORT')),
4627 _('port to listen on (default: 8000)'), _('PORT')),
4622 ('a', 'address', '',
4628 ('a', 'address', '',
4623 _('address to listen on (default: all interfaces)'), _('ADDR')),
4629 _('address to listen on (default: all interfaces)'), _('ADDR')),
4624 ('', 'prefix', '',
4630 ('', 'prefix', '',
4625 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4631 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4626 ('n', 'name', '',
4632 ('n', 'name', '',
4627 _('name to show in web pages (default: working directory)'),
4633 _('name to show in web pages (default: working directory)'),
4628 _('NAME')),
4634 _('NAME')),
4629 ('', 'web-conf', '',
4635 ('', 'web-conf', '',
4630 _('name of the hgweb config file (see "hg help hgweb")'),
4636 _('name of the hgweb config file (see "hg help hgweb")'),
4631 _('FILE')),
4637 _('FILE')),
4632 ('', 'webdir-conf', '',
4638 ('', 'webdir-conf', '',
4633 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4639 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4634 ('', 'pid-file', '',
4640 ('', 'pid-file', '',
4635 _('name of file to write process ID to'), _('FILE')),
4641 _('name of file to write process ID to'), _('FILE')),
4636 ('', 'stdio', None, _('for remote clients')),
4642 ('', 'stdio', None, _('for remote clients')),
4637 ('t', 'templates', '',
4643 ('t', 'templates', '',
4638 _('web templates to use'), _('TEMPLATE')),
4644 _('web templates to use'), _('TEMPLATE')),
4639 ('', 'style', '',
4645 ('', 'style', '',
4640 _('template style to use'), _('STYLE')),
4646 _('template style to use'), _('STYLE')),
4641 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4647 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4642 ('', 'certificate', '',
4648 ('', 'certificate', '',
4643 _('SSL certificate file'), _('FILE'))],
4649 _('SSL certificate file'), _('FILE'))],
4644 _('[OPTION]...')),
4650 _('[OPTION]...')),
4645 "showconfig|debugconfig":
4651 "showconfig|debugconfig":
4646 (showconfig,
4652 (showconfig,
4647 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4653 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4648 _('[-u] [NAME]...')),
4654 _('[-u] [NAME]...')),
4649 "^summary|sum":
4655 "^summary|sum":
4650 (summary,
4656 (summary,
4651 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4657 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4652 "^status|st":
4658 "^status|st":
4653 (status,
4659 (status,
4654 [('A', 'all', None, _('show status of all files')),
4660 [('A', 'all', None, _('show status of all files')),
4655 ('m', 'modified', None, _('show only modified files')),
4661 ('m', 'modified', None, _('show only modified files')),
4656 ('a', 'added', None, _('show only added files')),
4662 ('a', 'added', None, _('show only added files')),
4657 ('r', 'removed', None, _('show only removed files')),
4663 ('r', 'removed', None, _('show only removed files')),
4658 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4664 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4659 ('c', 'clean', None, _('show only files without changes')),
4665 ('c', 'clean', None, _('show only files without changes')),
4660 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4666 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4661 ('i', 'ignored', None, _('show only ignored files')),
4667 ('i', 'ignored', None, _('show only ignored files')),
4662 ('n', 'no-status', None, _('hide status prefix')),
4668 ('n', 'no-status', None, _('hide status prefix')),
4663 ('C', 'copies', None, _('show source of copied files')),
4669 ('C', 'copies', None, _('show source of copied files')),
4664 ('0', 'print0', None,
4670 ('0', 'print0', None,
4665 _('end filenames with NUL, for use with xargs')),
4671 _('end filenames with NUL, for use with xargs')),
4666 ('', 'rev', [],
4672 ('', 'rev', [],
4667 _('show difference from revision'), _('REV')),
4673 _('show difference from revision'), _('REV')),
4668 ('', 'change', '',
4674 ('', 'change', '',
4669 _('list the changed files of a revision'), _('REV')),
4675 _('list the changed files of a revision'), _('REV')),
4670 ] + walkopts + subrepoopts,
4676 ] + walkopts + subrepoopts,
4671 _('[OPTION]... [FILE]...')),
4677 _('[OPTION]... [FILE]...')),
4672 "tag":
4678 "tag":
4673 (tag,
4679 (tag,
4674 [('f', 'force', None, _('force tag')),
4680 [('f', 'force', None, _('force tag')),
4675 ('l', 'local', None, _('make the tag local')),
4681 ('l', 'local', None, _('make the tag local')),
4676 ('r', 'rev', '',
4682 ('r', 'rev', '',
4677 _('revision to tag'), _('REV')),
4683 _('revision to tag'), _('REV')),
4678 ('', 'remove', None, _('remove a tag')),
4684 ('', 'remove', None, _('remove a tag')),
4679 # -l/--local is already there, commitopts cannot be used
4685 # -l/--local is already there, commitopts cannot be used
4680 ('e', 'edit', None, _('edit commit message')),
4686 ('e', 'edit', None, _('edit commit message')),
4681 ('m', 'message', '',
4687 ('m', 'message', '',
4682 _('use <text> as commit message'), _('TEXT')),
4688 _('use <text> as commit message'), _('TEXT')),
4683 ] + commitopts2,
4689 ] + commitopts2,
4684 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4690 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4685 "tags": (tags, [], ''),
4691 "tags": (tags, [], ''),
4686 "tip":
4692 "tip":
4687 (tip,
4693 (tip,
4688 [('p', 'patch', None, _('show patch')),
4694 [('p', 'patch', None, _('show patch')),
4689 ('g', 'git', None, _('use git extended diff format')),
4695 ('g', 'git', None, _('use git extended diff format')),
4690 ] + templateopts,
4696 ] + templateopts,
4691 _('[-p] [-g]')),
4697 _('[-p] [-g]')),
4692 "unbundle":
4698 "unbundle":
4693 (unbundle,
4699 (unbundle,
4694 [('u', 'update', None,
4700 [('u', 'update', None,
4695 _('update to new branch head if changesets were unbundled'))],
4701 _('update to new branch head if changesets were unbundled'))],
4696 _('[-u] FILE...')),
4702 _('[-u] FILE...')),
4697 "^update|up|checkout|co":
4703 "^update|up|checkout|co":
4698 (update,
4704 (update,
4699 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4705 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4700 ('c', 'check', None,
4706 ('c', 'check', None,
4701 _('update across branches if no uncommitted changes')),
4707 _('update across branches if no uncommitted changes')),
4702 ('d', 'date', '',
4708 ('d', 'date', '',
4703 _('tipmost revision matching date'), _('DATE')),
4709 _('tipmost revision matching date'), _('DATE')),
4704 ('r', 'rev', '',
4710 ('r', 'rev', '',
4705 _('revision'), _('REV'))],
4711 _('revision'), _('REV'))],
4706 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4712 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4707 "verify": (verify, []),
4713 "verify": (verify, []),
4708 "version": (version_, []),
4714 "version": (version_, []),
4709 }
4715 }
4710
4716
4711 norepo = ("clone init version help debugcommands debugcomplete"
4717 norepo = ("clone init version help debugcommands debugcomplete"
4712 " debugdate debuginstall debugfsinfo debugpushkey")
4718 " debugdate debuginstall debugfsinfo debugpushkey")
4713 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4719 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4714 " debugdata debugindex debugindexdot")
4720 " debugdata debugindex debugindexdot")
@@ -1,306 +1,307
1 # match.py - filename matching
1 # match.py - filename matching
2 #
2 #
3 # Copyright 2008, 2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2008, 2009 Matt Mackall <mpm@selenic.com> and others
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 import re
8 import re
9 import util
9 import util
10 from i18n import _
10 from i18n import _
11
11
12 class match(object):
12 class match(object):
13 def __init__(self, root, cwd, patterns, include=[], exclude=[],
13 def __init__(self, root, cwd, patterns, include=[], exclude=[],
14 default='glob', exact=False, auditor=None):
14 default='glob', exact=False, auditor=None):
15 """build an object to match a set of file patterns
15 """build an object to match a set of file patterns
16
16
17 arguments:
17 arguments:
18 root - the canonical root of the tree you're matching against
18 root - the canonical root of the tree you're matching against
19 cwd - the current working directory, if relevant
19 cwd - the current working directory, if relevant
20 patterns - patterns to find
20 patterns - patterns to find
21 include - patterns to include
21 include - patterns to include
22 exclude - patterns to exclude
22 exclude - patterns to exclude
23 default - if a pattern in names has no explicit type, assume this one
23 default - if a pattern in names has no explicit type, assume this one
24 exact - patterns are actually literals
24 exact - patterns are actually literals
25
25
26 a pattern is one of:
26 a pattern is one of:
27 'glob:<glob>' - a glob relative to cwd
27 'glob:<glob>' - a glob relative to cwd
28 're:<regexp>' - a regular expression
28 're:<regexp>' - a regular expression
29 'path:<path>' - a path relative to canonroot
29 'path:<path>' - a path relative to canonroot
30 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
30 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
31 'relpath:<path>' - a path relative to cwd
31 'relpath:<path>' - a path relative to cwd
32 'relre:<regexp>' - a regexp that needn't match the start of a name
32 'relre:<regexp>' - a regexp that needn't match the start of a name
33 '<something>' - a pattern of the specified default type
33 '<something>' - a pattern of the specified default type
34 """
34 """
35
35
36 self._root = root
36 self._root = root
37 self._cwd = cwd
37 self._cwd = cwd
38 self._files = []
38 self._files = []
39 self._anypats = bool(include or exclude)
39 self._anypats = bool(include or exclude)
40
40
41 if include:
41 if include:
42 im = _buildmatch(_normalize(include, 'glob', root, cwd, auditor),
42 pats = _normalize(include, 'glob', root, cwd, auditor)
43 '(?:/|$)')
43 self.includepat, im = _buildmatch(pats, '(?:/|$)')
44 if exclude:
44 if exclude:
45 em = _buildmatch(_normalize(exclude, 'glob', root, cwd, auditor),
45 pats = _normalize(exclude, 'glob', root, cwd, auditor)
46 '(?:/|$)')
46 self.excludepat, em = _buildmatch(pats, '(?:/|$)')
47 if exact:
47 if exact:
48 self._files = patterns
48 self._files = patterns
49 pm = self.exact
49 pm = self.exact
50 elif patterns:
50 elif patterns:
51 pats = _normalize(patterns, default, root, cwd, auditor)
51 pats = _normalize(patterns, default, root, cwd, auditor)
52 self._files = _roots(pats)
52 self._files = _roots(pats)
53 self._anypats = self._anypats or _anypats(pats)
53 self._anypats = self._anypats or _anypats(pats)
54 pm = _buildmatch(pats, '$')
54 self.patternspat, pm = _buildmatch(pats, '$')
55
55
56 if patterns or exact:
56 if patterns or exact:
57 if include:
57 if include:
58 if exclude:
58 if exclude:
59 m = lambda f: im(f) and not em(f) and pm(f)
59 m = lambda f: im(f) and not em(f) and pm(f)
60 else:
60 else:
61 m = lambda f: im(f) and pm(f)
61 m = lambda f: im(f) and pm(f)
62 else:
62 else:
63 if exclude:
63 if exclude:
64 m = lambda f: not em(f) and pm(f)
64 m = lambda f: not em(f) and pm(f)
65 else:
65 else:
66 m = pm
66 m = pm
67 else:
67 else:
68 if include:
68 if include:
69 if exclude:
69 if exclude:
70 m = lambda f: im(f) and not em(f)
70 m = lambda f: im(f) and not em(f)
71 else:
71 else:
72 m = im
72 m = im
73 else:
73 else:
74 if exclude:
74 if exclude:
75 m = lambda f: not em(f)
75 m = lambda f: not em(f)
76 else:
76 else:
77 m = lambda f: True
77 m = lambda f: True
78
78
79 self.matchfn = m
79 self.matchfn = m
80 self._fmap = set(self._files)
80 self._fmap = set(self._files)
81
81
82 def __call__(self, fn):
82 def __call__(self, fn):
83 return self.matchfn(fn)
83 return self.matchfn(fn)
84 def __iter__(self):
84 def __iter__(self):
85 for f in self._files:
85 for f in self._files:
86 yield f
86 yield f
87 def bad(self, f, msg):
87 def bad(self, f, msg):
88 '''callback for each explicit file that can't be
88 '''callback for each explicit file that can't be
89 found/accessed, with an error message
89 found/accessed, with an error message
90 '''
90 '''
91 pass
91 pass
92 def dir(self, f):
92 def dir(self, f):
93 pass
93 pass
94 def missing(self, f):
94 def missing(self, f):
95 pass
95 pass
96 def exact(self, f):
96 def exact(self, f):
97 return f in self._fmap
97 return f in self._fmap
98 def rel(self, f):
98 def rel(self, f):
99 return util.pathto(self._root, self._cwd, f)
99 return util.pathto(self._root, self._cwd, f)
100 def files(self):
100 def files(self):
101 return self._files
101 return self._files
102 def anypats(self):
102 def anypats(self):
103 return self._anypats
103 return self._anypats
104
104
105 class exact(match):
105 class exact(match):
106 def __init__(self, root, cwd, files):
106 def __init__(self, root, cwd, files):
107 match.__init__(self, root, cwd, files, exact = True)
107 match.__init__(self, root, cwd, files, exact = True)
108
108
109 class always(match):
109 class always(match):
110 def __init__(self, root, cwd):
110 def __init__(self, root, cwd):
111 match.__init__(self, root, cwd, [])
111 match.__init__(self, root, cwd, [])
112
112
113 class narrowmatcher(match):
113 class narrowmatcher(match):
114 """Adapt a matcher to work on a subdirectory only.
114 """Adapt a matcher to work on a subdirectory only.
115
115
116 The paths are remapped to remove/insert the path as needed:
116 The paths are remapped to remove/insert the path as needed:
117
117
118 >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
118 >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
119 >>> m2 = narrowmatcher('sub', m1)
119 >>> m2 = narrowmatcher('sub', m1)
120 >>> bool(m2('a.txt'))
120 >>> bool(m2('a.txt'))
121 False
121 False
122 >>> bool(m2('b.txt'))
122 >>> bool(m2('b.txt'))
123 True
123 True
124 >>> bool(m2.matchfn('a.txt'))
124 >>> bool(m2.matchfn('a.txt'))
125 False
125 False
126 >>> bool(m2.matchfn('b.txt'))
126 >>> bool(m2.matchfn('b.txt'))
127 True
127 True
128 >>> m2.files()
128 >>> m2.files()
129 ['b.txt']
129 ['b.txt']
130 >>> m2.exact('b.txt')
130 >>> m2.exact('b.txt')
131 True
131 True
132 >>> m2.rel('b.txt')
132 >>> m2.rel('b.txt')
133 'b.txt'
133 'b.txt'
134 >>> def bad(f, msg):
134 >>> def bad(f, msg):
135 ... print "%s: %s" % (f, msg)
135 ... print "%s: %s" % (f, msg)
136 >>> m1.bad = bad
136 >>> m1.bad = bad
137 >>> m2.bad('x.txt', 'No such file')
137 >>> m2.bad('x.txt', 'No such file')
138 sub/x.txt: No such file
138 sub/x.txt: No such file
139 """
139 """
140
140
141 def __init__(self, path, matcher):
141 def __init__(self, path, matcher):
142 self._root = matcher._root
142 self._root = matcher._root
143 self._cwd = matcher._cwd
143 self._cwd = matcher._cwd
144 self._path = path
144 self._path = path
145 self._matcher = matcher
145 self._matcher = matcher
146
146
147 self._files = [f[len(path) + 1:] for f in matcher._files
147 self._files = [f[len(path) + 1:] for f in matcher._files
148 if f.startswith(path + "/")]
148 if f.startswith(path + "/")]
149 self._anypats = matcher._anypats
149 self._anypats = matcher._anypats
150 self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
150 self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
151 self._fmap = set(self._files)
151 self._fmap = set(self._files)
152
152
153 def bad(self, f, msg):
153 def bad(self, f, msg):
154 self._matcher.bad(self._path + "/" + f, msg)
154 self._matcher.bad(self._path + "/" + f, msg)
155
155
156 def patkind(pat):
156 def patkind(pat):
157 return _patsplit(pat, None)[0]
157 return _patsplit(pat, None)[0]
158
158
159 def _patsplit(pat, default):
159 def _patsplit(pat, default):
160 """Split a string into an optional pattern kind prefix and the
160 """Split a string into an optional pattern kind prefix and the
161 actual pattern."""
161 actual pattern."""
162 if ':' in pat:
162 if ':' in pat:
163 kind, val = pat.split(':', 1)
163 kind, val = pat.split(':', 1)
164 if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
164 if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
165 'listfile', 'listfile0'):
165 'listfile', 'listfile0'):
166 return kind, val
166 return kind, val
167 return default, pat
167 return default, pat
168
168
169 def _globre(pat):
169 def _globre(pat):
170 "convert a glob pattern into a regexp"
170 "convert a glob pattern into a regexp"
171 i, n = 0, len(pat)
171 i, n = 0, len(pat)
172 res = ''
172 res = ''
173 group = 0
173 group = 0
174 escape = re.escape
174 escape = re.escape
175 def peek():
175 def peek():
176 return i < n and pat[i]
176 return i < n and pat[i]
177 while i < n:
177 while i < n:
178 c = pat[i]
178 c = pat[i]
179 i += 1
179 i += 1
180 if c not in '*?[{},\\':
180 if c not in '*?[{},\\':
181 res += escape(c)
181 res += escape(c)
182 elif c == '*':
182 elif c == '*':
183 if peek() == '*':
183 if peek() == '*':
184 i += 1
184 i += 1
185 res += '.*'
185 res += '.*'
186 else:
186 else:
187 res += '[^/]*'
187 res += '[^/]*'
188 elif c == '?':
188 elif c == '?':
189 res += '.'
189 res += '.'
190 elif c == '[':
190 elif c == '[':
191 j = i
191 j = i
192 if j < n and pat[j] in '!]':
192 if j < n and pat[j] in '!]':
193 j += 1
193 j += 1
194 while j < n and pat[j] != ']':
194 while j < n and pat[j] != ']':
195 j += 1
195 j += 1
196 if j >= n:
196 if j >= n:
197 res += '\\['
197 res += '\\['
198 else:
198 else:
199 stuff = pat[i:j].replace('\\','\\\\')
199 stuff = pat[i:j].replace('\\','\\\\')
200 i = j + 1
200 i = j + 1
201 if stuff[0] == '!':
201 if stuff[0] == '!':
202 stuff = '^' + stuff[1:]
202 stuff = '^' + stuff[1:]
203 elif stuff[0] == '^':
203 elif stuff[0] == '^':
204 stuff = '\\' + stuff
204 stuff = '\\' + stuff
205 res = '%s[%s]' % (res, stuff)
205 res = '%s[%s]' % (res, stuff)
206 elif c == '{':
206 elif c == '{':
207 group += 1
207 group += 1
208 res += '(?:'
208 res += '(?:'
209 elif c == '}' and group:
209 elif c == '}' and group:
210 res += ')'
210 res += ')'
211 group -= 1
211 group -= 1
212 elif c == ',' and group:
212 elif c == ',' and group:
213 res += '|'
213 res += '|'
214 elif c == '\\':
214 elif c == '\\':
215 p = peek()
215 p = peek()
216 if p:
216 if p:
217 i += 1
217 i += 1
218 res += escape(p)
218 res += escape(p)
219 else:
219 else:
220 res += escape(c)
220 res += escape(c)
221 else:
221 else:
222 res += escape(c)
222 res += escape(c)
223 return res
223 return res
224
224
225 def _regex(kind, name, tail):
225 def _regex(kind, name, tail):
226 '''convert a pattern into a regular expression'''
226 '''convert a pattern into a regular expression'''
227 if not name:
227 if not name:
228 return ''
228 return ''
229 if kind == 're':
229 if kind == 're':
230 return name
230 return name
231 elif kind == 'path':
231 elif kind == 'path':
232 return '^' + re.escape(name) + '(?:/|$)'
232 return '^' + re.escape(name) + '(?:/|$)'
233 elif kind == 'relglob':
233 elif kind == 'relglob':
234 return '(?:|.*/)' + _globre(name) + tail
234 return '(?:|.*/)' + _globre(name) + tail
235 elif kind == 'relpath':
235 elif kind == 'relpath':
236 return re.escape(name) + '(?:/|$)'
236 return re.escape(name) + '(?:/|$)'
237 elif kind == 'relre':
237 elif kind == 'relre':
238 if name.startswith('^'):
238 if name.startswith('^'):
239 return name
239 return name
240 return '.*' + name
240 return '.*' + name
241 return _globre(name) + tail
241 return _globre(name) + tail
242
242
243 def _buildmatch(pats, tail):
243 def _buildmatch(pats, tail):
244 """build a matching function from a set of patterns"""
244 """build a matching function from a set of patterns"""
245 try:
245 try:
246 pat = '(?:%s)' % '|'.join([_regex(k, p, tail) for (k, p) in pats])
246 pat = '(?:%s)' % '|'.join([_regex(k, p, tail) for (k, p) in pats])
247 if len(pat) > 20000:
247 if len(pat) > 20000:
248 raise OverflowError()
248 raise OverflowError()
249 return re.compile(pat).match
249 return pat, re.compile(pat).match
250 except OverflowError:
250 except OverflowError:
251 # We're using a Python with a tiny regex engine and we
251 # We're using a Python with a tiny regex engine and we
252 # made it explode, so we'll divide the pattern list in two
252 # made it explode, so we'll divide the pattern list in two
253 # until it works
253 # until it works
254 l = len(pats)
254 l = len(pats)
255 if l < 2:
255 if l < 2:
256 raise
256 raise
257 a, b = _buildmatch(pats[:l//2], tail), _buildmatch(pats[l//2:], tail)
257 pata, a = _buildmatch(pats[:l//2], tail),
258 return lambda s: a(s) or b(s)
258 patb, b = _buildmatch(pats[l//2:], tail)
259 return pat, lambda s: a(s) or b(s)
259 except re.error:
260 except re.error:
260 for k, p in pats:
261 for k, p in pats:
261 try:
262 try:
262 re.compile('(?:%s)' % _regex(k, p, tail))
263 re.compile('(?:%s)' % _regex(k, p, tail))
263 except re.error:
264 except re.error:
264 raise util.Abort(_("invalid pattern (%s): %s") % (k, p))
265 raise util.Abort(_("invalid pattern (%s): %s") % (k, p))
265 raise util.Abort(_("invalid pattern"))
266 raise util.Abort(_("invalid pattern"))
266
267
267 def _normalize(names, default, root, cwd, auditor):
268 def _normalize(names, default, root, cwd, auditor):
268 pats = []
269 pats = []
269 for kind, name in [_patsplit(p, default) for p in names]:
270 for kind, name in [_patsplit(p, default) for p in names]:
270 if kind in ('glob', 'relpath'):
271 if kind in ('glob', 'relpath'):
271 name = util.canonpath(root, cwd, name, auditor)
272 name = util.canonpath(root, cwd, name, auditor)
272 elif kind in ('relglob', 'path'):
273 elif kind in ('relglob', 'path'):
273 name = util.normpath(name)
274 name = util.normpath(name)
274 elif kind in ('listfile', 'listfile0'):
275 elif kind in ('listfile', 'listfile0'):
275 delimiter = kind == 'listfile0' and '\0' or '\n'
276 delimiter = kind == 'listfile0' and '\0' or '\n'
276 try:
277 try:
277 files = open(name, 'r').read().split(delimiter)
278 files = open(name, 'r').read().split(delimiter)
278 files = [f for f in files if f]
279 files = [f for f in files if f]
279 except EnvironmentError:
280 except EnvironmentError:
280 raise util.Abort(_("unable to read file list (%s)") % name)
281 raise util.Abort(_("unable to read file list (%s)") % name)
281 pats += _normalize(files, default, root, cwd, auditor)
282 pats += _normalize(files, default, root, cwd, auditor)
282 continue
283 continue
283
284
284 pats.append((kind, name))
285 pats.append((kind, name))
285 return pats
286 return pats
286
287
287 def _roots(patterns):
288 def _roots(patterns):
288 r = []
289 r = []
289 for kind, name in patterns:
290 for kind, name in patterns:
290 if kind == 'glob': # find the non-glob prefix
291 if kind == 'glob': # find the non-glob prefix
291 root = []
292 root = []
292 for p in name.split('/'):
293 for p in name.split('/'):
293 if '[' in p or '{' in p or '*' in p or '?' in p:
294 if '[' in p or '{' in p or '*' in p or '?' in p:
294 break
295 break
295 root.append(p)
296 root.append(p)
296 r.append('/'.join(root) or '.')
297 r.append('/'.join(root) or '.')
297 elif kind in ('relpath', 'path'):
298 elif kind in ('relpath', 'path'):
298 r.append(name or '.')
299 r.append(name or '.')
299 elif kind == 'relglob':
300 elif kind == 'relglob':
300 r.append('.')
301 r.append('.')
301 return r
302 return r
302
303
303 def _anypats(patterns):
304 def _anypats(patterns):
304 for kind, name in patterns:
305 for kind, name in patterns:
305 if kind in ('glob', 're', 'relglob', 'relre'):
306 if kind in ('glob', 're', 'relglob', 'relre'):
306 return True
307 return True
@@ -1,251 +1,253
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 copy
16 copy
17 diff
17 diff
18 export
18 export
19 forget
19 forget
20 grep
20 grep
21 heads
21 heads
22 help
22 help
23 identify
23 identify
24 import
24 import
25 incoming
25 incoming
26 init
26 init
27 locate
27 locate
28 log
28 log
29 manifest
29 manifest
30 merge
30 merge
31 outgoing
31 outgoing
32 parents
32 parents
33 paths
33 paths
34 pull
34 pull
35 push
35 push
36 recover
36 recover
37 remove
37 remove
38 rename
38 rename
39 resolve
39 resolve
40 revert
40 revert
41 rollback
41 rollback
42 root
42 root
43 serve
43 serve
44 showconfig
44 showconfig
45 status
45 status
46 summary
46 summary
47 tag
47 tag
48 tags
48 tags
49 tip
49 tip
50 unbundle
50 unbundle
51 update
51 update
52 verify
52 verify
53 version
53 version
54
54
55 Show all commands that start with "a"
55 Show all commands that start with "a"
56 $ hg debugcomplete a
56 $ hg debugcomplete a
57 add
57 add
58 addremove
58 addremove
59 annotate
59 annotate
60 archive
60 archive
61
61
62 Do not show debug commands if there are other candidates
62 Do not show debug commands if there are other candidates
63 $ hg debugcomplete d
63 $ hg debugcomplete d
64 diff
64 diff
65
65
66 Show debug commands if there are no other candidates
66 Show debug commands if there are no other candidates
67 $ hg debugcomplete debug
67 $ hg debugcomplete debug
68 debugancestor
68 debugancestor
69 debugbuilddag
69 debugbuilddag
70 debugcheckstate
70 debugcheckstate
71 debugcommands
71 debugcommands
72 debugcomplete
72 debugcomplete
73 debugconfig
73 debugconfig
74 debugdag
74 debugdag
75 debugdata
75 debugdata
76 debugdate
76 debugdate
77 debugfsinfo
77 debugfsinfo
78 debugignore
78 debugindex
79 debugindex
79 debugindexdot
80 debugindexdot
80 debuginstall
81 debuginstall
81 debugpushkey
82 debugpushkey
82 debugrebuildstate
83 debugrebuildstate
83 debugrename
84 debugrename
84 debugrevspec
85 debugrevspec
85 debugsetparents
86 debugsetparents
86 debugstate
87 debugstate
87 debugsub
88 debugsub
88 debugwalk
89 debugwalk
89
90
90 Do not show the alias of a debug command if there are other candidates
91 Do not show the alias of a debug command if there are other candidates
91 (this should hide rawcommit)
92 (this should hide rawcommit)
92 $ hg debugcomplete r
93 $ hg debugcomplete r
93 recover
94 recover
94 remove
95 remove
95 rename
96 rename
96 resolve
97 resolve
97 revert
98 revert
98 rollback
99 rollback
99 root
100 root
100 Show the alias of a debug command if there are no other candidates
101 Show the alias of a debug command if there are no other candidates
101 $ hg debugcomplete rawc
102 $ hg debugcomplete rawc
102
103
103
104
104 Show the global options
105 Show the global options
105 $ hg debugcomplete --options | sort
106 $ hg debugcomplete --options | sort
106 --config
107 --config
107 --cwd
108 --cwd
108 --debug
109 --debug
109 --debugger
110 --debugger
110 --encoding
111 --encoding
111 --encodingmode
112 --encodingmode
112 --help
113 --help
113 --noninteractive
114 --noninteractive
114 --profile
115 --profile
115 --quiet
116 --quiet
116 --repository
117 --repository
117 --time
118 --time
118 --traceback
119 --traceback
119 --verbose
120 --verbose
120 --version
121 --version
121 -R
122 -R
122 -h
123 -h
123 -q
124 -q
124 -v
125 -v
125 -y
126 -y
126
127
127 Show the options for the "serve" command
128 Show the options for the "serve" command
128 $ hg debugcomplete --options serve | sort
129 $ hg debugcomplete --options serve | sort
129 --accesslog
130 --accesslog
130 --address
131 --address
131 --certificate
132 --certificate
132 --config
133 --config
133 --cwd
134 --cwd
134 --daemon
135 --daemon
135 --daemon-pipefds
136 --daemon-pipefds
136 --debug
137 --debug
137 --debugger
138 --debugger
138 --encoding
139 --encoding
139 --encodingmode
140 --encodingmode
140 --errorlog
141 --errorlog
141 --help
142 --help
142 --ipv6
143 --ipv6
143 --name
144 --name
144 --noninteractive
145 --noninteractive
145 --pid-file
146 --pid-file
146 --port
147 --port
147 --prefix
148 --prefix
148 --profile
149 --profile
149 --quiet
150 --quiet
150 --repository
151 --repository
151 --stdio
152 --stdio
152 --style
153 --style
153 --templates
154 --templates
154 --time
155 --time
155 --traceback
156 --traceback
156 --verbose
157 --verbose
157 --version
158 --version
158 --web-conf
159 --web-conf
159 -6
160 -6
160 -A
161 -A
161 -E
162 -E
162 -R
163 -R
163 -a
164 -a
164 -d
165 -d
165 -h
166 -h
166 -n
167 -n
167 -p
168 -p
168 -q
169 -q
169 -t
170 -t
170 -v
171 -v
171 -y
172 -y
172
173
173 Show an error if we use --options with an ambiguous abbreviation
174 Show an error if we use --options with an ambiguous abbreviation
174 $ hg debugcomplete --options s
175 $ hg debugcomplete --options s
175 hg: command 's' is ambiguous:
176 hg: command 's' is ambiguous:
176 serve showconfig status summary
177 serve showconfig status summary
177 [255]
178 [255]
178
179
179 Show all commands + options
180 Show all commands + options
180 $ hg debugcommands
181 $ hg debugcommands
181 add: include, exclude, subrepos, dry-run
182 add: include, exclude, subrepos, dry-run
182 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
183 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
183 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
184 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
184 commit: addremove, close-branch, include, exclude, message, logfile, date, user
185 commit: addremove, close-branch, include, exclude, message, logfile, date, user
185 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
186 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
186 export: output, switch-parent, rev, text, git, nodates
187 export: output, switch-parent, rev, text, git, nodates
187 forget: include, exclude
188 forget: include, exclude
188 init: ssh, remotecmd, insecure
189 init: ssh, remotecmd, insecure
189 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
190 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
190 merge: force, tool, rev, preview
191 merge: force, tool, rev, preview
191 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
192 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
192 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
193 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
193 remove: after, force, include, exclude
194 remove: after, force, include, exclude
194 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
195 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
195 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
196 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
196 summary: remote
197 summary: remote
197 update: clean, check, date, rev
198 update: clean, check, date, rev
198 addremove: similarity, include, exclude, dry-run
199 addremove: similarity, include, exclude, dry-run
199 archive: no-decode, prefix, rev, type, subrepos, include, exclude
200 archive: no-decode, prefix, rev, type, subrepos, include, exclude
200 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
201 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
201 bisect: reset, good, bad, skip, command, noupdate
202 bisect: reset, good, bad, skip, command, noupdate
202 bookmarks: force, rev, delete, rename
203 bookmarks: force, rev, delete, rename
203 branch: force, clean
204 branch: force, clean
204 branches: active, closed
205 branches: active, closed
205 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
206 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
206 cat: output, rev, decode, include, exclude
207 cat: output, rev, decode, include, exclude
207 copy: after, force, include, exclude, dry-run
208 copy: after, force, include, exclude, dry-run
208 debugancestor:
209 debugancestor:
209 debugbuilddag: mergeable-file, appended-file, overwritten-file, new-file
210 debugbuilddag: mergeable-file, appended-file, overwritten-file, new-file
210 debugcheckstate:
211 debugcheckstate:
211 debugcommands:
212 debugcommands:
212 debugcomplete: options
213 debugcomplete: options
213 debugdag: tags, branches, dots, spaces
214 debugdag: tags, branches, dots, spaces
214 debugdata:
215 debugdata:
215 debugdate: extended
216 debugdate: extended
216 debugfsinfo:
217 debugfsinfo:
218 debugignore:
217 debugindex: format
219 debugindex: format
218 debugindexdot:
220 debugindexdot:
219 debuginstall:
221 debuginstall:
220 debugpushkey:
222 debugpushkey:
221 debugrebuildstate: rev
223 debugrebuildstate: rev
222 debugrename: rev
224 debugrename: rev
223 debugrevspec:
225 debugrevspec:
224 debugsetparents:
226 debugsetparents:
225 debugstate: nodates
227 debugstate: nodates
226 debugsub: rev
228 debugsub: rev
227 debugwalk: include, exclude
229 debugwalk: include, exclude
228 grep: print0, all, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
230 grep: print0, all, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
229 heads: rev, topo, active, closed, style, template
231 heads: rev, topo, active, closed, style, template
230 help:
232 help:
231 identify: rev, num, id, branch, tags
233 identify: rev, num, id, branch, tags
232 import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
234 import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
233 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
235 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
234 locate: rev, print0, fullpath, include, exclude
236 locate: rev, print0, fullpath, include, exclude
235 manifest: rev
237 manifest: rev
236 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
238 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
237 parents: rev, style, template
239 parents: rev, style, template
238 paths:
240 paths:
239 recover:
241 recover:
240 rename: after, force, include, exclude, dry-run
242 rename: after, force, include, exclude, dry-run
241 resolve: all, list, mark, unmark, tool, no-status, include, exclude
243 resolve: all, list, mark, unmark, tool, no-status, include, exclude
242 revert: all, date, rev, no-backup, include, exclude, dry-run
244 revert: all, date, rev, no-backup, include, exclude, dry-run
243 rollback: dry-run
245 rollback: dry-run
244 root:
246 root:
245 showconfig: untrusted
247 showconfig: untrusted
246 tag: force, local, rev, remove, edit, message, date, user
248 tag: force, local, rev, remove, edit, message, date, user
247 tags:
249 tags:
248 tip: patch, git, style, template
250 tip: patch, git, style, template
249 unbundle: update
251 unbundle: update
250 verify:
252 verify:
251 version:
253 version:
@@ -1,122 +1,124
1 $ hg init
1 $ hg init
2
2
3 Issue562: .hgignore requires newline at end:
3 Issue562: .hgignore requires newline at end:
4
4
5 $ touch foo
5 $ touch foo
6 $ touch bar
6 $ touch bar
7 $ touch baz
7 $ touch baz
8 $ cat > makeignore.py <<EOF
8 $ cat > makeignore.py <<EOF
9 > f = open(".hgignore", "w")
9 > f = open(".hgignore", "w")
10 > f.write("ignore\n")
10 > f.write("ignore\n")
11 > f.write("foo\n")
11 > f.write("foo\n")
12 > # No EOL here
12 > # No EOL here
13 > f.write("bar")
13 > f.write("bar")
14 > f.close()
14 > f.close()
15 > EOF
15 > EOF
16
16
17 $ python makeignore.py
17 $ python makeignore.py
18
18
19 Should display baz only:
19 Should display baz only:
20
20
21 $ hg status
21 $ hg status
22 ? baz
22 ? baz
23
23
24 $ rm foo bar baz .hgignore makeignore.py
24 $ rm foo bar baz .hgignore makeignore.py
25
25
26 $ touch a.o
26 $ touch a.o
27 $ touch a.c
27 $ touch a.c
28 $ touch syntax
28 $ touch syntax
29 $ mkdir dir
29 $ mkdir dir
30 $ touch dir/a.o
30 $ touch dir/a.o
31 $ touch dir/b.o
31 $ touch dir/b.o
32 $ touch dir/c.o
32 $ touch dir/c.o
33
33
34 $ hg add dir/a.o
34 $ hg add dir/a.o
35 $ hg commit -m 0
35 $ hg commit -m 0
36 $ hg add dir/b.o
36 $ hg add dir/b.o
37
37
38 $ hg status
38 $ hg status
39 A dir/b.o
39 A dir/b.o
40 ? a.c
40 ? a.c
41 ? a.o
41 ? a.o
42 ? dir/c.o
42 ? dir/c.o
43 ? syntax
43 ? syntax
44
44
45 $ echo "*.o" > .hgignore
45 $ echo "*.o" > .hgignore
46 $ hg status
46 $ hg status
47 abort: $TESTTMP/.hgignore: invalid pattern (relre): *.o
47 abort: $TESTTMP/.hgignore: invalid pattern (relre): *.o
48 [255]
48 [255]
49
49
50 $ echo ".*\.o" > .hgignore
50 $ echo ".*\.o" > .hgignore
51 $ hg status
51 $ hg status
52 A dir/b.o
52 A dir/b.o
53 ? .hgignore
53 ? .hgignore
54 ? a.c
54 ? a.c
55 ? syntax
55 ? syntax
56
56
57 Check it does not ignore the current directory '.':
57 Check it does not ignore the current directory '.':
58
58
59 $ echo "^\." > .hgignore
59 $ echo "^\." > .hgignore
60 $ hg status
60 $ hg status
61 A dir/b.o
61 A dir/b.o
62 ? a.c
62 ? a.c
63 ? a.o
63 ? a.o
64 ? dir/c.o
64 ? dir/c.o
65 ? syntax
65 ? syntax
66
66
67 $ echo "glob:**.o" > .hgignore
67 $ echo "glob:**.o" > .hgignore
68 $ hg status
68 $ hg status
69 A dir/b.o
69 A dir/b.o
70 ? .hgignore
70 ? .hgignore
71 ? a.c
71 ? a.c
72 ? syntax
72 ? syntax
73
73
74 $ echo "glob:*.o" > .hgignore
74 $ echo "glob:*.o" > .hgignore
75 $ hg status
75 $ hg status
76 A dir/b.o
76 A dir/b.o
77 ? .hgignore
77 ? .hgignore
78 ? a.c
78 ? a.c
79 ? syntax
79 ? syntax
80
80
81 $ echo "syntax: glob" > .hgignore
81 $ echo "syntax: glob" > .hgignore
82 $ echo "re:.*\.o" >> .hgignore
82 $ echo "re:.*\.o" >> .hgignore
83 $ hg status
83 $ hg status
84 A dir/b.o
84 A dir/b.o
85 ? .hgignore
85 ? .hgignore
86 ? a.c
86 ? a.c
87 ? syntax
87 ? syntax
88
88
89 $ echo "syntax: invalid" > .hgignore
89 $ echo "syntax: invalid" > .hgignore
90 $ hg status
90 $ hg status
91 $TESTTMP/.hgignore: ignoring invalid syntax 'invalid'
91 $TESTTMP/.hgignore: ignoring invalid syntax 'invalid'
92 A dir/b.o
92 A dir/b.o
93 ? .hgignore
93 ? .hgignore
94 ? a.c
94 ? a.c
95 ? a.o
95 ? a.o
96 ? dir/c.o
96 ? dir/c.o
97 ? syntax
97 ? syntax
98
98
99 $ echo "syntax: glob" > .hgignore
99 $ echo "syntax: glob" > .hgignore
100 $ echo "*.o" >> .hgignore
100 $ echo "*.o" >> .hgignore
101 $ hg status
101 $ hg status
102 A dir/b.o
102 A dir/b.o
103 ? .hgignore
103 ? .hgignore
104 ? a.c
104 ? a.c
105 ? syntax
105 ? syntax
106
106
107 $ echo "relglob:syntax*" > .hgignore
107 $ echo "relglob:syntax*" > .hgignore
108 $ hg status
108 $ hg status
109 A dir/b.o
109 A dir/b.o
110 ? .hgignore
110 ? .hgignore
111 ? a.c
111 ? a.c
112 ? a.o
112 ? a.o
113 ? dir/c.o
113 ? dir/c.o
114
114
115 $ echo "relglob:*" > .hgignore
115 $ echo "relglob:*" > .hgignore
116 $ hg status
116 $ hg status
117 A dir/b.o
117 A dir/b.o
118
118
119 $ cd dir
119 $ cd dir
120 $ hg status .
120 $ hg status .
121 A b.o
121 A b.o
122
122
123 $ hg debugignore
124 (?:(?:|.*/)[^/]*(?:/|$))
General Comments 0
You need to be logged in to leave comments. Login now