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