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