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