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