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