##// END OF EJS Templates
commands: fix typo
Martin Geisler -
r10830:82431002 default
parent child Browse files
Show More
@@ -1,3901 +1,3901 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 if stat:
1177 if stat:
1178 it = patch.diff(repo, node1, node2, match=m, opts=diffopts)
1178 it = patch.diff(repo, node1, node2, match=m, opts=diffopts)
1179 width = ui.interactive() and util.termwidth() or 80
1179 width = ui.interactive() and util.termwidth() or 80
1180 for chunk, label in patch.diffstatui(util.iterlines(it), width=width,
1180 for chunk, label in patch.diffstatui(util.iterlines(it), width=width,
1181 git=diffopts.git):
1181 git=diffopts.git):
1182 ui.write(chunk, label=label)
1182 ui.write(chunk, label=label)
1183 else:
1183 else:
1184 it = patch.diffui(repo, node1, node2, match=m, opts=diffopts)
1184 it = patch.diffui(repo, node1, node2, match=m, opts=diffopts)
1185 for chunk, label in it:
1185 for chunk, label in it:
1186 ui.write(chunk, label=label)
1186 ui.write(chunk, label=label)
1187
1187
1188 def export(ui, repo, *changesets, **opts):
1188 def export(ui, repo, *changesets, **opts):
1189 """dump the header and diffs for one or more changesets
1189 """dump the header and diffs for one or more changesets
1190
1190
1191 Print the changeset header and diffs for one or more revisions.
1191 Print the changeset header and diffs for one or more revisions.
1192
1192
1193 The information shown in the changeset header is: author, date,
1193 The information shown in the changeset header is: author, date,
1194 branch name (if non-default), changeset hash, parent(s) and commit
1194 branch name (if non-default), changeset hash, parent(s) and commit
1195 comment.
1195 comment.
1196
1196
1197 NOTE: export may generate unexpected diff output for merge
1197 NOTE: export may generate unexpected diff output for merge
1198 changesets, as it will compare the merge changeset against its
1198 changesets, as it will compare the merge changeset against its
1199 first parent only.
1199 first parent only.
1200
1200
1201 Output may be to a file, in which case the name of the file is
1201 Output may be to a file, in which case the name of the file is
1202 given using a format string. The formatting rules are as follows:
1202 given using a format string. The formatting rules are as follows:
1203
1203
1204 :``%%``: literal "%" character
1204 :``%%``: literal "%" character
1205 :``%H``: changeset hash (40 bytes of hexadecimal)
1205 :``%H``: changeset hash (40 bytes of hexadecimal)
1206 :``%N``: number of patches being generated
1206 :``%N``: number of patches being generated
1207 :``%R``: changeset revision number
1207 :``%R``: changeset revision number
1208 :``%b``: basename of the exporting repository
1208 :``%b``: basename of the exporting repository
1209 :``%h``: short-form changeset hash (12 bytes of hexadecimal)
1209 :``%h``: short-form changeset hash (12 bytes of hexadecimal)
1210 :``%n``: zero-padded sequence number, starting at 1
1210 :``%n``: zero-padded sequence number, starting at 1
1211 :``%r``: zero-padded changeset revision number
1211 :``%r``: zero-padded changeset revision number
1212
1212
1213 Without the -a/--text option, export will avoid generating diffs
1213 Without the -a/--text option, export will avoid generating diffs
1214 of files it detects as binary. With -a, export will generate a
1214 of files it detects as binary. With -a, export will generate a
1215 diff anyway, probably with undesirable results.
1215 diff anyway, probably with undesirable results.
1216
1216
1217 Use the -g/--git option to generate diffs in the git extended diff
1217 Use the -g/--git option to generate diffs in the git extended diff
1218 format. See 'hg help diffs' for more information.
1218 format. See 'hg help diffs' for more information.
1219
1219
1220 With the --switch-parent option, the diff will be against the
1220 With the --switch-parent option, the diff will be against the
1221 second parent. It can be useful to review a merge.
1221 second parent. It can be useful to review a merge.
1222 """
1222 """
1223 changesets += tuple(opts.get('rev', []))
1223 changesets += tuple(opts.get('rev', []))
1224 if not changesets:
1224 if not changesets:
1225 raise util.Abort(_("export requires at least one changeset"))
1225 raise util.Abort(_("export requires at least one changeset"))
1226 revs = cmdutil.revrange(repo, changesets)
1226 revs = cmdutil.revrange(repo, changesets)
1227 if len(revs) > 1:
1227 if len(revs) > 1:
1228 ui.note(_('exporting patches:\n'))
1228 ui.note(_('exporting patches:\n'))
1229 else:
1229 else:
1230 ui.note(_('exporting patch:\n'))
1230 ui.note(_('exporting patch:\n'))
1231 cmdutil.export(repo, revs, template=opts.get('output'),
1231 cmdutil.export(repo, revs, template=opts.get('output'),
1232 switch_parent=opts.get('switch_parent'),
1232 switch_parent=opts.get('switch_parent'),
1233 opts=patch.diffopts(ui, opts))
1233 opts=patch.diffopts(ui, opts))
1234
1234
1235 def forget(ui, repo, *pats, **opts):
1235 def forget(ui, repo, *pats, **opts):
1236 """forget the specified files on the next commit
1236 """forget the specified files on the next commit
1237
1237
1238 Mark the specified files so they will no longer be tracked
1238 Mark the specified files so they will no longer be tracked
1239 after the next commit.
1239 after the next commit.
1240
1240
1241 This only removes files from the current branch, not from the
1241 This only removes files from the current branch, not from the
1242 entire project history, and it does not delete them from the
1242 entire project history, and it does not delete them from the
1243 working directory.
1243 working directory.
1244
1244
1245 To undo a forget before the next commit, see hg add.
1245 To undo a forget before the next commit, see hg add.
1246 """
1246 """
1247
1247
1248 if not pats:
1248 if not pats:
1249 raise util.Abort(_('no files specified'))
1249 raise util.Abort(_('no files specified'))
1250
1250
1251 m = cmdutil.match(repo, pats, opts)
1251 m = cmdutil.match(repo, pats, opts)
1252 s = repo.status(match=m, clean=True)
1252 s = repo.status(match=m, clean=True)
1253 forget = sorted(s[0] + s[1] + s[3] + s[6])
1253 forget = sorted(s[0] + s[1] + s[3] + s[6])
1254
1254
1255 for f in m.files():
1255 for f in m.files():
1256 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1256 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1257 ui.warn(_('not removing %s: file is already untracked\n')
1257 ui.warn(_('not removing %s: file is already untracked\n')
1258 % m.rel(f))
1258 % m.rel(f))
1259
1259
1260 for f in forget:
1260 for f in forget:
1261 if ui.verbose or not m.exact(f):
1261 if ui.verbose or not m.exact(f):
1262 ui.status(_('removing %s\n') % m.rel(f))
1262 ui.status(_('removing %s\n') % m.rel(f))
1263
1263
1264 repo.remove(forget, unlink=False)
1264 repo.remove(forget, unlink=False)
1265
1265
1266 def grep(ui, repo, pattern, *pats, **opts):
1266 def grep(ui, repo, pattern, *pats, **opts):
1267 """search for a pattern in specified files and revisions
1267 """search for a pattern in specified files and revisions
1268
1268
1269 Search revisions of files for a regular expression.
1269 Search revisions of files for a regular expression.
1270
1270
1271 This command behaves differently than Unix grep. It only accepts
1271 This command behaves differently than Unix grep. It only accepts
1272 Python/Perl regexps. It searches repository history, not the
1272 Python/Perl regexps. It searches repository history, not the
1273 working directory. It always prints the revision number in which a
1273 working directory. It always prints the revision number in which a
1274 match appears.
1274 match appears.
1275
1275
1276 By default, grep only prints output for the first revision of a
1276 By default, grep only prints output for the first revision of a
1277 file in which it finds a match. To get it to print every revision
1277 file in which it finds a match. To get it to print every revision
1278 that contains a change in match status ("-" for a match that
1278 that contains a change in match status ("-" for a match that
1279 becomes a non-match, or "+" for a non-match that becomes a match),
1279 becomes a non-match, or "+" for a non-match that becomes a match),
1280 use the --all flag.
1280 use the --all flag.
1281 """
1281 """
1282 reflags = 0
1282 reflags = 0
1283 if opts.get('ignore_case'):
1283 if opts.get('ignore_case'):
1284 reflags |= re.I
1284 reflags |= re.I
1285 try:
1285 try:
1286 regexp = re.compile(pattern, reflags)
1286 regexp = re.compile(pattern, reflags)
1287 except Exception, inst:
1287 except Exception, inst:
1288 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1288 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1289 return None
1289 return None
1290 sep, eol = ':', '\n'
1290 sep, eol = ':', '\n'
1291 if opts.get('print0'):
1291 if opts.get('print0'):
1292 sep = eol = '\0'
1292 sep = eol = '\0'
1293
1293
1294 getfile = util.lrucachefunc(repo.file)
1294 getfile = util.lrucachefunc(repo.file)
1295
1295
1296 def matchlines(body):
1296 def matchlines(body):
1297 begin = 0
1297 begin = 0
1298 linenum = 0
1298 linenum = 0
1299 while True:
1299 while True:
1300 match = regexp.search(body, begin)
1300 match = regexp.search(body, begin)
1301 if not match:
1301 if not match:
1302 break
1302 break
1303 mstart, mend = match.span()
1303 mstart, mend = match.span()
1304 linenum += body.count('\n', begin, mstart) + 1
1304 linenum += body.count('\n', begin, mstart) + 1
1305 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1305 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1306 begin = body.find('\n', mend) + 1 or len(body)
1306 begin = body.find('\n', mend) + 1 or len(body)
1307 lend = begin - 1
1307 lend = begin - 1
1308 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1308 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1309
1309
1310 class linestate(object):
1310 class linestate(object):
1311 def __init__(self, line, linenum, colstart, colend):
1311 def __init__(self, line, linenum, colstart, colend):
1312 self.line = line
1312 self.line = line
1313 self.linenum = linenum
1313 self.linenum = linenum
1314 self.colstart = colstart
1314 self.colstart = colstart
1315 self.colend = colend
1315 self.colend = colend
1316
1316
1317 def __hash__(self):
1317 def __hash__(self):
1318 return hash((self.linenum, self.line))
1318 return hash((self.linenum, self.line))
1319
1319
1320 def __eq__(self, other):
1320 def __eq__(self, other):
1321 return self.line == other.line
1321 return self.line == other.line
1322
1322
1323 matches = {}
1323 matches = {}
1324 copies = {}
1324 copies = {}
1325 def grepbody(fn, rev, body):
1325 def grepbody(fn, rev, body):
1326 matches[rev].setdefault(fn, [])
1326 matches[rev].setdefault(fn, [])
1327 m = matches[rev][fn]
1327 m = matches[rev][fn]
1328 for lnum, cstart, cend, line in matchlines(body):
1328 for lnum, cstart, cend, line in matchlines(body):
1329 s = linestate(line, lnum, cstart, cend)
1329 s = linestate(line, lnum, cstart, cend)
1330 m.append(s)
1330 m.append(s)
1331
1331
1332 def difflinestates(a, b):
1332 def difflinestates(a, b):
1333 sm = difflib.SequenceMatcher(None, a, b)
1333 sm = difflib.SequenceMatcher(None, a, b)
1334 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1334 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1335 if tag == 'insert':
1335 if tag == 'insert':
1336 for i in xrange(blo, bhi):
1336 for i in xrange(blo, bhi):
1337 yield ('+', b[i])
1337 yield ('+', b[i])
1338 elif tag == 'delete':
1338 elif tag == 'delete':
1339 for i in xrange(alo, ahi):
1339 for i in xrange(alo, ahi):
1340 yield ('-', a[i])
1340 yield ('-', a[i])
1341 elif tag == 'replace':
1341 elif tag == 'replace':
1342 for i in xrange(alo, ahi):
1342 for i in xrange(alo, ahi):
1343 yield ('-', a[i])
1343 yield ('-', a[i])
1344 for i in xrange(blo, bhi):
1344 for i in xrange(blo, bhi):
1345 yield ('+', b[i])
1345 yield ('+', b[i])
1346
1346
1347 def display(fn, ctx, pstates, states):
1347 def display(fn, ctx, pstates, states):
1348 rev = ctx.rev()
1348 rev = ctx.rev()
1349 datefunc = ui.quiet and util.shortdate or util.datestr
1349 datefunc = ui.quiet and util.shortdate or util.datestr
1350 found = False
1350 found = False
1351 filerevmatches = {}
1351 filerevmatches = {}
1352 if opts.get('all'):
1352 if opts.get('all'):
1353 iter = difflinestates(pstates, states)
1353 iter = difflinestates(pstates, states)
1354 else:
1354 else:
1355 iter = [('', l) for l in states]
1355 iter = [('', l) for l in states]
1356 for change, l in iter:
1356 for change, l in iter:
1357 cols = [fn, str(rev)]
1357 cols = [fn, str(rev)]
1358 before, match, after = None, None, None
1358 before, match, after = None, None, None
1359 if opts.get('line_number'):
1359 if opts.get('line_number'):
1360 cols.append(str(l.linenum))
1360 cols.append(str(l.linenum))
1361 if opts.get('all'):
1361 if opts.get('all'):
1362 cols.append(change)
1362 cols.append(change)
1363 if opts.get('user'):
1363 if opts.get('user'):
1364 cols.append(ui.shortuser(ctx.user()))
1364 cols.append(ui.shortuser(ctx.user()))
1365 if opts.get('date'):
1365 if opts.get('date'):
1366 cols.append(datefunc(ctx.date()))
1366 cols.append(datefunc(ctx.date()))
1367 if opts.get('files_with_matches'):
1367 if opts.get('files_with_matches'):
1368 c = (fn, rev)
1368 c = (fn, rev)
1369 if c in filerevmatches:
1369 if c in filerevmatches:
1370 continue
1370 continue
1371 filerevmatches[c] = 1
1371 filerevmatches[c] = 1
1372 else:
1372 else:
1373 before = l.line[:l.colstart]
1373 before = l.line[:l.colstart]
1374 match = l.line[l.colstart:l.colend]
1374 match = l.line[l.colstart:l.colend]
1375 after = l.line[l.colend:]
1375 after = l.line[l.colend:]
1376 ui.write(sep.join(cols))
1376 ui.write(sep.join(cols))
1377 if before is not None:
1377 if before is not None:
1378 ui.write(sep + before)
1378 ui.write(sep + before)
1379 ui.write(match, label='grep.match')
1379 ui.write(match, label='grep.match')
1380 ui.write(after)
1380 ui.write(after)
1381 ui.write(eol)
1381 ui.write(eol)
1382 found = True
1382 found = True
1383 return found
1383 return found
1384
1384
1385 skip = {}
1385 skip = {}
1386 revfiles = {}
1386 revfiles = {}
1387 matchfn = cmdutil.match(repo, pats, opts)
1387 matchfn = cmdutil.match(repo, pats, opts)
1388 found = False
1388 found = False
1389 follow = opts.get('follow')
1389 follow = opts.get('follow')
1390
1390
1391 def prep(ctx, fns):
1391 def prep(ctx, fns):
1392 rev = ctx.rev()
1392 rev = ctx.rev()
1393 pctx = ctx.parents()[0]
1393 pctx = ctx.parents()[0]
1394 parent = pctx.rev()
1394 parent = pctx.rev()
1395 matches.setdefault(rev, {})
1395 matches.setdefault(rev, {})
1396 matches.setdefault(parent, {})
1396 matches.setdefault(parent, {})
1397 files = revfiles.setdefault(rev, [])
1397 files = revfiles.setdefault(rev, [])
1398 for fn in fns:
1398 for fn in fns:
1399 flog = getfile(fn)
1399 flog = getfile(fn)
1400 try:
1400 try:
1401 fnode = ctx.filenode(fn)
1401 fnode = ctx.filenode(fn)
1402 except error.LookupError:
1402 except error.LookupError:
1403 continue
1403 continue
1404
1404
1405 copied = flog.renamed(fnode)
1405 copied = flog.renamed(fnode)
1406 copy = follow and copied and copied[0]
1406 copy = follow and copied and copied[0]
1407 if copy:
1407 if copy:
1408 copies.setdefault(rev, {})[fn] = copy
1408 copies.setdefault(rev, {})[fn] = copy
1409 if fn in skip:
1409 if fn in skip:
1410 if copy:
1410 if copy:
1411 skip[copy] = True
1411 skip[copy] = True
1412 continue
1412 continue
1413 files.append(fn)
1413 files.append(fn)
1414
1414
1415 if fn not in matches[rev]:
1415 if fn not in matches[rev]:
1416 grepbody(fn, rev, flog.read(fnode))
1416 grepbody(fn, rev, flog.read(fnode))
1417
1417
1418 pfn = copy or fn
1418 pfn = copy or fn
1419 if pfn not in matches[parent]:
1419 if pfn not in matches[parent]:
1420 try:
1420 try:
1421 fnode = pctx.filenode(pfn)
1421 fnode = pctx.filenode(pfn)
1422 grepbody(pfn, parent, flog.read(fnode))
1422 grepbody(pfn, parent, flog.read(fnode))
1423 except error.LookupError:
1423 except error.LookupError:
1424 pass
1424 pass
1425
1425
1426 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1426 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1427 rev = ctx.rev()
1427 rev = ctx.rev()
1428 parent = ctx.parents()[0].rev()
1428 parent = ctx.parents()[0].rev()
1429 for fn in sorted(revfiles.get(rev, [])):
1429 for fn in sorted(revfiles.get(rev, [])):
1430 states = matches[rev][fn]
1430 states = matches[rev][fn]
1431 copy = copies.get(rev, {}).get(fn)
1431 copy = copies.get(rev, {}).get(fn)
1432 if fn in skip:
1432 if fn in skip:
1433 if copy:
1433 if copy:
1434 skip[copy] = True
1434 skip[copy] = True
1435 continue
1435 continue
1436 pstates = matches.get(parent, {}).get(copy or fn, [])
1436 pstates = matches.get(parent, {}).get(copy or fn, [])
1437 if pstates or states:
1437 if pstates or states:
1438 r = display(fn, ctx, pstates, states)
1438 r = display(fn, ctx, pstates, states)
1439 found = found or r
1439 found = found or r
1440 if r and not opts.get('all'):
1440 if r and not opts.get('all'):
1441 skip[fn] = True
1441 skip[fn] = True
1442 if copy:
1442 if copy:
1443 skip[copy] = True
1443 skip[copy] = True
1444 del matches[rev]
1444 del matches[rev]
1445 del revfiles[rev]
1445 del revfiles[rev]
1446
1446
1447 def heads(ui, repo, *branchrevs, **opts):
1447 def heads(ui, repo, *branchrevs, **opts):
1448 """show current repository heads or show branch heads
1448 """show current repository heads or show branch heads
1449
1449
1450 With no arguments, show all repository branch heads.
1450 With no arguments, show all repository branch heads.
1451
1451
1452 Repository "heads" are changesets with no child changesets. They are
1452 Repository "heads" are changesets with no child changesets. They are
1453 where development generally takes place and are the usual targets
1453 where development generally takes place and are the usual targets
1454 for update and merge operations. Branch heads are changesets that have
1454 for update and merge operations. Branch heads are changesets that have
1455 no child changeset on the same branch.
1455 no child changeset on the same branch.
1456
1456
1457 If one or more REVs are given, only branch heads on the branches
1457 If one or more REVs are given, only branch heads on the branches
1458 associated with the specified changesets are shown.
1458 associated with the specified changesets are shown.
1459
1459
1460 If -c/--closed is specified, also show branch heads marked closed
1460 If -c/--closed is specified, also show branch heads marked closed
1461 (see hg commit --close-branch).
1461 (see hg commit --close-branch).
1462
1462
1463 If STARTREV is specified, only those heads that are descendants of
1463 If STARTREV is specified, only those heads that are descendants of
1464 STARTREV will be displayed.
1464 STARTREV will be displayed.
1465
1465
1466 If -t/--topo is specified, named branch mechanics will be ignored and only
1466 If -t/--topo is specified, named branch mechanics will be ignored and only
1467 changesets without children will be shown.
1467 changesets without children will be shown.
1468 """
1468 """
1469
1469
1470 if opts.get('rev'):
1470 if opts.get('rev'):
1471 start = repo.lookup(opts['rev'])
1471 start = repo.lookup(opts['rev'])
1472 else:
1472 else:
1473 start = None
1473 start = None
1474
1474
1475 if opts.get('topo'):
1475 if opts.get('topo'):
1476 heads = [repo[h] for h in repo.heads(start)]
1476 heads = [repo[h] for h in repo.heads(start)]
1477 else:
1477 else:
1478 heads = []
1478 heads = []
1479 for b, ls in repo.branchmap().iteritems():
1479 for b, ls in repo.branchmap().iteritems():
1480 if start is None:
1480 if start is None:
1481 heads += [repo[h] for h in ls]
1481 heads += [repo[h] for h in ls]
1482 continue
1482 continue
1483 startrev = repo.changelog.rev(start)
1483 startrev = repo.changelog.rev(start)
1484 descendants = set(repo.changelog.descendants(startrev))
1484 descendants = set(repo.changelog.descendants(startrev))
1485 descendants.add(startrev)
1485 descendants.add(startrev)
1486 rev = repo.changelog.rev
1486 rev = repo.changelog.rev
1487 heads += [repo[h] for h in ls if rev(h) in descendants]
1487 heads += [repo[h] for h in ls if rev(h) in descendants]
1488
1488
1489 if branchrevs:
1489 if branchrevs:
1490 decode, encode = encoding.fromlocal, encoding.tolocal
1490 decode, encode = encoding.fromlocal, encoding.tolocal
1491 branches = set(repo[decode(br)].branch() for br in branchrevs)
1491 branches = set(repo[decode(br)].branch() for br in branchrevs)
1492 heads = [h for h in heads if h.branch() in branches]
1492 heads = [h for h in heads if h.branch() in branches]
1493
1493
1494 if not opts.get('closed'):
1494 if not opts.get('closed'):
1495 heads = [h for h in heads if not h.extra().get('close')]
1495 heads = [h for h in heads if not h.extra().get('close')]
1496
1496
1497 if opts.get('active') and branchrevs:
1497 if opts.get('active') and branchrevs:
1498 dagheads = repo.heads(start)
1498 dagheads = repo.heads(start)
1499 heads = [h for h in heads if h.node() in dagheads]
1499 heads = [h for h in heads if h.node() in dagheads]
1500
1500
1501 if branchrevs:
1501 if branchrevs:
1502 haveheads = set(h.branch() for h in heads)
1502 haveheads = set(h.branch() for h in heads)
1503 if branches - haveheads:
1503 if branches - haveheads:
1504 headless = ', '.join(encode(b) for b in branches - haveheads)
1504 headless = ', '.join(encode(b) for b in branches - haveheads)
1505 msg = _('no open branch heads found on branches %s')
1505 msg = _('no open branch heads found on branches %s')
1506 if opts.get('rev'):
1506 if opts.get('rev'):
1507 msg += _(' (started at %s)' % opts['rev'])
1507 msg += _(' (started at %s)' % opts['rev'])
1508 ui.warn((msg + '\n') % headless)
1508 ui.warn((msg + '\n') % headless)
1509
1509
1510 if not heads:
1510 if not heads:
1511 return 1
1511 return 1
1512
1512
1513 heads = sorted(heads, key=lambda x: -x.rev())
1513 heads = sorted(heads, key=lambda x: -x.rev())
1514 displayer = cmdutil.show_changeset(ui, repo, opts)
1514 displayer = cmdutil.show_changeset(ui, repo, opts)
1515 for ctx in heads:
1515 for ctx in heads:
1516 displayer.show(ctx)
1516 displayer.show(ctx)
1517 displayer.close()
1517 displayer.close()
1518
1518
1519 def help_(ui, name=None, with_version=False, unknowncmd=False):
1519 def help_(ui, name=None, with_version=False, unknowncmd=False):
1520 """show help for a given topic or a help overview
1520 """show help for a given topic or a help overview
1521
1521
1522 With no arguments, print a list of commands with short help messages.
1522 With no arguments, print a list of commands with short help messages.
1523
1523
1524 Given a topic, extension, or command name, print help for that
1524 Given a topic, extension, or command name, print help for that
1525 topic."""
1525 topic."""
1526 option_lists = []
1526 option_lists = []
1527 textwidth = util.termwidth() - 2
1527 textwidth = util.termwidth() - 2
1528
1528
1529 def addglobalopts(aliases):
1529 def addglobalopts(aliases):
1530 if ui.verbose:
1530 if ui.verbose:
1531 option_lists.append((_("global options:"), globalopts))
1531 option_lists.append((_("global options:"), globalopts))
1532 if name == 'shortlist':
1532 if name == 'shortlist':
1533 option_lists.append((_('use "hg help" for the full list '
1533 option_lists.append((_('use "hg help" for the full list '
1534 'of commands'), ()))
1534 'of commands'), ()))
1535 else:
1535 else:
1536 if name == 'shortlist':
1536 if name == 'shortlist':
1537 msg = _('use "hg help" for the full list of commands '
1537 msg = _('use "hg help" for the full list of commands '
1538 'or "hg -v" for details')
1538 'or "hg -v" for details')
1539 elif aliases:
1539 elif aliases:
1540 msg = _('use "hg -v help%s" to show aliases and '
1540 msg = _('use "hg -v help%s" to show aliases and '
1541 'global options') % (name and " " + name or "")
1541 'global options') % (name and " " + name or "")
1542 else:
1542 else:
1543 msg = _('use "hg -v help %s" to show global options') % name
1543 msg = _('use "hg -v help %s" to show global options') % name
1544 option_lists.append((msg, ()))
1544 option_lists.append((msg, ()))
1545
1545
1546 def helpcmd(name):
1546 def helpcmd(name):
1547 if with_version:
1547 if with_version:
1548 version_(ui)
1548 version_(ui)
1549 ui.write('\n')
1549 ui.write('\n')
1550
1550
1551 try:
1551 try:
1552 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1552 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1553 except error.AmbiguousCommand, inst:
1553 except error.AmbiguousCommand, inst:
1554 # py3k fix: except vars can't be used outside the scope of the
1554 # py3k fix: except vars can't be used outside the scope of the
1555 # except block, nor can be used inside a lambda. python issue4617
1555 # except block, nor can be used inside a lambda. python issue4617
1556 prefix = inst.args[0]
1556 prefix = inst.args[0]
1557 select = lambda c: c.lstrip('^').startswith(prefix)
1557 select = lambda c: c.lstrip('^').startswith(prefix)
1558 helplist(_('list of commands:\n\n'), select)
1558 helplist(_('list of commands:\n\n'), select)
1559 return
1559 return
1560
1560
1561 # check if it's an invalid alias and display its error if it is
1561 # check if it's an invalid alias and display its error if it is
1562 if getattr(entry[0], 'badalias', False):
1562 if getattr(entry[0], 'badalias', False):
1563 if not unknowncmd:
1563 if not unknowncmd:
1564 entry[0](ui)
1564 entry[0](ui)
1565 return
1565 return
1566
1566
1567 # synopsis
1567 # synopsis
1568 if len(entry) > 2:
1568 if len(entry) > 2:
1569 if entry[2].startswith('hg'):
1569 if entry[2].startswith('hg'):
1570 ui.write("%s\n" % entry[2])
1570 ui.write("%s\n" % entry[2])
1571 else:
1571 else:
1572 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1572 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1573 else:
1573 else:
1574 ui.write('hg %s\n' % aliases[0])
1574 ui.write('hg %s\n' % aliases[0])
1575
1575
1576 # aliases
1576 # aliases
1577 if not ui.quiet and len(aliases) > 1:
1577 if not ui.quiet and len(aliases) > 1:
1578 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1578 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1579
1579
1580 # description
1580 # description
1581 doc = gettext(entry[0].__doc__)
1581 doc = gettext(entry[0].__doc__)
1582 if not doc:
1582 if not doc:
1583 doc = _("(no help text available)")
1583 doc = _("(no help text available)")
1584 if hasattr(entry[0], 'definition'): # aliased command
1584 if hasattr(entry[0], 'definition'): # aliased command
1585 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1585 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1586 if ui.quiet:
1586 if ui.quiet:
1587 doc = doc.splitlines()[0]
1587 doc = doc.splitlines()[0]
1588 keep = ui.verbose and ['verbose'] or []
1588 keep = ui.verbose and ['verbose'] or []
1589 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1589 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1590 ui.write("\n%s\n" % formatted)
1590 ui.write("\n%s\n" % formatted)
1591 if pruned:
1591 if pruned:
1592 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1592 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1593
1593
1594 if not ui.quiet:
1594 if not ui.quiet:
1595 # options
1595 # options
1596 if entry[1]:
1596 if entry[1]:
1597 option_lists.append((_("options:\n"), entry[1]))
1597 option_lists.append((_("options:\n"), entry[1]))
1598
1598
1599 addglobalopts(False)
1599 addglobalopts(False)
1600
1600
1601 def helplist(header, select=None):
1601 def helplist(header, select=None):
1602 h = {}
1602 h = {}
1603 cmds = {}
1603 cmds = {}
1604 for c, e in table.iteritems():
1604 for c, e in table.iteritems():
1605 f = c.split("|", 1)[0]
1605 f = c.split("|", 1)[0]
1606 if select and not select(f):
1606 if select and not select(f):
1607 continue
1607 continue
1608 if (not select and name != 'shortlist' and
1608 if (not select and name != 'shortlist' and
1609 e[0].__module__ != __name__):
1609 e[0].__module__ != __name__):
1610 continue
1610 continue
1611 if name == "shortlist" and not f.startswith("^"):
1611 if name == "shortlist" and not f.startswith("^"):
1612 continue
1612 continue
1613 f = f.lstrip("^")
1613 f = f.lstrip("^")
1614 if not ui.debugflag and f.startswith("debug"):
1614 if not ui.debugflag and f.startswith("debug"):
1615 continue
1615 continue
1616 doc = e[0].__doc__
1616 doc = e[0].__doc__
1617 if doc and 'DEPRECATED' in doc and not ui.verbose:
1617 if doc and 'DEPRECATED' in doc and not ui.verbose:
1618 continue
1618 continue
1619 doc = gettext(doc)
1619 doc = gettext(doc)
1620 if not doc:
1620 if not doc:
1621 doc = _("(no help text available)")
1621 doc = _("(no help text available)")
1622 h[f] = doc.splitlines()[0].rstrip()
1622 h[f] = doc.splitlines()[0].rstrip()
1623 cmds[f] = c.lstrip("^")
1623 cmds[f] = c.lstrip("^")
1624
1624
1625 if not h:
1625 if not h:
1626 ui.status(_('no commands defined\n'))
1626 ui.status(_('no commands defined\n'))
1627 return
1627 return
1628
1628
1629 ui.status(header)
1629 ui.status(header)
1630 fns = sorted(h)
1630 fns = sorted(h)
1631 m = max(map(len, fns))
1631 m = max(map(len, fns))
1632 for f in fns:
1632 for f in fns:
1633 if ui.verbose:
1633 if ui.verbose:
1634 commands = cmds[f].replace("|",", ")
1634 commands = cmds[f].replace("|",", ")
1635 ui.write(" %s:\n %s\n"%(commands, h[f]))
1635 ui.write(" %s:\n %s\n"%(commands, h[f]))
1636 else:
1636 else:
1637 ui.write(' %-*s %s\n' % (m, f, util.wrap(h[f], m + 4)))
1637 ui.write(' %-*s %s\n' % (m, f, util.wrap(h[f], m + 4)))
1638
1638
1639 if not ui.quiet:
1639 if not ui.quiet:
1640 addglobalopts(True)
1640 addglobalopts(True)
1641
1641
1642 def helptopic(name):
1642 def helptopic(name):
1643 for names, header, doc in help.helptable:
1643 for names, header, doc in help.helptable:
1644 if name in names:
1644 if name in names:
1645 break
1645 break
1646 else:
1646 else:
1647 raise error.UnknownCommand(name)
1647 raise error.UnknownCommand(name)
1648
1648
1649 # description
1649 # description
1650 if not doc:
1650 if not doc:
1651 doc = _("(no help text available)")
1651 doc = _("(no help text available)")
1652 if hasattr(doc, '__call__'):
1652 if hasattr(doc, '__call__'):
1653 doc = doc()
1653 doc = doc()
1654
1654
1655 ui.write("%s\n\n" % header)
1655 ui.write("%s\n\n" % header)
1656 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1656 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1657
1657
1658 def helpext(name):
1658 def helpext(name):
1659 try:
1659 try:
1660 mod = extensions.find(name)
1660 mod = extensions.find(name)
1661 doc = gettext(mod.__doc__) or _('no help text available')
1661 doc = gettext(mod.__doc__) or _('no help text available')
1662 except KeyError:
1662 except KeyError:
1663 mod = None
1663 mod = None
1664 doc = extensions.disabledext(name)
1664 doc = extensions.disabledext(name)
1665 if not doc:
1665 if not doc:
1666 raise error.UnknownCommand(name)
1666 raise error.UnknownCommand(name)
1667
1667
1668 if '\n' not in doc:
1668 if '\n' not in doc:
1669 head, tail = doc, ""
1669 head, tail = doc, ""
1670 else:
1670 else:
1671 head, tail = doc.split('\n', 1)
1671 head, tail = doc.split('\n', 1)
1672 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1672 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1673 if tail:
1673 if tail:
1674 ui.write(minirst.format(tail, textwidth))
1674 ui.write(minirst.format(tail, textwidth))
1675 ui.status('\n\n')
1675 ui.status('\n\n')
1676
1676
1677 if mod:
1677 if mod:
1678 try:
1678 try:
1679 ct = mod.cmdtable
1679 ct = mod.cmdtable
1680 except AttributeError:
1680 except AttributeError:
1681 ct = {}
1681 ct = {}
1682 modcmds = set([c.split('|', 1)[0] for c in ct])
1682 modcmds = set([c.split('|', 1)[0] for c in ct])
1683 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1683 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1684 else:
1684 else:
1685 ui.write(_('use "hg help extensions" for information on enabling '
1685 ui.write(_('use "hg help extensions" for information on enabling '
1686 'extensions\n'))
1686 'extensions\n'))
1687
1687
1688 def helpextcmd(name):
1688 def helpextcmd(name):
1689 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1689 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1690 doc = gettext(mod.__doc__).splitlines()[0]
1690 doc = gettext(mod.__doc__).splitlines()[0]
1691
1691
1692 msg = help.listexts(_("'%s' is provided by the following "
1692 msg = help.listexts(_("'%s' is provided by the following "
1693 "extension:") % cmd, {ext: doc}, len(ext),
1693 "extension:") % cmd, {ext: doc}, len(ext),
1694 indent=4)
1694 indent=4)
1695 ui.write(minirst.format(msg, textwidth))
1695 ui.write(minirst.format(msg, textwidth))
1696 ui.write('\n\n')
1696 ui.write('\n\n')
1697 ui.write(_('use "hg help extensions" for information on enabling '
1697 ui.write(_('use "hg help extensions" for information on enabling '
1698 'extensions\n'))
1698 'extensions\n'))
1699
1699
1700 if name and name != 'shortlist':
1700 if name and name != 'shortlist':
1701 i = None
1701 i = None
1702 if unknowncmd:
1702 if unknowncmd:
1703 queries = (helpextcmd,)
1703 queries = (helpextcmd,)
1704 else:
1704 else:
1705 queries = (helptopic, helpcmd, helpext, helpextcmd)
1705 queries = (helptopic, helpcmd, helpext, helpextcmd)
1706 for f in queries:
1706 for f in queries:
1707 try:
1707 try:
1708 f(name)
1708 f(name)
1709 i = None
1709 i = None
1710 break
1710 break
1711 except error.UnknownCommand, inst:
1711 except error.UnknownCommand, inst:
1712 i = inst
1712 i = inst
1713 if i:
1713 if i:
1714 raise i
1714 raise i
1715
1715
1716 else:
1716 else:
1717 # program name
1717 # program name
1718 if ui.verbose or with_version:
1718 if ui.verbose or with_version:
1719 version_(ui)
1719 version_(ui)
1720 else:
1720 else:
1721 ui.status(_("Mercurial Distributed SCM\n"))
1721 ui.status(_("Mercurial Distributed SCM\n"))
1722 ui.status('\n')
1722 ui.status('\n')
1723
1723
1724 # list of commands
1724 # list of commands
1725 if name == "shortlist":
1725 if name == "shortlist":
1726 header = _('basic commands:\n\n')
1726 header = _('basic commands:\n\n')
1727 else:
1727 else:
1728 header = _('list of commands:\n\n')
1728 header = _('list of commands:\n\n')
1729
1729
1730 helplist(header)
1730 helplist(header)
1731 if name != 'shortlist':
1731 if name != 'shortlist':
1732 exts, maxlength = extensions.enabled()
1732 exts, maxlength = extensions.enabled()
1733 text = help.listexts(_('enabled extensions:'), exts, maxlength)
1733 text = help.listexts(_('enabled extensions:'), exts, maxlength)
1734 if text:
1734 if text:
1735 ui.write("\n%s\n" % minirst.format(text, textwidth))
1735 ui.write("\n%s\n" % minirst.format(text, textwidth))
1736
1736
1737 # list all option lists
1737 # list all option lists
1738 opt_output = []
1738 opt_output = []
1739 for title, options in option_lists:
1739 for title, options in option_lists:
1740 opt_output.append(("\n%s" % title, None))
1740 opt_output.append(("\n%s" % title, None))
1741 for shortopt, longopt, default, desc in options:
1741 for shortopt, longopt, default, desc in options:
1742 if _("DEPRECATED") in desc and not ui.verbose:
1742 if _("DEPRECATED") in desc and not ui.verbose:
1743 continue
1743 continue
1744 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1744 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1745 longopt and " --%s" % longopt),
1745 longopt and " --%s" % longopt),
1746 "%s%s" % (desc,
1746 "%s%s" % (desc,
1747 default
1747 default
1748 and _(" (default: %s)") % default
1748 and _(" (default: %s)") % default
1749 or "")))
1749 or "")))
1750
1750
1751 if not name:
1751 if not name:
1752 ui.write(_("\nadditional help topics:\n\n"))
1752 ui.write(_("\nadditional help topics:\n\n"))
1753 topics = []
1753 topics = []
1754 for names, header, doc in help.helptable:
1754 for names, header, doc in help.helptable:
1755 topics.append((sorted(names, key=len, reverse=True)[0], header))
1755 topics.append((sorted(names, key=len, reverse=True)[0], header))
1756 topics_len = max([len(s[0]) for s in topics])
1756 topics_len = max([len(s[0]) for s in topics])
1757 for t, desc in topics:
1757 for t, desc in topics:
1758 ui.write(" %-*s %s\n" % (topics_len, t, desc))
1758 ui.write(" %-*s %s\n" % (topics_len, t, desc))
1759
1759
1760 if opt_output:
1760 if opt_output:
1761 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1761 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1762 for first, second in opt_output:
1762 for first, second in opt_output:
1763 if second:
1763 if second:
1764 second = util.wrap(second, opts_len + 3)
1764 second = util.wrap(second, opts_len + 3)
1765 ui.write(" %-*s %s\n" % (opts_len, first, second))
1765 ui.write(" %-*s %s\n" % (opts_len, first, second))
1766 else:
1766 else:
1767 ui.write("%s\n" % first)
1767 ui.write("%s\n" % first)
1768
1768
1769 def identify(ui, repo, source=None,
1769 def identify(ui, repo, source=None,
1770 rev=None, num=None, id=None, branch=None, tags=None):
1770 rev=None, num=None, id=None, branch=None, tags=None):
1771 """identify the working copy or specified revision
1771 """identify the working copy or specified revision
1772
1772
1773 With no revision, print a summary of the current state of the
1773 With no revision, print a summary of the current state of the
1774 repository.
1774 repository.
1775
1775
1776 Specifying a path to a repository root or Mercurial bundle will
1776 Specifying a path to a repository root or Mercurial bundle will
1777 cause lookup to operate on that repository/bundle.
1777 cause lookup to operate on that repository/bundle.
1778
1778
1779 This summary identifies the repository state using one or two
1779 This summary identifies the repository state using one or two
1780 parent hash identifiers, followed by a "+" if there are
1780 parent hash identifiers, followed by a "+" if there are
1781 uncommitted changes in the working directory, a list of tags for
1781 uncommitted changes in the working directory, a list of tags for
1782 this revision and a branch name for non-default branches.
1782 this revision and a branch name for non-default branches.
1783 """
1783 """
1784
1784
1785 if not repo and not source:
1785 if not repo and not source:
1786 raise util.Abort(_("There is no Mercurial repository here "
1786 raise util.Abort(_("There is no Mercurial repository here "
1787 "(.hg not found)"))
1787 "(.hg not found)"))
1788
1788
1789 hexfunc = ui.debugflag and hex or short
1789 hexfunc = ui.debugflag and hex or short
1790 default = not (num or id or branch or tags)
1790 default = not (num or id or branch or tags)
1791 output = []
1791 output = []
1792
1792
1793 revs = []
1793 revs = []
1794 if source:
1794 if source:
1795 source, branches = hg.parseurl(ui.expandpath(source))
1795 source, branches = hg.parseurl(ui.expandpath(source))
1796 repo = hg.repository(ui, source)
1796 repo = hg.repository(ui, source)
1797 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
1797 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
1798
1798
1799 if not repo.local():
1799 if not repo.local():
1800 if not rev and revs:
1800 if not rev and revs:
1801 rev = revs[0]
1801 rev = revs[0]
1802 if not rev:
1802 if not rev:
1803 rev = "tip"
1803 rev = "tip"
1804 if num or branch or tags:
1804 if num or branch or tags:
1805 raise util.Abort(
1805 raise util.Abort(
1806 "can't query remote revision number, branch, or tags")
1806 "can't query remote revision number, branch, or tags")
1807 output = [hexfunc(repo.lookup(rev))]
1807 output = [hexfunc(repo.lookup(rev))]
1808 elif not rev:
1808 elif not rev:
1809 ctx = repo[None]
1809 ctx = repo[None]
1810 parents = ctx.parents()
1810 parents = ctx.parents()
1811 changed = False
1811 changed = False
1812 if default or id or num:
1812 if default or id or num:
1813 changed = util.any(repo.status())
1813 changed = util.any(repo.status())
1814 if default or id:
1814 if default or id:
1815 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1815 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1816 (changed) and "+" or "")]
1816 (changed) and "+" or "")]
1817 if num:
1817 if num:
1818 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1818 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1819 (changed) and "+" or ""))
1819 (changed) and "+" or ""))
1820 else:
1820 else:
1821 ctx = repo[rev]
1821 ctx = repo[rev]
1822 if default or id:
1822 if default or id:
1823 output = [hexfunc(ctx.node())]
1823 output = [hexfunc(ctx.node())]
1824 if num:
1824 if num:
1825 output.append(str(ctx.rev()))
1825 output.append(str(ctx.rev()))
1826
1826
1827 if repo.local() and default and not ui.quiet:
1827 if repo.local() and default and not ui.quiet:
1828 b = encoding.tolocal(ctx.branch())
1828 b = encoding.tolocal(ctx.branch())
1829 if b != 'default':
1829 if b != 'default':
1830 output.append("(%s)" % b)
1830 output.append("(%s)" % b)
1831
1831
1832 # multiple tags for a single parent separated by '/'
1832 # multiple tags for a single parent separated by '/'
1833 t = "/".join(ctx.tags())
1833 t = "/".join(ctx.tags())
1834 if t:
1834 if t:
1835 output.append(t)
1835 output.append(t)
1836
1836
1837 if branch:
1837 if branch:
1838 output.append(encoding.tolocal(ctx.branch()))
1838 output.append(encoding.tolocal(ctx.branch()))
1839
1839
1840 if tags:
1840 if tags:
1841 output.extend(ctx.tags())
1841 output.extend(ctx.tags())
1842
1842
1843 ui.write("%s\n" % ' '.join(output))
1843 ui.write("%s\n" % ' '.join(output))
1844
1844
1845 def import_(ui, repo, patch1, *patches, **opts):
1845 def import_(ui, repo, patch1, *patches, **opts):
1846 """import an ordered set of patches
1846 """import an ordered set of patches
1847
1847
1848 Import a list of patches and commit them individually (unless
1848 Import a list of patches and commit them individually (unless
1849 --no-commit is specified).
1849 --no-commit is specified).
1850
1850
1851 If there are outstanding changes in the working directory, import
1851 If there are outstanding changes in the working directory, import
1852 will abort unless given the -f/--force flag.
1852 will abort unless given the -f/--force flag.
1853
1853
1854 You can import a patch straight from a mail message. Even patches
1854 You can import a patch straight from a mail message. Even patches
1855 as attachments work (to use the body part, it must have type
1855 as attachments work (to use the body part, it must have type
1856 text/plain or text/x-patch). From and Subject headers of email
1856 text/plain or text/x-patch). From and Subject headers of email
1857 message are used as default committer and commit message. All
1857 message are used as default committer and commit message. All
1858 text/plain body parts before first diff are added to commit
1858 text/plain body parts before first diff are added to commit
1859 message.
1859 message.
1860
1860
1861 If the imported patch was generated by hg export, user and
1861 If the imported patch was generated by hg export, user and
1862 description from patch override values from message headers and
1862 description from patch override values from message headers and
1863 body. Values given on command line with -m/--message and -u/--user
1863 body. Values given on command line with -m/--message and -u/--user
1864 override these.
1864 override these.
1865
1865
1866 If --exact is specified, import will set the working directory to
1866 If --exact is specified, import will set the working directory to
1867 the parent of each patch before applying it, and will abort if the
1867 the parent of each patch before applying it, and will abort if the
1868 resulting changeset has a different ID than the one recorded in
1868 resulting changeset has a different ID than the one recorded in
1869 the patch. This may happen due to character set problems or other
1869 the patch. This may happen due to character set problems or other
1870 deficiencies in the text patch format.
1870 deficiencies in the text patch format.
1871
1871
1872 With -s/--similarity, hg will attempt to discover renames and
1872 With -s/--similarity, hg will attempt to discover renames and
1873 copies in the patch in the same way as 'addremove'.
1873 copies in the patch in the same way as 'addremove'.
1874
1874
1875 To read a patch from standard input, use "-" as the patch name. If
1875 To read a patch from standard input, use "-" as the patch name. If
1876 a URL is specified, the patch will be downloaded from it.
1876 a URL is specified, the patch will be downloaded from it.
1877 See 'hg help dates' for a list of formats valid for -d/--date.
1877 See 'hg help dates' for a list of formats valid for -d/--date.
1878 """
1878 """
1879 patches = (patch1,) + patches
1879 patches = (patch1,) + patches
1880
1880
1881 date = opts.get('date')
1881 date = opts.get('date')
1882 if date:
1882 if date:
1883 opts['date'] = util.parsedate(date)
1883 opts['date'] = util.parsedate(date)
1884
1884
1885 try:
1885 try:
1886 sim = float(opts.get('similarity') or 0)
1886 sim = float(opts.get('similarity') or 0)
1887 except ValueError:
1887 except ValueError:
1888 raise util.Abort(_('similarity must be a number'))
1888 raise util.Abort(_('similarity must be a number'))
1889 if sim < 0 or sim > 100:
1889 if sim < 0 or sim > 100:
1890 raise util.Abort(_('similarity must be between 0 and 100'))
1890 raise util.Abort(_('similarity must be between 0 and 100'))
1891
1891
1892 if opts.get('exact') or not opts.get('force'):
1892 if opts.get('exact') or not opts.get('force'):
1893 cmdutil.bail_if_changed(repo)
1893 cmdutil.bail_if_changed(repo)
1894
1894
1895 d = opts["base"]
1895 d = opts["base"]
1896 strip = opts["strip"]
1896 strip = opts["strip"]
1897 wlock = lock = None
1897 wlock = lock = None
1898
1898
1899 def tryone(ui, hunk):
1899 def tryone(ui, hunk):
1900 tmpname, message, user, date, branch, nodeid, p1, p2 = \
1900 tmpname, message, user, date, branch, nodeid, p1, p2 = \
1901 patch.extract(ui, hunk)
1901 patch.extract(ui, hunk)
1902
1902
1903 if not tmpname:
1903 if not tmpname:
1904 return None
1904 return None
1905 commitid = _('to working directory')
1905 commitid = _('to working directory')
1906
1906
1907 try:
1907 try:
1908 cmdline_message = cmdutil.logmessage(opts)
1908 cmdline_message = cmdutil.logmessage(opts)
1909 if cmdline_message:
1909 if cmdline_message:
1910 # pickup the cmdline msg
1910 # pickup the cmdline msg
1911 message = cmdline_message
1911 message = cmdline_message
1912 elif message:
1912 elif message:
1913 # pickup the patch msg
1913 # pickup the patch msg
1914 message = message.strip()
1914 message = message.strip()
1915 else:
1915 else:
1916 # launch the editor
1916 # launch the editor
1917 message = None
1917 message = None
1918 ui.debug('message:\n%s\n' % message)
1918 ui.debug('message:\n%s\n' % message)
1919
1919
1920 wp = repo.parents()
1920 wp = repo.parents()
1921 if opts.get('exact'):
1921 if opts.get('exact'):
1922 if not nodeid or not p1:
1922 if not nodeid or not p1:
1923 raise util.Abort(_('not a Mercurial patch'))
1923 raise util.Abort(_('not a Mercurial patch'))
1924 p1 = repo.lookup(p1)
1924 p1 = repo.lookup(p1)
1925 p2 = repo.lookup(p2 or hex(nullid))
1925 p2 = repo.lookup(p2 or hex(nullid))
1926
1926
1927 if p1 != wp[0].node():
1927 if p1 != wp[0].node():
1928 hg.clean(repo, p1)
1928 hg.clean(repo, p1)
1929 repo.dirstate.setparents(p1, p2)
1929 repo.dirstate.setparents(p1, p2)
1930 elif p2:
1930 elif p2:
1931 try:
1931 try:
1932 p1 = repo.lookup(p1)
1932 p1 = repo.lookup(p1)
1933 p2 = repo.lookup(p2)
1933 p2 = repo.lookup(p2)
1934 if p1 == wp[0].node():
1934 if p1 == wp[0].node():
1935 repo.dirstate.setparents(p1, p2)
1935 repo.dirstate.setparents(p1, p2)
1936 except error.RepoError:
1936 except error.RepoError:
1937 pass
1937 pass
1938 if opts.get('exact') or opts.get('import_branch'):
1938 if opts.get('exact') or opts.get('import_branch'):
1939 repo.dirstate.setbranch(branch or 'default')
1939 repo.dirstate.setbranch(branch or 'default')
1940
1940
1941 files = {}
1941 files = {}
1942 try:
1942 try:
1943 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1943 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1944 files=files, eolmode=None)
1944 files=files, eolmode=None)
1945 finally:
1945 finally:
1946 files = patch.updatedir(ui, repo, files,
1946 files = patch.updatedir(ui, repo, files,
1947 similarity=sim / 100.0)
1947 similarity=sim / 100.0)
1948 if not opts.get('no_commit'):
1948 if not opts.get('no_commit'):
1949 if opts.get('exact'):
1949 if opts.get('exact'):
1950 m = None
1950 m = None
1951 else:
1951 else:
1952 m = cmdutil.matchfiles(repo, files or [])
1952 m = cmdutil.matchfiles(repo, files or [])
1953 n = repo.commit(message, opts.get('user') or user,
1953 n = repo.commit(message, opts.get('user') or user,
1954 opts.get('date') or date, match=m,
1954 opts.get('date') or date, match=m,
1955 editor=cmdutil.commiteditor)
1955 editor=cmdutil.commiteditor)
1956 if opts.get('exact'):
1956 if opts.get('exact'):
1957 if hex(n) != nodeid:
1957 if hex(n) != nodeid:
1958 repo.rollback()
1958 repo.rollback()
1959 raise util.Abort(_('patch is damaged'
1959 raise util.Abort(_('patch is damaged'
1960 ' or loses information'))
1960 ' or loses information'))
1961 # Force a dirstate write so that the next transaction
1961 # Force a dirstate write so that the next transaction
1962 # backups an up-do-date file.
1962 # backups an up-do-date file.
1963 repo.dirstate.write()
1963 repo.dirstate.write()
1964 if n:
1964 if n:
1965 commitid = short(n)
1965 commitid = short(n)
1966
1966
1967 return commitid
1967 return commitid
1968 finally:
1968 finally:
1969 os.unlink(tmpname)
1969 os.unlink(tmpname)
1970
1970
1971 try:
1971 try:
1972 wlock = repo.wlock()
1972 wlock = repo.wlock()
1973 lock = repo.lock()
1973 lock = repo.lock()
1974 lastcommit = None
1974 lastcommit = None
1975 for p in patches:
1975 for p in patches:
1976 pf = os.path.join(d, p)
1976 pf = os.path.join(d, p)
1977
1977
1978 if pf == '-':
1978 if pf == '-':
1979 ui.status(_("applying patch from stdin\n"))
1979 ui.status(_("applying patch from stdin\n"))
1980 pf = sys.stdin
1980 pf = sys.stdin
1981 else:
1981 else:
1982 ui.status(_("applying %s\n") % p)
1982 ui.status(_("applying %s\n") % p)
1983 pf = url.open(ui, pf)
1983 pf = url.open(ui, pf)
1984
1984
1985 haspatch = False
1985 haspatch = False
1986 for hunk in patch.split(pf):
1986 for hunk in patch.split(pf):
1987 commitid = tryone(ui, hunk)
1987 commitid = tryone(ui, hunk)
1988 if commitid:
1988 if commitid:
1989 haspatch = True
1989 haspatch = True
1990 if lastcommit:
1990 if lastcommit:
1991 ui.status(_('applied %s\n') % lastcommit)
1991 ui.status(_('applied %s\n') % lastcommit)
1992 lastcommit = commitid
1992 lastcommit = commitid
1993
1993
1994 if not haspatch:
1994 if not haspatch:
1995 raise util.Abort(_('no diffs found'))
1995 raise util.Abort(_('no diffs found'))
1996
1996
1997 finally:
1997 finally:
1998 release(lock, wlock)
1998 release(lock, wlock)
1999
1999
2000 def incoming(ui, repo, source="default", **opts):
2000 def incoming(ui, repo, source="default", **opts):
2001 """show new changesets found in source
2001 """show new changesets found in source
2002
2002
2003 Show new changesets found in the specified path/URL or the default
2003 Show new changesets found in the specified path/URL or the default
2004 pull location. These are the changesets that would have been pulled
2004 pull location. These are the changesets that would have been pulled
2005 if a pull at the time you issued this command.
2005 if a pull at the time you issued this command.
2006
2006
2007 For remote repository, using --bundle avoids downloading the
2007 For remote repository, using --bundle avoids downloading the
2008 changesets twice if the incoming is followed by a pull.
2008 changesets twice if the incoming is followed by a pull.
2009
2009
2010 See pull for valid source format details.
2010 See pull for valid source format details.
2011 """
2011 """
2012 limit = cmdutil.loglimit(opts)
2012 limit = cmdutil.loglimit(opts)
2013 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2013 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2014 other = hg.repository(cmdutil.remoteui(repo, opts), source)
2014 other = hg.repository(cmdutil.remoteui(repo, opts), source)
2015 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2015 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2016 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2016 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2017 if revs:
2017 if revs:
2018 revs = [other.lookup(rev) for rev in revs]
2018 revs = [other.lookup(rev) for rev in revs]
2019 common, incoming, rheads = repo.findcommonincoming(other, heads=revs,
2019 common, incoming, rheads = repo.findcommonincoming(other, heads=revs,
2020 force=opts["force"])
2020 force=opts["force"])
2021 if not incoming:
2021 if not incoming:
2022 try:
2022 try:
2023 os.unlink(opts["bundle"])
2023 os.unlink(opts["bundle"])
2024 except:
2024 except:
2025 pass
2025 pass
2026 ui.status(_("no changes found\n"))
2026 ui.status(_("no changes found\n"))
2027 return 1
2027 return 1
2028
2028
2029 cleanup = None
2029 cleanup = None
2030 try:
2030 try:
2031 fname = opts["bundle"]
2031 fname = opts["bundle"]
2032 if fname or not other.local():
2032 if fname or not other.local():
2033 # create a bundle (uncompressed if other repo is not local)
2033 # create a bundle (uncompressed if other repo is not local)
2034
2034
2035 if revs is None and other.capable('changegroupsubset'):
2035 if revs is None and other.capable('changegroupsubset'):
2036 revs = rheads
2036 revs = rheads
2037
2037
2038 if revs is None:
2038 if revs is None:
2039 cg = other.changegroup(incoming, "incoming")
2039 cg = other.changegroup(incoming, "incoming")
2040 else:
2040 else:
2041 cg = other.changegroupsubset(incoming, revs, 'incoming')
2041 cg = other.changegroupsubset(incoming, revs, 'incoming')
2042 bundletype = other.local() and "HG10BZ" or "HG10UN"
2042 bundletype = other.local() and "HG10BZ" or "HG10UN"
2043 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2043 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2044 # keep written bundle?
2044 # keep written bundle?
2045 if opts["bundle"]:
2045 if opts["bundle"]:
2046 cleanup = None
2046 cleanup = None
2047 if not other.local():
2047 if not other.local():
2048 # use the created uncompressed bundlerepo
2048 # use the created uncompressed bundlerepo
2049 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2049 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2050
2050
2051 o = other.changelog.nodesbetween(incoming, revs)[0]
2051 o = other.changelog.nodesbetween(incoming, revs)[0]
2052 if opts.get('newest_first'):
2052 if opts.get('newest_first'):
2053 o.reverse()
2053 o.reverse()
2054 displayer = cmdutil.show_changeset(ui, other, opts)
2054 displayer = cmdutil.show_changeset(ui, other, opts)
2055 count = 0
2055 count = 0
2056 for n in o:
2056 for n in o:
2057 if limit is not None and count >= limit:
2057 if limit is not None and count >= limit:
2058 break
2058 break
2059 parents = [p for p in other.changelog.parents(n) if p != nullid]
2059 parents = [p for p in other.changelog.parents(n) if p != nullid]
2060 if opts.get('no_merges') and len(parents) == 2:
2060 if opts.get('no_merges') and len(parents) == 2:
2061 continue
2061 continue
2062 count += 1
2062 count += 1
2063 displayer.show(other[n])
2063 displayer.show(other[n])
2064 displayer.close()
2064 displayer.close()
2065 finally:
2065 finally:
2066 if hasattr(other, 'close'):
2066 if hasattr(other, 'close'):
2067 other.close()
2067 other.close()
2068 if cleanup:
2068 if cleanup:
2069 os.unlink(cleanup)
2069 os.unlink(cleanup)
2070
2070
2071 def init(ui, dest=".", **opts):
2071 def init(ui, dest=".", **opts):
2072 """create a new repository in the given directory
2072 """create a new repository in the given directory
2073
2073
2074 Initialize a new repository in the given directory. If the given
2074 Initialize a new repository in the given directory. If the given
2075 directory does not exist, it will be created.
2075 directory does not exist, it will be created.
2076
2076
2077 If no directory is given, the current directory is used.
2077 If no directory is given, the current directory is used.
2078
2078
2079 It is possible to specify an ``ssh://`` URL as the destination.
2079 It is possible to specify an ``ssh://`` URL as the destination.
2080 See 'hg help urls' for more information.
2080 See 'hg help urls' for more information.
2081 """
2081 """
2082 hg.repository(cmdutil.remoteui(ui, opts), dest, create=1)
2082 hg.repository(cmdutil.remoteui(ui, opts), dest, create=1)
2083
2083
2084 def locate(ui, repo, *pats, **opts):
2084 def locate(ui, repo, *pats, **opts):
2085 """locate files matching specific patterns
2085 """locate files matching specific patterns
2086
2086
2087 Print files under Mercurial control in the working directory whose
2087 Print files under Mercurial control in the working directory whose
2088 names match the given patterns.
2088 names match the given patterns.
2089
2089
2090 By default, this command searches all directories in the working
2090 By default, this command searches all directories in the working
2091 directory. To search just the current directory and its
2091 directory. To search just the current directory and its
2092 subdirectories, use "--include .".
2092 subdirectories, use "--include .".
2093
2093
2094 If no patterns are given to match, this command prints the names
2094 If no patterns are given to match, this command prints the names
2095 of all files under Mercurial control in the working directory.
2095 of all files under Mercurial control in the working directory.
2096
2096
2097 If you want to feed the output of this command into the "xargs"
2097 If you want to feed the output of this command into the "xargs"
2098 command, use the -0 option to both this command and "xargs". This
2098 command, use the -0 option to both this command and "xargs". This
2099 will avoid the problem of "xargs" treating single filenames that
2099 will avoid the problem of "xargs" treating single filenames that
2100 contain whitespace as multiple filenames.
2100 contain whitespace as multiple filenames.
2101 """
2101 """
2102 end = opts.get('print0') and '\0' or '\n'
2102 end = opts.get('print0') and '\0' or '\n'
2103 rev = opts.get('rev') or None
2103 rev = opts.get('rev') or None
2104
2104
2105 ret = 1
2105 ret = 1
2106 m = cmdutil.match(repo, pats, opts, default='relglob')
2106 m = cmdutil.match(repo, pats, opts, default='relglob')
2107 m.bad = lambda x, y: False
2107 m.bad = lambda x, y: False
2108 for abs in repo[rev].walk(m):
2108 for abs in repo[rev].walk(m):
2109 if not rev and abs not in repo.dirstate:
2109 if not rev and abs not in repo.dirstate:
2110 continue
2110 continue
2111 if opts.get('fullpath'):
2111 if opts.get('fullpath'):
2112 ui.write(repo.wjoin(abs), end)
2112 ui.write(repo.wjoin(abs), end)
2113 else:
2113 else:
2114 ui.write(((pats and m.rel(abs)) or abs), end)
2114 ui.write(((pats and m.rel(abs)) or abs), end)
2115 ret = 0
2115 ret = 0
2116
2116
2117 return ret
2117 return ret
2118
2118
2119 def log(ui, repo, *pats, **opts):
2119 def log(ui, repo, *pats, **opts):
2120 """show revision history of entire repository or files
2120 """show revision history of entire repository or files
2121
2121
2122 Print the revision history of the specified files or the entire
2122 Print the revision history of the specified files or the entire
2123 project.
2123 project.
2124
2124
2125 File history is shown without following rename or copy history of
2125 File history is shown without following rename or copy history of
2126 files. Use -f/--follow with a filename to follow history across
2126 files. Use -f/--follow with a filename to follow history across
2127 renames and copies. --follow without a filename will only show
2127 renames and copies. --follow without a filename will only show
2128 ancestors or descendants of the starting revision. --follow-first
2128 ancestors or descendants of the starting revision. --follow-first
2129 only follows the first parent of merge revisions.
2129 only follows the first parent of merge revisions.
2130
2130
2131 If no revision range is specified, the default is tip:0 unless
2131 If no revision range is specified, the default is tip:0 unless
2132 --follow is set, in which case the working directory parent is
2132 --follow is set, in which case the working directory parent is
2133 used as the starting revision.
2133 used as the starting revision.
2134
2134
2135 See 'hg help dates' for a list of formats valid for -d/--date.
2135 See 'hg help dates' for a list of formats valid for -d/--date.
2136
2136
2137 By default this command prints revision number and changeset id,
2137 By default this command prints revision number and changeset id,
2138 tags, non-trivial parents, user, date and time, and a summary for
2138 tags, non-trivial parents, user, date and time, and a summary for
2139 each commit. When the -v/--verbose switch is used, the list of
2139 each commit. When the -v/--verbose switch is used, the list of
2140 changed files and full commit message are shown.
2140 changed files and full commit message are shown.
2141
2141
2142 NOTE: log -p/--patch may generate unexpected diff output for merge
2142 NOTE: log -p/--patch may generate unexpected diff output for merge
2143 changesets, as it will only compare the merge changeset against
2143 changesets, as it will only compare the merge changeset against
2144 its first parent. Also, only files different from BOTH parents
2144 its first parent. Also, only files different from BOTH parents
2145 will appear in files:.
2145 will appear in files:.
2146 """
2146 """
2147
2147
2148 matchfn = cmdutil.match(repo, pats, opts)
2148 matchfn = cmdutil.match(repo, pats, opts)
2149 limit = cmdutil.loglimit(opts)
2149 limit = cmdutil.loglimit(opts)
2150 count = 0
2150 count = 0
2151
2151
2152 endrev = None
2152 endrev = None
2153 if opts.get('copies') and opts.get('rev'):
2153 if opts.get('copies') and opts.get('rev'):
2154 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2154 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2155
2155
2156 df = False
2156 df = False
2157 if opts["date"]:
2157 if opts["date"]:
2158 df = util.matchdate(opts["date"])
2158 df = util.matchdate(opts["date"])
2159
2159
2160 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
2160 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
2161 def prep(ctx, fns):
2161 def prep(ctx, fns):
2162 rev = ctx.rev()
2162 rev = ctx.rev()
2163 parents = [p for p in repo.changelog.parentrevs(rev)
2163 parents = [p for p in repo.changelog.parentrevs(rev)
2164 if p != nullrev]
2164 if p != nullrev]
2165 if opts.get('no_merges') and len(parents) == 2:
2165 if opts.get('no_merges') and len(parents) == 2:
2166 return
2166 return
2167 if opts.get('only_merges') and len(parents) != 2:
2167 if opts.get('only_merges') and len(parents) != 2:
2168 return
2168 return
2169 if opts.get('only_branch') and ctx.branch() not in opts['only_branch']:
2169 if opts.get('only_branch') and ctx.branch() not in opts['only_branch']:
2170 return
2170 return
2171 if df and not df(ctx.date()[0]):
2171 if df and not df(ctx.date()[0]):
2172 return
2172 return
2173 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2173 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2174 return
2174 return
2175 if opts.get('keyword'):
2175 if opts.get('keyword'):
2176 for k in [kw.lower() for kw in opts['keyword']]:
2176 for k in [kw.lower() for kw in opts['keyword']]:
2177 if (k in ctx.user().lower() or
2177 if (k in ctx.user().lower() or
2178 k in ctx.description().lower() or
2178 k in ctx.description().lower() or
2179 k in " ".join(ctx.files()).lower()):
2179 k in " ".join(ctx.files()).lower()):
2180 break
2180 break
2181 else:
2181 else:
2182 return
2182 return
2183
2183
2184 copies = None
2184 copies = None
2185 if opts.get('copies') and rev:
2185 if opts.get('copies') and rev:
2186 copies = []
2186 copies = []
2187 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2187 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2188 for fn in ctx.files():
2188 for fn in ctx.files():
2189 rename = getrenamed(fn, rev)
2189 rename = getrenamed(fn, rev)
2190 if rename:
2190 if rename:
2191 copies.append((fn, rename[0]))
2191 copies.append((fn, rename[0]))
2192
2192
2193 displayer.show(ctx, copies=copies)
2193 displayer.show(ctx, copies=copies)
2194
2194
2195 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2195 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2196 if count == limit:
2196 if count == limit:
2197 break
2197 break
2198 if displayer.flush(ctx.rev()):
2198 if displayer.flush(ctx.rev()):
2199 count += 1
2199 count += 1
2200 displayer.close()
2200 displayer.close()
2201
2201
2202 def manifest(ui, repo, node=None, rev=None):
2202 def manifest(ui, repo, node=None, rev=None):
2203 """output the current or given revision of the project manifest
2203 """output the current or given revision of the project manifest
2204
2204
2205 Print a list of version controlled files for the given revision.
2205 Print a list of version controlled files for the given revision.
2206 If no revision is given, the first parent of the working directory
2206 If no revision is given, the first parent of the working directory
2207 is used, or the null revision if no revision is checked out.
2207 is used, or the null revision if no revision is checked out.
2208
2208
2209 With -v, print file permissions, symlink and executable bits.
2209 With -v, print file permissions, symlink and executable bits.
2210 With --debug, print file revision hashes.
2210 With --debug, print file revision hashes.
2211 """
2211 """
2212
2212
2213 if rev and node:
2213 if rev and node:
2214 raise util.Abort(_("please specify just one revision"))
2214 raise util.Abort(_("please specify just one revision"))
2215
2215
2216 if not node:
2216 if not node:
2217 node = rev
2217 node = rev
2218
2218
2219 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2219 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2220 ctx = repo[node]
2220 ctx = repo[node]
2221 for f in ctx:
2221 for f in ctx:
2222 if ui.debugflag:
2222 if ui.debugflag:
2223 ui.write("%40s " % hex(ctx.manifest()[f]))
2223 ui.write("%40s " % hex(ctx.manifest()[f]))
2224 if ui.verbose:
2224 if ui.verbose:
2225 ui.write(decor[ctx.flags(f)])
2225 ui.write(decor[ctx.flags(f)])
2226 ui.write("%s\n" % f)
2226 ui.write("%s\n" % f)
2227
2227
2228 def merge(ui, repo, node=None, **opts):
2228 def merge(ui, repo, node=None, **opts):
2229 """merge working directory with another revision
2229 """merge working directory with another revision
2230
2230
2231 The current working directory is updated with all changes made in
2231 The current working directory is updated with all changes made in
2232 the requested revision since the last common predecessor revision.
2232 the requested revision since the last common predecessor revision.
2233
2233
2234 Files that changed between either parent are marked as changed for
2234 Files that changed between either parent are marked as changed for
2235 the next commit and a commit must be performed before any further
2235 the next commit and a commit must be performed before any further
2236 updates to the repository are allowed. The next commit will have
2236 updates to the repository are allowed. The next commit will have
2237 two parents.
2237 two parents.
2238
2238
2239 If no revision is specified, the working directory's parent is a
2239 If no revision is specified, the working directory's parent is a
2240 head revision, and the current branch contains exactly one other
2240 head revision, and the current branch contains exactly one other
2241 head, the other head is merged with by default. Otherwise, an
2241 head, the other head is merged with by default. Otherwise, an
2242 explicit revision with which to merge with must be provided.
2242 explicit revision with which to merge with must be provided.
2243 """
2243 """
2244
2244
2245 if opts.get('rev') and node:
2245 if opts.get('rev') and node:
2246 raise util.Abort(_("please specify just one revision"))
2246 raise util.Abort(_("please specify just one revision"))
2247 if not node:
2247 if not node:
2248 node = opts.get('rev')
2248 node = opts.get('rev')
2249
2249
2250 if not node:
2250 if not node:
2251 branch = repo.changectx(None).branch()
2251 branch = repo.changectx(None).branch()
2252 bheads = repo.branchheads(branch)
2252 bheads = repo.branchheads(branch)
2253 if len(bheads) > 2:
2253 if len(bheads) > 2:
2254 ui.warn(_("abort: branch '%s' has %d heads - "
2254 ui.warn(_("abort: branch '%s' has %d heads - "
2255 "please merge with an explicit rev\n")
2255 "please merge with an explicit rev\n")
2256 % (branch, len(bheads)))
2256 % (branch, len(bheads)))
2257 ui.status(_("(run 'hg heads .' to see heads)\n"))
2257 ui.status(_("(run 'hg heads .' to see heads)\n"))
2258 return False
2258 return False
2259
2259
2260 parent = repo.dirstate.parents()[0]
2260 parent = repo.dirstate.parents()[0]
2261 if len(bheads) == 1:
2261 if len(bheads) == 1:
2262 if len(repo.heads()) > 1:
2262 if len(repo.heads()) > 1:
2263 ui.warn(_("abort: branch '%s' has one head - "
2263 ui.warn(_("abort: branch '%s' has one head - "
2264 "please merge with an explicit rev\n" % branch))
2264 "please merge with an explicit rev\n" % branch))
2265 ui.status(_("(run 'hg heads' to see all heads)\n"))
2265 ui.status(_("(run 'hg heads' to see all heads)\n"))
2266 return False
2266 return False
2267 msg = _('there is nothing to merge')
2267 msg = _('there is nothing to merge')
2268 if parent != repo.lookup(repo[None].branch()):
2268 if parent != repo.lookup(repo[None].branch()):
2269 msg = _('%s - use "hg update" instead') % msg
2269 msg = _('%s - use "hg update" instead') % msg
2270 raise util.Abort(msg)
2270 raise util.Abort(msg)
2271
2271
2272 if parent not in bheads:
2272 if parent not in bheads:
2273 raise util.Abort(_('working dir not at a head rev - '
2273 raise util.Abort(_('working dir not at a head rev - '
2274 'use "hg update" or merge with an explicit rev'))
2274 'use "hg update" or merge with an explicit rev'))
2275 node = parent == bheads[0] and bheads[-1] or bheads[0]
2275 node = parent == bheads[0] and bheads[-1] or bheads[0]
2276
2276
2277 if opts.get('preview'):
2277 if opts.get('preview'):
2278 # find nodes that are ancestors of p2 but not of p1
2278 # find nodes that are ancestors of p2 but not of p1
2279 p1 = repo.lookup('.')
2279 p1 = repo.lookup('.')
2280 p2 = repo.lookup(node)
2280 p2 = repo.lookup(node)
2281 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2281 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2282
2282
2283 displayer = cmdutil.show_changeset(ui, repo, opts)
2283 displayer = cmdutil.show_changeset(ui, repo, opts)
2284 for node in nodes:
2284 for node in nodes:
2285 displayer.show(repo[node])
2285 displayer.show(repo[node])
2286 displayer.close()
2286 displayer.close()
2287 return 0
2287 return 0
2288
2288
2289 return hg.merge(repo, node, force=opts.get('force'))
2289 return hg.merge(repo, node, force=opts.get('force'))
2290
2290
2291 def outgoing(ui, repo, dest=None, **opts):
2291 def outgoing(ui, repo, dest=None, **opts):
2292 """show changesets not found in the destination
2292 """show changesets not found in the destination
2293
2293
2294 Show changesets not found in the specified destination repository
2294 Show changesets not found in the specified destination repository
2295 or the default push location. These are the changesets that would
2295 or the default push location. These are the changesets that would
2296 be pushed if a push was requested.
2296 be pushed if a push was requested.
2297
2297
2298 See pull for details of valid destination formats.
2298 See pull for details of valid destination formats.
2299 """
2299 """
2300 limit = cmdutil.loglimit(opts)
2300 limit = cmdutil.loglimit(opts)
2301 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2301 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2302 dest, branches = hg.parseurl(dest, opts.get('branch'))
2302 dest, branches = hg.parseurl(dest, opts.get('branch'))
2303 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2303 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2304 if revs:
2304 if revs:
2305 revs = [repo.lookup(rev) for rev in revs]
2305 revs = [repo.lookup(rev) for rev in revs]
2306
2306
2307 other = hg.repository(cmdutil.remoteui(repo, opts), dest)
2307 other = hg.repository(cmdutil.remoteui(repo, opts), dest)
2308 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2308 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2309 o = repo.findoutgoing(other, force=opts.get('force'))
2309 o = repo.findoutgoing(other, force=opts.get('force'))
2310 if not o:
2310 if not o:
2311 ui.status(_("no changes found\n"))
2311 ui.status(_("no changes found\n"))
2312 return 1
2312 return 1
2313 o = repo.changelog.nodesbetween(o, revs)[0]
2313 o = repo.changelog.nodesbetween(o, revs)[0]
2314 if opts.get('newest_first'):
2314 if opts.get('newest_first'):
2315 o.reverse()
2315 o.reverse()
2316 displayer = cmdutil.show_changeset(ui, repo, opts)
2316 displayer = cmdutil.show_changeset(ui, repo, opts)
2317 count = 0
2317 count = 0
2318 for n in o:
2318 for n in o:
2319 if limit is not None and count >= limit:
2319 if limit is not None and count >= limit:
2320 break
2320 break
2321 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2321 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2322 if opts.get('no_merges') and len(parents) == 2:
2322 if opts.get('no_merges') and len(parents) == 2:
2323 continue
2323 continue
2324 count += 1
2324 count += 1
2325 displayer.show(repo[n])
2325 displayer.show(repo[n])
2326 displayer.close()
2326 displayer.close()
2327
2327
2328 def parents(ui, repo, file_=None, **opts):
2328 def parents(ui, repo, file_=None, **opts):
2329 """show the parents of the working directory or revision
2329 """show the parents of the working directory or revision
2330
2330
2331 Print the working directory's parent revisions. If a revision is
2331 Print the working directory's parent revisions. If a revision is
2332 given via -r/--rev, the parent of that revision will be printed.
2332 given via -r/--rev, the parent of that revision will be printed.
2333 If a file argument is given, the revision in which the file was
2333 If a file argument is given, the revision in which the file was
2334 last changed (before the working directory revision or the
2334 last changed (before the working directory revision or the
2335 argument to --rev if given) is printed.
2335 argument to --rev if given) is printed.
2336 """
2336 """
2337 rev = opts.get('rev')
2337 rev = opts.get('rev')
2338 if rev:
2338 if rev:
2339 ctx = repo[rev]
2339 ctx = repo[rev]
2340 else:
2340 else:
2341 ctx = repo[None]
2341 ctx = repo[None]
2342
2342
2343 if file_:
2343 if file_:
2344 m = cmdutil.match(repo, (file_,), opts)
2344 m = cmdutil.match(repo, (file_,), opts)
2345 if m.anypats() or len(m.files()) != 1:
2345 if m.anypats() or len(m.files()) != 1:
2346 raise util.Abort(_('can only specify an explicit filename'))
2346 raise util.Abort(_('can only specify an explicit filename'))
2347 file_ = m.files()[0]
2347 file_ = m.files()[0]
2348 filenodes = []
2348 filenodes = []
2349 for cp in ctx.parents():
2349 for cp in ctx.parents():
2350 if not cp:
2350 if not cp:
2351 continue
2351 continue
2352 try:
2352 try:
2353 filenodes.append(cp.filenode(file_))
2353 filenodes.append(cp.filenode(file_))
2354 except error.LookupError:
2354 except error.LookupError:
2355 pass
2355 pass
2356 if not filenodes:
2356 if not filenodes:
2357 raise util.Abort(_("'%s' not found in manifest!") % file_)
2357 raise util.Abort(_("'%s' not found in manifest!") % file_)
2358 fl = repo.file(file_)
2358 fl = repo.file(file_)
2359 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2359 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2360 else:
2360 else:
2361 p = [cp.node() for cp in ctx.parents()]
2361 p = [cp.node() for cp in ctx.parents()]
2362
2362
2363 displayer = cmdutil.show_changeset(ui, repo, opts)
2363 displayer = cmdutil.show_changeset(ui, repo, opts)
2364 for n in p:
2364 for n in p:
2365 if n != nullid:
2365 if n != nullid:
2366 displayer.show(repo[n])
2366 displayer.show(repo[n])
2367 displayer.close()
2367 displayer.close()
2368
2368
2369 def paths(ui, repo, search=None):
2369 def paths(ui, repo, search=None):
2370 """show aliases for remote repositories
2370 """show aliases for remote repositories
2371
2371
2372 Show definition of symbolic path name NAME. If no name is given,
2372 Show definition of symbolic path name NAME. If no name is given,
2373 show definition of all available names.
2373 show definition of all available names.
2374
2374
2375 Path names are defined in the [paths] section of /etc/mercurial/hgrc
2375 Path names are defined in the [paths] section of /etc/mercurial/hgrc
2376 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
2376 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
2377
2377
2378 See 'hg help urls' for more information.
2378 See 'hg help urls' for more information.
2379 """
2379 """
2380 if search:
2380 if search:
2381 for name, path in ui.configitems("paths"):
2381 for name, path in ui.configitems("paths"):
2382 if name == search:
2382 if name == search:
2383 ui.write("%s\n" % url.hidepassword(path))
2383 ui.write("%s\n" % url.hidepassword(path))
2384 return
2384 return
2385 ui.warn(_("not found!\n"))
2385 ui.warn(_("not found!\n"))
2386 return 1
2386 return 1
2387 else:
2387 else:
2388 for name, path in ui.configitems("paths"):
2388 for name, path in ui.configitems("paths"):
2389 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2389 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2390
2390
2391 def postincoming(ui, repo, modheads, optupdate, checkout):
2391 def postincoming(ui, repo, modheads, optupdate, checkout):
2392 if modheads == 0:
2392 if modheads == 0:
2393 return
2393 return
2394 if optupdate:
2394 if optupdate:
2395 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2395 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2396 return hg.update(repo, checkout)
2396 return hg.update(repo, checkout)
2397 else:
2397 else:
2398 ui.status(_("not updating, since new heads added\n"))
2398 ui.status(_("not updating, since new heads added\n"))
2399 if modheads > 1:
2399 if modheads > 1:
2400 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2400 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2401 else:
2401 else:
2402 ui.status(_("(run 'hg update' to get a working copy)\n"))
2402 ui.status(_("(run 'hg update' to get a working copy)\n"))
2403
2403
2404 def pull(ui, repo, source="default", **opts):
2404 def pull(ui, repo, source="default", **opts):
2405 """pull changes from the specified source
2405 """pull changes from the specified source
2406
2406
2407 Pull changes from a remote repository to a local one.
2407 Pull changes from a remote repository to a local one.
2408
2408
2409 This finds all changes from the repository at the specified path
2409 This finds all changes from the repository at the specified path
2410 or URL and adds them to a local repository (the current one unless
2410 or URL and adds them to a local repository (the current one unless
2411 -R is specified). By default, this does not update the copy of the
2411 -R is specified). By default, this does not update the copy of the
2412 project in the working directory.
2412 project in the working directory.
2413
2413
2414 Use hg incoming if you want to see what would have been added by a
2414 Use hg incoming if you want to see what would have been added by a
2415 pull at the time you issued this command. If you then decide to
2415 pull at the time you issued this command. If you then decide to
2416 added those changes to the repository, you should use pull -r X
2416 added those changes to the repository, you should use pull -r X
2417 where X is the last changeset listed by hg incoming.
2417 where X is the last changeset listed by hg incoming.
2418
2418
2419 If SOURCE is omitted, the 'default' path will be used.
2419 If SOURCE is omitted, the 'default' path will be used.
2420 See 'hg help urls' for more information.
2420 See 'hg help urls' for more information.
2421 """
2421 """
2422 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2422 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2423 other = hg.repository(cmdutil.remoteui(repo, opts), source)
2423 other = hg.repository(cmdutil.remoteui(repo, opts), source)
2424 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2424 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2425 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2425 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2426 if revs:
2426 if revs:
2427 try:
2427 try:
2428 revs = [other.lookup(rev) for rev in revs]
2428 revs = [other.lookup(rev) for rev in revs]
2429 except error.CapabilityError:
2429 except error.CapabilityError:
2430 err = _("Other repository doesn't support revision lookup, "
2430 err = _("Other repository doesn't support revision lookup, "
2431 "so a rev cannot be specified.")
2431 "so a rev cannot be specified.")
2432 raise util.Abort(err)
2432 raise util.Abort(err)
2433
2433
2434 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2434 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2435 if checkout:
2435 if checkout:
2436 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2436 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2437 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2437 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2438
2438
2439 def push(ui, repo, dest=None, **opts):
2439 def push(ui, repo, dest=None, **opts):
2440 """push changes to the specified destination
2440 """push changes to the specified destination
2441
2441
2442 Push changes from the local repository to the specified destination.
2442 Push changes from the local repository to the specified destination.
2443
2443
2444 This is the symmetrical operation for pull. It moves changes from
2444 This is the symmetrical operation for pull. It moves changes from
2445 the current repository to a different one. If the destination is
2445 the current repository to a different one. If the destination is
2446 local this is identical to a pull in that directory from the
2446 local this is identical to a pull in that directory from the
2447 current one.
2447 current one.
2448
2448
2449 By default, push will refuse to run if it detects the result would
2449 By default, push will refuse to run if it detects the result would
2450 increase the number of remote heads. This generally indicates the
2450 increase the number of remote heads. This generally indicates the
2451 user forgot to pull and merge before pushing.
2451 user forgot to pull and merge before pushing.
2452
2452
2453 If -r/--rev is used, the named revision and all its ancestors will
2453 If -r/--rev is used, the named revision and all its ancestors will
2454 be pushed to the remote repository.
2454 be pushed to the remote repository.
2455
2455
2456 Please see 'hg help urls' for important details about ``ssh://``
2456 Please see 'hg help urls' for important details about ``ssh://``
2457 URLs. If DESTINATION is omitted, a default path will be used.
2457 URLs. If DESTINATION is omitted, a default path will be used.
2458 """
2458 """
2459 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2459 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2460 dest, branches = hg.parseurl(dest, opts.get('branch'))
2460 dest, branches = hg.parseurl(dest, opts.get('branch'))
2461 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2461 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2462 other = hg.repository(cmdutil.remoteui(repo, opts), dest)
2462 other = hg.repository(cmdutil.remoteui(repo, opts), dest)
2463 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2463 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2464 if revs:
2464 if revs:
2465 revs = [repo.lookup(rev) for rev in revs]
2465 revs = [repo.lookup(rev) for rev in revs]
2466
2466
2467 # push subrepos depth-first for coherent ordering
2467 # push subrepos depth-first for coherent ordering
2468 c = repo['']
2468 c = repo['']
2469 subs = c.substate # only repos that are committed
2469 subs = c.substate # only repos that are committed
2470 for s in sorted(subs):
2470 for s in sorted(subs):
2471 c.sub(s).push(opts.get('force'))
2471 c.sub(s).push(opts.get('force'))
2472
2472
2473 r = repo.push(other, opts.get('force'), revs=revs)
2473 r = repo.push(other, opts.get('force'), revs=revs)
2474 return r == 0
2474 return r == 0
2475
2475
2476 def recover(ui, repo):
2476 def recover(ui, repo):
2477 """roll back an interrupted transaction
2477 """roll back an interrupted transaction
2478
2478
2479 Recover from an interrupted commit or pull.
2479 Recover from an interrupted commit or pull.
2480
2480
2481 This command tries to fix the repository status after an
2481 This command tries to fix the repository status after an
2482 interrupted operation. It should only be necessary when Mercurial
2482 interrupted operation. It should only be necessary when Mercurial
2483 suggests it.
2483 suggests it.
2484 """
2484 """
2485 if repo.recover():
2485 if repo.recover():
2486 return hg.verify(repo)
2486 return hg.verify(repo)
2487 return 1
2487 return 1
2488
2488
2489 def remove(ui, repo, *pats, **opts):
2489 def remove(ui, repo, *pats, **opts):
2490 """remove the specified files on the next commit
2490 """remove the specified files on the next commit
2491
2491
2492 Schedule the indicated files for removal from the repository.
2492 Schedule the indicated files for removal from the repository.
2493
2493
2494 This only removes files from the current branch, not from the
2494 This only removes files from the current branch, not from the
2495 entire project history. -A/--after can be used to remove only
2495 entire project history. -A/--after can be used to remove only
2496 files that have already been deleted, -f/--force can be used to
2496 files that have already been deleted, -f/--force can be used to
2497 force deletion, and -Af can be used to remove files from the next
2497 force deletion, and -Af can be used to remove files from the next
2498 revision without deleting them from the working directory.
2498 revision without deleting them from the working directory.
2499
2499
2500 The following table details the behavior of remove for different
2500 The following table details the behavior of remove for different
2501 file states (columns) and option combinations (rows). The file
2501 file states (columns) and option combinations (rows). The file
2502 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2502 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2503 reported by hg status). The actions are Warn, Remove (from branch)
2503 reported by hg status). The actions are Warn, Remove (from branch)
2504 and Delete (from disk)::
2504 and Delete (from disk)::
2505
2505
2506 A C M !
2506 A C M !
2507 none W RD W R
2507 none W RD W R
2508 -f R RD RD R
2508 -f R RD RD R
2509 -A W W W R
2509 -A W W W R
2510 -Af R R R R
2510 -Af R R R R
2511
2511
2512 This command schedules the files to be removed at the next commit.
2512 This command schedules the files to be removed at the next commit.
2513 To undo a remove before that, see hg revert.
2513 To undo a remove before that, see hg revert.
2514 """
2514 """
2515
2515
2516 after, force = opts.get('after'), opts.get('force')
2516 after, force = opts.get('after'), opts.get('force')
2517 if not pats and not after:
2517 if not pats and not after:
2518 raise util.Abort(_('no files specified'))
2518 raise util.Abort(_('no files specified'))
2519
2519
2520 m = cmdutil.match(repo, pats, opts)
2520 m = cmdutil.match(repo, pats, opts)
2521 s = repo.status(match=m, clean=True)
2521 s = repo.status(match=m, clean=True)
2522 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2522 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2523
2523
2524 for f in m.files():
2524 for f in m.files():
2525 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2525 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2526 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2526 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2527
2527
2528 def warn(files, reason):
2528 def warn(files, reason):
2529 for f in files:
2529 for f in files:
2530 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2530 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2531 % (m.rel(f), reason))
2531 % (m.rel(f), reason))
2532
2532
2533 if force:
2533 if force:
2534 remove, forget = modified + deleted + clean, added
2534 remove, forget = modified + deleted + clean, added
2535 elif after:
2535 elif after:
2536 remove, forget = deleted, []
2536 remove, forget = deleted, []
2537 warn(modified + added + clean, _('still exists'))
2537 warn(modified + added + clean, _('still exists'))
2538 else:
2538 else:
2539 remove, forget = deleted + clean, []
2539 remove, forget = deleted + clean, []
2540 warn(modified, _('is modified'))
2540 warn(modified, _('is modified'))
2541 warn(added, _('has been marked for add'))
2541 warn(added, _('has been marked for add'))
2542
2542
2543 for f in sorted(remove + forget):
2543 for f in sorted(remove + forget):
2544 if ui.verbose or not m.exact(f):
2544 if ui.verbose or not m.exact(f):
2545 ui.status(_('removing %s\n') % m.rel(f))
2545 ui.status(_('removing %s\n') % m.rel(f))
2546
2546
2547 repo.forget(forget)
2547 repo.forget(forget)
2548 repo.remove(remove, unlink=not after)
2548 repo.remove(remove, unlink=not after)
2549
2549
2550 def rename(ui, repo, *pats, **opts):
2550 def rename(ui, repo, *pats, **opts):
2551 """rename files; equivalent of copy + remove
2551 """rename files; equivalent of copy + remove
2552
2552
2553 Mark dest as copies of sources; mark sources for deletion. If dest
2553 Mark dest as copies of sources; mark sources for deletion. If dest
2554 is a directory, copies are put in that directory. If dest is a
2554 is a directory, copies are put in that directory. If dest is a
2555 file, there can only be one source.
2555 file, there can only be one source.
2556
2556
2557 By default, this command copies the contents of files as they
2557 By default, this command copies the contents of files as they
2558 exist in the working directory. If invoked with -A/--after, the
2558 exist in the working directory. If invoked with -A/--after, the
2559 operation is recorded, but no copying is performed.
2559 operation is recorded, but no copying is performed.
2560
2560
2561 This command takes effect at the next commit. To undo a rename
2561 This command takes effect at the next commit. To undo a rename
2562 before that, see hg revert.
2562 before that, see hg revert.
2563 """
2563 """
2564 wlock = repo.wlock(False)
2564 wlock = repo.wlock(False)
2565 try:
2565 try:
2566 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2566 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2567 finally:
2567 finally:
2568 wlock.release()
2568 wlock.release()
2569
2569
2570 def resolve(ui, repo, *pats, **opts):
2570 def resolve(ui, repo, *pats, **opts):
2571 """various operations to help finish a merge
2571 """various operations to help finish a merge
2572
2572
2573 This command includes several actions that are often useful while
2573 This command includes several actions that are often useful while
2574 performing a merge, after running ``merge`` but before running
2574 performing a merge, after running ``merge`` but before running
2575 ``commit``. (It is only meaningful if your working directory has
2575 ``commit``. (It is only meaningful if your working directory has
2576 two parents.) It is most relevant for merges with unresolved
2576 two parents.) It is most relevant for merges with unresolved
2577 conflicts, which are typically a result of non-interactive merging with
2577 conflicts, which are typically a result of non-interactive merging with
2578 ``internal:merge`` or a command-line merge tool like ``diff3``.
2578 ``internal:merge`` or a command-line merge tool like ``diff3``.
2579
2579
2580 The available actions are:
2580 The available actions are:
2581
2581
2582 1) list files that were merged with conflicts (U, for unresolved)
2582 1) list files that were merged with conflicts (U, for unresolved)
2583 and without conflicts (R, for resolved): ``hg resolve -l``
2583 and without conflicts (R, for resolved): ``hg resolve -l``
2584 (this is like ``status`` for merges)
2584 (this is like ``status`` for merges)
2585 2) record that you have resolved conflicts in certain files:
2585 2) record that you have resolved conflicts in certain files:
2586 ``hg resolve -m [file ...]`` (default: mark all unresolved files)
2586 ``hg resolve -m [file ...]`` (default: mark all unresolved files)
2587 3) forget that you have resolved conflicts in certain files:
2587 3) forget that you have resolved conflicts in certain files:
2588 ``hg resolve -u [file ...]`` (default: unmark all resolved files)
2588 ``hg resolve -u [file ...]`` (default: unmark all resolved files)
2589 4) discard your current attempt(s) at resolving conflicts and
2589 4) discard your current attempt(s) at resolving conflicts and
2590 restart the merge from scratch: ``hg resolve file...``
2590 restart the merge from scratch: ``hg resolve file...``
2591 (or ``-a`` for all unresolved files)
2591 (or ``-a`` for all unresolved files)
2592
2592
2593 Note that Mercurial will not let you commit files with unresolved merge
2593 Note that Mercurial will not let you commit files with unresolved merge
2594 conflicts. You must use ``hg resolve -m ...`` before you can commit
2594 conflicts. You must use ``hg resolve -m ...`` before you can commit
2595 after a conflicting merge.
2595 after a conflicting merge.
2596 """
2596 """
2597
2597
2598 all, mark, unmark, show, nostatus = \
2598 all, mark, unmark, show, nostatus = \
2599 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2599 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2600
2600
2601 if (show and (mark or unmark)) or (mark and unmark):
2601 if (show and (mark or unmark)) or (mark and unmark):
2602 raise util.Abort(_("too many options specified"))
2602 raise util.Abort(_("too many options specified"))
2603 if pats and all:
2603 if pats and all:
2604 raise util.Abort(_("can't specify --all and patterns"))
2604 raise util.Abort(_("can't specify --all and patterns"))
2605 if not (all or pats or show or mark or unmark):
2605 if not (all or pats or show or mark or unmark):
2606 raise util.Abort(_('no files or directories specified; '
2606 raise util.Abort(_('no files or directories specified; '
2607 'use --all to remerge all files'))
2607 'use --all to remerge all files'))
2608
2608
2609 ms = mergemod.mergestate(repo)
2609 ms = mergemod.mergestate(repo)
2610 m = cmdutil.match(repo, pats, opts)
2610 m = cmdutil.match(repo, pats, opts)
2611
2611
2612 for f in ms:
2612 for f in ms:
2613 if m(f):
2613 if m(f):
2614 if show:
2614 if show:
2615 if nostatus:
2615 if nostatus:
2616 ui.write("%s\n" % f)
2616 ui.write("%s\n" % f)
2617 else:
2617 else:
2618 ui.write("%s %s\n" % (ms[f].upper(), f),
2618 ui.write("%s %s\n" % (ms[f].upper(), f),
2619 label='resolve.' +
2619 label='resolve.' +
2620 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
2620 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
2621 elif mark:
2621 elif mark:
2622 ms.mark(f, "r")
2622 ms.mark(f, "r")
2623 elif unmark:
2623 elif unmark:
2624 ms.mark(f, "u")
2624 ms.mark(f, "u")
2625 else:
2625 else:
2626 wctx = repo[None]
2626 wctx = repo[None]
2627 mctx = wctx.parents()[-1]
2627 mctx = wctx.parents()[-1]
2628
2628
2629 # backup pre-resolve (merge uses .orig for its own purposes)
2629 # backup pre-resolve (merge uses .orig for its own purposes)
2630 a = repo.wjoin(f)
2630 a = repo.wjoin(f)
2631 util.copyfile(a, a + ".resolve")
2631 util.copyfile(a, a + ".resolve")
2632
2632
2633 # resolve file
2633 # resolve file
2634 ms.resolve(f, wctx, mctx)
2634 ms.resolve(f, wctx, mctx)
2635
2635
2636 # replace filemerge's .orig file with our resolve file
2636 # replace filemerge's .orig file with our resolve file
2637 util.rename(a + ".resolve", a + ".orig")
2637 util.rename(a + ".resolve", a + ".orig")
2638
2638
2639 def revert(ui, repo, *pats, **opts):
2639 def revert(ui, repo, *pats, **opts):
2640 """restore individual files or directories to an earlier state
2640 """restore individual files or directories to an earlier state
2641
2641
2642 (Use update -r to check out earlier revisions, revert does not
2642 (Use update -r to check out earlier revisions, revert does not
2643 change the working directory parents.)
2643 change the working directory parents.)
2644
2644
2645 With no revision specified, revert the named files or directories
2645 With no revision specified, revert the named files or directories
2646 to the contents they had in the parent of the working directory.
2646 to the contents they had in the parent of the working directory.
2647 This restores the contents of the affected files to an unmodified
2647 This restores the contents of the affected files to an unmodified
2648 state and unschedules adds, removes, copies, and renames. If the
2648 state and unschedules adds, removes, copies, and renames. If the
2649 working directory has two parents, you must explicitly specify a
2649 working directory has two parents, you must explicitly specify a
2650 revision.
2650 revision.
2651
2651
2652 Using the -r/--rev option, revert the given files or directories
2652 Using the -r/--rev option, revert the given files or directories
2653 to their contents as of a specific revision. This can be helpful
2653 to their contents as of a specific revision. This can be helpful
2654 to "roll back" some or all of an earlier change. See 'hg help
2654 to "roll back" some or all of an earlier change. See 'hg help
2655 dates' for a list of formats valid for -d/--date.
2655 dates' for a list of formats valid for -d/--date.
2656
2656
2657 Revert modifies the working directory. It does not commit any
2657 Revert modifies the working directory. It does not commit any
2658 changes, or change the parent of the working directory. If you
2658 changes, or change the parent of the working directory. If you
2659 revert to a revision other than the parent of the working
2659 revert to a revision other than the parent of the working
2660 directory, the reverted files will thus appear modified
2660 directory, the reverted files will thus appear modified
2661 afterwards.
2661 afterwards.
2662
2662
2663 If a file has been deleted, it is restored. If the executable mode
2663 If a file has been deleted, it is restored. If the executable mode
2664 of a file was changed, it is reset.
2664 of a file was changed, it is reset.
2665
2665
2666 If names are given, all files matching the names are reverted.
2666 If names are given, all files matching the names are reverted.
2667 If no arguments are given, no files are reverted.
2667 If no arguments are given, no files are reverted.
2668
2668
2669 Modified files are saved with a .orig suffix before reverting.
2669 Modified files are saved with a .orig suffix before reverting.
2670 To disable these backups, use --no-backup.
2670 To disable these backups, use --no-backup.
2671 """
2671 """
2672
2672
2673 if opts["date"]:
2673 if opts["date"]:
2674 if opts["rev"]:
2674 if opts["rev"]:
2675 raise util.Abort(_("you can't specify a revision and a date"))
2675 raise util.Abort(_("you can't specify a revision and a date"))
2676 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2676 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2677
2677
2678 if not pats and not opts.get('all'):
2678 if not pats and not opts.get('all'):
2679 raise util.Abort(_('no files or directories specified; '
2679 raise util.Abort(_('no files or directories specified; '
2680 'use --all to revert the whole repo'))
2680 'use --all to revert the whole repo'))
2681
2681
2682 parent, p2 = repo.dirstate.parents()
2682 parent, p2 = repo.dirstate.parents()
2683 if not opts.get('rev') and p2 != nullid:
2683 if not opts.get('rev') and p2 != nullid:
2684 raise util.Abort(_('uncommitted merge - please provide a '
2684 raise util.Abort(_('uncommitted merge - please provide a '
2685 'specific revision'))
2685 'specific revision'))
2686 ctx = repo[opts.get('rev')]
2686 ctx = repo[opts.get('rev')]
2687 node = ctx.node()
2687 node = ctx.node()
2688 mf = ctx.manifest()
2688 mf = ctx.manifest()
2689 if node == parent:
2689 if node == parent:
2690 pmf = mf
2690 pmf = mf
2691 else:
2691 else:
2692 pmf = None
2692 pmf = None
2693
2693
2694 # need all matching names in dirstate and manifest of target rev,
2694 # need all matching names in dirstate and manifest of target rev,
2695 # so have to walk both. do not print errors if files exist in one
2695 # so have to walk both. do not print errors if files exist in one
2696 # but not other.
2696 # but not other.
2697
2697
2698 names = {}
2698 names = {}
2699
2699
2700 wlock = repo.wlock()
2700 wlock = repo.wlock()
2701 try:
2701 try:
2702 # walk dirstate.
2702 # walk dirstate.
2703
2703
2704 m = cmdutil.match(repo, pats, opts)
2704 m = cmdutil.match(repo, pats, opts)
2705 m.bad = lambda x, y: False
2705 m.bad = lambda x, y: False
2706 for abs in repo.walk(m):
2706 for abs in repo.walk(m):
2707 names[abs] = m.rel(abs), m.exact(abs)
2707 names[abs] = m.rel(abs), m.exact(abs)
2708
2708
2709 # walk target manifest.
2709 # walk target manifest.
2710
2710
2711 def badfn(path, msg):
2711 def badfn(path, msg):
2712 if path in names:
2712 if path in names:
2713 return
2713 return
2714 path_ = path + '/'
2714 path_ = path + '/'
2715 for f in names:
2715 for f in names:
2716 if f.startswith(path_):
2716 if f.startswith(path_):
2717 return
2717 return
2718 ui.warn("%s: %s\n" % (m.rel(path), msg))
2718 ui.warn("%s: %s\n" % (m.rel(path), msg))
2719
2719
2720 m = cmdutil.match(repo, pats, opts)
2720 m = cmdutil.match(repo, pats, opts)
2721 m.bad = badfn
2721 m.bad = badfn
2722 for abs in repo[node].walk(m):
2722 for abs in repo[node].walk(m):
2723 if abs not in names:
2723 if abs not in names:
2724 names[abs] = m.rel(abs), m.exact(abs)
2724 names[abs] = m.rel(abs), m.exact(abs)
2725
2725
2726 m = cmdutil.matchfiles(repo, names)
2726 m = cmdutil.matchfiles(repo, names)
2727 changes = repo.status(match=m)[:4]
2727 changes = repo.status(match=m)[:4]
2728 modified, added, removed, deleted = map(set, changes)
2728 modified, added, removed, deleted = map(set, changes)
2729
2729
2730 # if f is a rename, also revert the source
2730 # if f is a rename, also revert the source
2731 cwd = repo.getcwd()
2731 cwd = repo.getcwd()
2732 for f in added:
2732 for f in added:
2733 src = repo.dirstate.copied(f)
2733 src = repo.dirstate.copied(f)
2734 if src and src not in names and repo.dirstate[src] == 'r':
2734 if src and src not in names and repo.dirstate[src] == 'r':
2735 removed.add(src)
2735 removed.add(src)
2736 names[src] = (repo.pathto(src, cwd), True)
2736 names[src] = (repo.pathto(src, cwd), True)
2737
2737
2738 def removeforget(abs):
2738 def removeforget(abs):
2739 if repo.dirstate[abs] == 'a':
2739 if repo.dirstate[abs] == 'a':
2740 return _('forgetting %s\n')
2740 return _('forgetting %s\n')
2741 return _('removing %s\n')
2741 return _('removing %s\n')
2742
2742
2743 revert = ([], _('reverting %s\n'))
2743 revert = ([], _('reverting %s\n'))
2744 add = ([], _('adding %s\n'))
2744 add = ([], _('adding %s\n'))
2745 remove = ([], removeforget)
2745 remove = ([], removeforget)
2746 undelete = ([], _('undeleting %s\n'))
2746 undelete = ([], _('undeleting %s\n'))
2747
2747
2748 disptable = (
2748 disptable = (
2749 # dispatch table:
2749 # dispatch table:
2750 # file state
2750 # file state
2751 # action if in target manifest
2751 # action if in target manifest
2752 # action if not in target manifest
2752 # action if not in target manifest
2753 # make backup if in target manifest
2753 # make backup if in target manifest
2754 # make backup if not in target manifest
2754 # make backup if not in target manifest
2755 (modified, revert, remove, True, True),
2755 (modified, revert, remove, True, True),
2756 (added, revert, remove, True, False),
2756 (added, revert, remove, True, False),
2757 (removed, undelete, None, False, False),
2757 (removed, undelete, None, False, False),
2758 (deleted, revert, remove, False, False),
2758 (deleted, revert, remove, False, False),
2759 )
2759 )
2760
2760
2761 for abs, (rel, exact) in sorted(names.items()):
2761 for abs, (rel, exact) in sorted(names.items()):
2762 mfentry = mf.get(abs)
2762 mfentry = mf.get(abs)
2763 target = repo.wjoin(abs)
2763 target = repo.wjoin(abs)
2764 def handle(xlist, dobackup):
2764 def handle(xlist, dobackup):
2765 xlist[0].append(abs)
2765 xlist[0].append(abs)
2766 if dobackup and not opts.get('no_backup') and util.lexists(target):
2766 if dobackup and not opts.get('no_backup') and util.lexists(target):
2767 bakname = "%s.orig" % rel
2767 bakname = "%s.orig" % rel
2768 ui.note(_('saving current version of %s as %s\n') %
2768 ui.note(_('saving current version of %s as %s\n') %
2769 (rel, bakname))
2769 (rel, bakname))
2770 if not opts.get('dry_run'):
2770 if not opts.get('dry_run'):
2771 util.copyfile(target, bakname)
2771 util.copyfile(target, bakname)
2772 if ui.verbose or not exact:
2772 if ui.verbose or not exact:
2773 msg = xlist[1]
2773 msg = xlist[1]
2774 if not isinstance(msg, basestring):
2774 if not isinstance(msg, basestring):
2775 msg = msg(abs)
2775 msg = msg(abs)
2776 ui.status(msg % rel)
2776 ui.status(msg % rel)
2777 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2777 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2778 if abs not in table:
2778 if abs not in table:
2779 continue
2779 continue
2780 # file has changed in dirstate
2780 # file has changed in dirstate
2781 if mfentry:
2781 if mfentry:
2782 handle(hitlist, backuphit)
2782 handle(hitlist, backuphit)
2783 elif misslist is not None:
2783 elif misslist is not None:
2784 handle(misslist, backupmiss)
2784 handle(misslist, backupmiss)
2785 break
2785 break
2786 else:
2786 else:
2787 if abs not in repo.dirstate:
2787 if abs not in repo.dirstate:
2788 if mfentry:
2788 if mfentry:
2789 handle(add, True)
2789 handle(add, True)
2790 elif exact:
2790 elif exact:
2791 ui.warn(_('file not managed: %s\n') % rel)
2791 ui.warn(_('file not managed: %s\n') % rel)
2792 continue
2792 continue
2793 # file has not changed in dirstate
2793 # file has not changed in dirstate
2794 if node == parent:
2794 if node == parent:
2795 if exact:
2795 if exact:
2796 ui.warn(_('no changes needed to %s\n') % rel)
2796 ui.warn(_('no changes needed to %s\n') % rel)
2797 continue
2797 continue
2798 if pmf is None:
2798 if pmf is None:
2799 # only need parent manifest in this unlikely case,
2799 # only need parent manifest in this unlikely case,
2800 # so do not read by default
2800 # so do not read by default
2801 pmf = repo[parent].manifest()
2801 pmf = repo[parent].manifest()
2802 if abs in pmf:
2802 if abs in pmf:
2803 if mfentry:
2803 if mfentry:
2804 # if version of file is same in parent and target
2804 # if version of file is same in parent and target
2805 # manifests, do nothing
2805 # manifests, do nothing
2806 if (pmf[abs] != mfentry or
2806 if (pmf[abs] != mfentry or
2807 pmf.flags(abs) != mf.flags(abs)):
2807 pmf.flags(abs) != mf.flags(abs)):
2808 handle(revert, False)
2808 handle(revert, False)
2809 else:
2809 else:
2810 handle(remove, False)
2810 handle(remove, False)
2811
2811
2812 if not opts.get('dry_run'):
2812 if not opts.get('dry_run'):
2813 def checkout(f):
2813 def checkout(f):
2814 fc = ctx[f]
2814 fc = ctx[f]
2815 repo.wwrite(f, fc.data(), fc.flags())
2815 repo.wwrite(f, fc.data(), fc.flags())
2816
2816
2817 audit_path = util.path_auditor(repo.root)
2817 audit_path = util.path_auditor(repo.root)
2818 for f in remove[0]:
2818 for f in remove[0]:
2819 if repo.dirstate[f] == 'a':
2819 if repo.dirstate[f] == 'a':
2820 repo.dirstate.forget(f)
2820 repo.dirstate.forget(f)
2821 continue
2821 continue
2822 audit_path(f)
2822 audit_path(f)
2823 try:
2823 try:
2824 util.unlink(repo.wjoin(f))
2824 util.unlink(repo.wjoin(f))
2825 except OSError:
2825 except OSError:
2826 pass
2826 pass
2827 repo.dirstate.remove(f)
2827 repo.dirstate.remove(f)
2828
2828
2829 normal = None
2829 normal = None
2830 if node == parent:
2830 if node == parent:
2831 # We're reverting to our parent. If possible, we'd like status
2831 # We're reverting to our parent. If possible, we'd like status
2832 # to report the file as clean. We have to use normallookup for
2832 # to report the file as clean. We have to use normallookup for
2833 # merges to avoid losing information about merged/dirty files.
2833 # merges to avoid losing information about merged/dirty files.
2834 if p2 != nullid:
2834 if p2 != nullid:
2835 normal = repo.dirstate.normallookup
2835 normal = repo.dirstate.normallookup
2836 else:
2836 else:
2837 normal = repo.dirstate.normal
2837 normal = repo.dirstate.normal
2838 for f in revert[0]:
2838 for f in revert[0]:
2839 checkout(f)
2839 checkout(f)
2840 if normal:
2840 if normal:
2841 normal(f)
2841 normal(f)
2842
2842
2843 for f in add[0]:
2843 for f in add[0]:
2844 checkout(f)
2844 checkout(f)
2845 repo.dirstate.add(f)
2845 repo.dirstate.add(f)
2846
2846
2847 normal = repo.dirstate.normallookup
2847 normal = repo.dirstate.normallookup
2848 if node == parent and p2 == nullid:
2848 if node == parent and p2 == nullid:
2849 normal = repo.dirstate.normal
2849 normal = repo.dirstate.normal
2850 for f in undelete[0]:
2850 for f in undelete[0]:
2851 checkout(f)
2851 checkout(f)
2852 normal(f)
2852 normal(f)
2853
2853
2854 finally:
2854 finally:
2855 wlock.release()
2855 wlock.release()
2856
2856
2857 def rollback(ui, repo):
2857 def rollback(ui, repo):
2858 """roll back the last transaction
2858 """roll back the last transaction
2859
2859
2860 This command should be used with care. There is only one level of
2860 This command should be used with care. There is only one level of
2861 rollback, and there is no way to undo a rollback. It will also
2861 rollback, and there is no way to undo a rollback. It will also
2862 restore the dirstate at the time of the last transaction, losing
2862 restore the dirstate at the time of the last transaction, losing
2863 any dirstate changes since that time. This command does not alter
2863 any dirstate changes since that time. This command does not alter
2864 the working directory.
2864 the working directory.
2865
2865
2866 Transactions are used to encapsulate the effects of all commands
2866 Transactions are used to encapsulate the effects of all commands
2867 that create new changesets or propagate existing changesets into a
2867 that create new changesets or propagate existing changesets into a
2868 repository. For example, the following commands are transactional,
2868 repository. For example, the following commands are transactional,
2869 and their effects can be rolled back:
2869 and their effects can be rolled back:
2870
2870
2871 - commit
2871 - commit
2872 - import
2872 - import
2873 - pull
2873 - pull
2874 - push (with this repository as the destination)
2874 - push (with this repository as the destination)
2875 - unbundle
2875 - unbundle
2876
2876
2877 This command is not intended for use on public repositories. Once
2877 This command is not intended for use on public repositories. Once
2878 changes are visible for pull by other users, rolling a transaction
2878 changes are visible for pull by other users, rolling a transaction
2879 back locally is ineffective (someone else may already have pulled
2879 back locally is ineffective (someone else may already have pulled
2880 the changes). Furthermore, a race is possible with readers of the
2880 the changes). Furthermore, a race is possible with readers of the
2881 repository; for example an in-progress pull from the repository
2881 repository; for example an in-progress pull from the repository
2882 may fail if a rollback is performed.
2882 may fail if a rollback is performed.
2883 """
2883 """
2884 repo.rollback()
2884 repo.rollback()
2885
2885
2886 def root(ui, repo):
2886 def root(ui, repo):
2887 """print the root (top) of the current working directory
2887 """print the root (top) of the current working directory
2888
2888
2889 Print the root directory of the current repository.
2889 Print the root directory of the current repository.
2890 """
2890 """
2891 ui.write(repo.root + "\n")
2891 ui.write(repo.root + "\n")
2892
2892
2893 def serve(ui, repo, **opts):
2893 def serve(ui, repo, **opts):
2894 """export the repository via HTTP
2894 """export the repository via HTTP
2895
2895
2896 Start a local HTTP repository browser and pull server.
2896 Start a local HTTP repository browser and pull server.
2897
2897
2898 By default, the server logs accesses to stdout and errors to
2898 By default, the server logs accesses to stdout and errors to
2899 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
2899 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
2900 files.
2900 files.
2901
2901
2902 To have the server choose a free port number to listen on, specify
2902 To have the server choose a free port number to listen on, specify
2903 a port number of 0; in this case, the server will print the port
2903 a port number of 0; in this case, the server will print the port
2904 number it uses.
2904 number it uses.
2905 """
2905 """
2906
2906
2907 if opts["stdio"]:
2907 if opts["stdio"]:
2908 if repo is None:
2908 if repo is None:
2909 raise error.RepoError(_("There is no Mercurial repository here"
2909 raise error.RepoError(_("There is no Mercurial repository here"
2910 " (.hg not found)"))
2910 " (.hg not found)"))
2911 s = sshserver.sshserver(ui, repo)
2911 s = sshserver.sshserver(ui, repo)
2912 s.serve_forever()
2912 s.serve_forever()
2913
2913
2914 # this way we can check if something was given in the command-line
2914 # this way we can check if something was given in the command-line
2915 if opts.get('port'):
2915 if opts.get('port'):
2916 opts['port'] = int(opts.get('port'))
2916 opts['port'] = int(opts.get('port'))
2917
2917
2918 baseui = repo and repo.baseui or ui
2918 baseui = repo and repo.baseui or ui
2919 optlist = ("name templates style address port prefix ipv6"
2919 optlist = ("name templates style address port prefix ipv6"
2920 " accesslog errorlog certificate encoding")
2920 " accesslog errorlog certificate encoding")
2921 for o in optlist.split():
2921 for o in optlist.split():
2922 val = opts.get(o, '')
2922 val = opts.get(o, '')
2923 if val in (None, ''): # should check against default options instead
2923 if val in (None, ''): # should check against default options instead
2924 continue
2924 continue
2925 baseui.setconfig("web", o, val)
2925 baseui.setconfig("web", o, val)
2926 if repo and repo.ui != baseui:
2926 if repo and repo.ui != baseui:
2927 repo.ui.setconfig("web", o, val)
2927 repo.ui.setconfig("web", o, val)
2928
2928
2929 if opts.get('webdir_conf'):
2929 if opts.get('webdir_conf'):
2930 app = hgwebdir_mod.hgwebdir(opts['webdir_conf'], ui)
2930 app = hgwebdir_mod.hgwebdir(opts['webdir_conf'], ui)
2931 elif repo is not None:
2931 elif repo is not None:
2932 app = hgweb_mod.hgweb(hg.repository(repo.ui, repo.root))
2932 app = hgweb_mod.hgweb(hg.repository(repo.ui, repo.root))
2933 else:
2933 else:
2934 raise error.RepoError(_("There is no Mercurial repository"
2934 raise error.RepoError(_("There is no Mercurial repository"
2935 " here (.hg not found)"))
2935 " here (.hg not found)"))
2936
2936
2937 class service(object):
2937 class service(object):
2938 def init(self):
2938 def init(self):
2939 util.set_signal_handler()
2939 util.set_signal_handler()
2940 self.httpd = server.create_server(ui, app)
2940 self.httpd = server.create_server(ui, app)
2941
2941
2942 if opts['port'] and not ui.verbose:
2942 if opts['port'] and not ui.verbose:
2943 return
2943 return
2944
2944
2945 if self.httpd.prefix:
2945 if self.httpd.prefix:
2946 prefix = self.httpd.prefix.strip('/') + '/'
2946 prefix = self.httpd.prefix.strip('/') + '/'
2947 else:
2947 else:
2948 prefix = ''
2948 prefix = ''
2949
2949
2950 port = ':%d' % self.httpd.port
2950 port = ':%d' % self.httpd.port
2951 if port == ':80':
2951 if port == ':80':
2952 port = ''
2952 port = ''
2953
2953
2954 bindaddr = self.httpd.addr
2954 bindaddr = self.httpd.addr
2955 if bindaddr == '0.0.0.0':
2955 if bindaddr == '0.0.0.0':
2956 bindaddr = '*'
2956 bindaddr = '*'
2957 elif ':' in bindaddr: # IPv6
2957 elif ':' in bindaddr: # IPv6
2958 bindaddr = '[%s]' % bindaddr
2958 bindaddr = '[%s]' % bindaddr
2959
2959
2960 fqaddr = self.httpd.fqaddr
2960 fqaddr = self.httpd.fqaddr
2961 if ':' in fqaddr:
2961 if ':' in fqaddr:
2962 fqaddr = '[%s]' % fqaddr
2962 fqaddr = '[%s]' % fqaddr
2963 if opts['port']:
2963 if opts['port']:
2964 write = ui.status
2964 write = ui.status
2965 else:
2965 else:
2966 write = ui.write
2966 write = ui.write
2967 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
2967 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
2968 (fqaddr, port, prefix, bindaddr, self.httpd.port))
2968 (fqaddr, port, prefix, bindaddr, self.httpd.port))
2969
2969
2970 def run(self):
2970 def run(self):
2971 self.httpd.serve_forever()
2971 self.httpd.serve_forever()
2972
2972
2973 service = service()
2973 service = service()
2974
2974
2975 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2975 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2976
2976
2977 def status(ui, repo, *pats, **opts):
2977 def status(ui, repo, *pats, **opts):
2978 """show changed files in the working directory
2978 """show changed files in the working directory
2979
2979
2980 Show status of files in the repository. If names are given, only
2980 Show status of files in the repository. If names are given, only
2981 files that match are shown. Files that are clean or ignored or
2981 files that match are shown. Files that are clean or ignored or
2982 the source of a copy/move operation, are not listed unless
2982 the source of a copy/move operation, are not listed unless
2983 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
2983 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
2984 Unless options described with "show only ..." are given, the
2984 Unless options described with "show only ..." are given, the
2985 options -mardu are used.
2985 options -mardu are used.
2986
2986
2987 Option -q/--quiet hides untracked (unknown and ignored) files
2987 Option -q/--quiet hides untracked (unknown and ignored) files
2988 unless explicitly requested with -u/--unknown or -i/--ignored.
2988 unless explicitly requested with -u/--unknown or -i/--ignored.
2989
2989
2990 NOTE: status may appear to disagree with diff if permissions have
2990 NOTE: status may appear to disagree with diff if permissions have
2991 changed or a merge has occurred. The standard diff format does not
2991 changed or a merge has occurred. The standard diff format does not
2992 report permission changes and diff only reports changes relative
2992 report permission changes and diff only reports changes relative
2993 to one merge parent.
2993 to one merge parent.
2994
2994
2995 If one revision is given, it is used as the base revision.
2995 If one revision is given, it is used as the base revision.
2996 If two revisions are given, the differences between them are
2996 If two revisions are given, the differences between them are
2997 shown. The --change option can also be used as a shortcut to list
2997 shown. The --change option can also be used as a shortcut to list
2998 the changed files of a revision from its first parent.
2998 the changed files of a revision from its first parent.
2999
2999
3000 The codes used to show the status of files are::
3000 The codes used to show the status of files are::
3001
3001
3002 M = modified
3002 M = modified
3003 A = added
3003 A = added
3004 R = removed
3004 R = removed
3005 C = clean
3005 C = clean
3006 ! = missing (deleted by non-hg command, but still tracked)
3006 ! = missing (deleted by non-hg command, but still tracked)
3007 ? = not tracked
3007 ? = not tracked
3008 I = ignored
3008 I = ignored
3009 = origin of the previous file listed as A (added)
3009 = origin of the previous file listed as A (added)
3010 """
3010 """
3011
3011
3012 revs = opts.get('rev')
3012 revs = opts.get('rev')
3013 change = opts.get('change')
3013 change = opts.get('change')
3014
3014
3015 if revs and change:
3015 if revs and change:
3016 msg = _('cannot specify --rev and --change at the same time')
3016 msg = _('cannot specify --rev and --change at the same time')
3017 raise util.Abort(msg)
3017 raise util.Abort(msg)
3018 elif change:
3018 elif change:
3019 node2 = repo.lookup(change)
3019 node2 = repo.lookup(change)
3020 node1 = repo[node2].parents()[0].node()
3020 node1 = repo[node2].parents()[0].node()
3021 else:
3021 else:
3022 node1, node2 = cmdutil.revpair(repo, revs)
3022 node1, node2 = cmdutil.revpair(repo, revs)
3023
3023
3024 cwd = (pats and repo.getcwd()) or ''
3024 cwd = (pats and repo.getcwd()) or ''
3025 end = opts.get('print0') and '\0' or '\n'
3025 end = opts.get('print0') and '\0' or '\n'
3026 copy = {}
3026 copy = {}
3027 states = 'modified added removed deleted unknown ignored clean'.split()
3027 states = 'modified added removed deleted unknown ignored clean'.split()
3028 show = [k for k in states if opts.get(k)]
3028 show = [k for k in states if opts.get(k)]
3029 if opts.get('all'):
3029 if opts.get('all'):
3030 show += ui.quiet and (states[:4] + ['clean']) or states
3030 show += ui.quiet and (states[:4] + ['clean']) or states
3031 if not show:
3031 if not show:
3032 show = ui.quiet and states[:4] or states[:5]
3032 show = ui.quiet and states[:4] or states[:5]
3033
3033
3034 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3034 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3035 'ignored' in show, 'clean' in show, 'unknown' in show)
3035 'ignored' in show, 'clean' in show, 'unknown' in show)
3036 changestates = zip(states, 'MAR!?IC', stat)
3036 changestates = zip(states, 'MAR!?IC', stat)
3037
3037
3038 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3038 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3039 ctxn = repo[nullid]
3039 ctxn = repo[nullid]
3040 ctx1 = repo[node1]
3040 ctx1 = repo[node1]
3041 ctx2 = repo[node2]
3041 ctx2 = repo[node2]
3042 added = stat[1]
3042 added = stat[1]
3043 if node2 is None:
3043 if node2 is None:
3044 added = stat[0] + stat[1] # merged?
3044 added = stat[0] + stat[1] # merged?
3045
3045
3046 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3046 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3047 if k in added:
3047 if k in added:
3048 copy[k] = v
3048 copy[k] = v
3049 elif v in added:
3049 elif v in added:
3050 copy[v] = k
3050 copy[v] = k
3051
3051
3052 for state, char, files in changestates:
3052 for state, char, files in changestates:
3053 if state in show:
3053 if state in show:
3054 format = "%s %%s%s" % (char, end)
3054 format = "%s %%s%s" % (char, end)
3055 if opts.get('no_status'):
3055 if opts.get('no_status'):
3056 format = "%%s%s" % end
3056 format = "%%s%s" % end
3057
3057
3058 for f in files:
3058 for f in files:
3059 ui.write(format % repo.pathto(f, cwd),
3059 ui.write(format % repo.pathto(f, cwd),
3060 label='status.' + state)
3060 label='status.' + state)
3061 if f in copy:
3061 if f in copy:
3062 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3062 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3063 label='status.copied')
3063 label='status.copied')
3064
3064
3065 def summary(ui, repo, **opts):
3065 def summary(ui, repo, **opts):
3066 """summarize working directory state
3066 """summarize working directory state
3067
3067
3068 This generates a brief summary of the working directory state,
3068 This generates a brief summary of the working directory state,
3069 including parents, branch, commit status, and available updates.
3069 including parents, branch, commit status, and available updates.
3070
3070
3071 With the --remote option, this will check the default paths for
3071 With the --remote option, this will check the default paths for
3072 incoming and outgoing changes. This can be time-consuming.
3072 incoming and outgoing changes. This can be time-consuming.
3073 """
3073 """
3074
3074
3075 ctx = repo[None]
3075 ctx = repo[None]
3076 parents = ctx.parents()
3076 parents = ctx.parents()
3077 pnode = parents[0].node()
3077 pnode = parents[0].node()
3078 tags = repo.tags()
3078 tags = repo.tags()
3079
3079
3080 for p in parents:
3080 for p in parents:
3081 t = ' '.join([t for t in tags if tags[t] == p.node()])
3081 t = ' '.join([t for t in tags if tags[t] == p.node()])
3082 if p.rev() == -1:
3082 if p.rev() == -1:
3083 if not len(repo):
3083 if not len(repo):
3084 t += _(' (empty repository)')
3084 t += _(' (empty repository)')
3085 else:
3085 else:
3086 t += _(' (no revision checked out)')
3086 t += _(' (no revision checked out)')
3087 ui.write(_('parent: %d:%s %s\n') % (p.rev(), str(p), t))
3087 ui.write(_('parent: %d:%s %s\n') % (p.rev(), str(p), t))
3088 if p.description():
3088 if p.description():
3089 ui.status(' ' + p.description().splitlines()[0].strip() + '\n')
3089 ui.status(' ' + p.description().splitlines()[0].strip() + '\n')
3090
3090
3091 branch = ctx.branch()
3091 branch = ctx.branch()
3092 bheads = repo.branchheads(branch)
3092 bheads = repo.branchheads(branch)
3093 m = _('branch: %s\n') % branch
3093 m = _('branch: %s\n') % branch
3094 if branch != 'default':
3094 if branch != 'default':
3095 ui.write(m)
3095 ui.write(m)
3096 else:
3096 else:
3097 ui.status(m)
3097 ui.status(m)
3098
3098
3099 st = list(repo.status(unknown=True))[:6]
3099 st = list(repo.status(unknown=True))[:6]
3100 ms = mergemod.mergestate(repo)
3100 ms = mergemod.mergestate(repo)
3101 st.append([f for f in ms if ms[f] == 'u'])
3101 st.append([f for f in ms if ms[f] == 'u'])
3102 labels = [_('%d modified'), _('%d added'), _('%d removed'),
3102 labels = [_('%d modified'), _('%d added'), _('%d removed'),
3103 _('%d deleted'), _('%d unknown'), _('%d ignored'),
3103 _('%d deleted'), _('%d unknown'), _('%d ignored'),
3104 _('%d unresolved')]
3104 _('%d unresolved')]
3105 t = []
3105 t = []
3106 for s, l in zip(st, labels):
3106 for s, l in zip(st, labels):
3107 if s:
3107 if s:
3108 t.append(l % len(s))
3108 t.append(l % len(s))
3109
3109
3110 t = ', '.join(t)
3110 t = ', '.join(t)
3111 cleanworkdir = False
3111 cleanworkdir = False
3112
3112
3113 if len(parents) > 1:
3113 if len(parents) > 1:
3114 t += _(' (merge)')
3114 t += _(' (merge)')
3115 elif branch != parents[0].branch():
3115 elif branch != parents[0].branch():
3116 t += _(' (new branch)')
3116 t += _(' (new branch)')
3117 elif (not st[0] and not st[1] and not st[2]):
3117 elif (not st[0] and not st[1] and not st[2]):
3118 t += _(' (clean)')
3118 t += _(' (clean)')
3119 cleanworkdir = True
3119 cleanworkdir = True
3120 elif pnode not in bheads:
3120 elif pnode not in bheads:
3121 t += _(' (new branch head)')
3121 t += _(' (new branch head)')
3122
3122
3123 if cleanworkdir:
3123 if cleanworkdir:
3124 ui.status(_('commit: %s\n') % t.strip())
3124 ui.status(_('commit: %s\n') % t.strip())
3125 else:
3125 else:
3126 ui.write(_('commit: %s\n') % t.strip())
3126 ui.write(_('commit: %s\n') % t.strip())
3127
3127
3128 # all ancestors of branch heads - all ancestors of parent = new csets
3128 # all ancestors of branch heads - all ancestors of parent = new csets
3129 new = [0] * len(repo)
3129 new = [0] * len(repo)
3130 cl = repo.changelog
3130 cl = repo.changelog
3131 for a in [cl.rev(n) for n in bheads]:
3131 for a in [cl.rev(n) for n in bheads]:
3132 new[a] = 1
3132 new[a] = 1
3133 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3133 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3134 new[a] = 1
3134 new[a] = 1
3135 for a in [p.rev() for p in parents]:
3135 for a in [p.rev() for p in parents]:
3136 if a >= 0:
3136 if a >= 0:
3137 new[a] = 0
3137 new[a] = 0
3138 for a in cl.ancestors(*[p.rev() for p in parents]):
3138 for a in cl.ancestors(*[p.rev() for p in parents]):
3139 new[a] = 0
3139 new[a] = 0
3140 new = sum(new)
3140 new = sum(new)
3141
3141
3142 if new == 0:
3142 if new == 0:
3143 ui.status(_('update: (current)\n'))
3143 ui.status(_('update: (current)\n'))
3144 elif pnode not in bheads:
3144 elif pnode not in bheads:
3145 ui.write(_('update: %d new changesets (update)\n') % new)
3145 ui.write(_('update: %d new changesets (update)\n') % new)
3146 else:
3146 else:
3147 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3147 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3148 (new, len(bheads)))
3148 (new, len(bheads)))
3149
3149
3150 if opts.get('remote'):
3150 if opts.get('remote'):
3151 t = []
3151 t = []
3152 source, branches = hg.parseurl(ui.expandpath('default'))
3152 source, branches = hg.parseurl(ui.expandpath('default'))
3153 other = hg.repository(cmdutil.remoteui(repo, {}), source)
3153 other = hg.repository(cmdutil.remoteui(repo, {}), source)
3154 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3154 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3155 ui.debug('comparing with %s\n' % url.hidepassword(source))
3155 ui.debug('comparing with %s\n' % url.hidepassword(source))
3156 repo.ui.pushbuffer()
3156 repo.ui.pushbuffer()
3157 common, incoming, rheads = repo.findcommonincoming(other)
3157 common, incoming, rheads = repo.findcommonincoming(other)
3158 repo.ui.popbuffer()
3158 repo.ui.popbuffer()
3159 if incoming:
3159 if incoming:
3160 t.append(_('1 or more incoming'))
3160 t.append(_('1 or more incoming'))
3161
3161
3162 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3162 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3163 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3163 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3164 other = hg.repository(cmdutil.remoteui(repo, {}), dest)
3164 other = hg.repository(cmdutil.remoteui(repo, {}), dest)
3165 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3165 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3166 repo.ui.pushbuffer()
3166 repo.ui.pushbuffer()
3167 o = repo.findoutgoing(other)
3167 o = repo.findoutgoing(other)
3168 repo.ui.popbuffer()
3168 repo.ui.popbuffer()
3169 o = repo.changelog.nodesbetween(o, None)[0]
3169 o = repo.changelog.nodesbetween(o, None)[0]
3170 if o:
3170 if o:
3171 t.append(_('%d outgoing') % len(o))
3171 t.append(_('%d outgoing') % len(o))
3172
3172
3173 if t:
3173 if t:
3174 ui.write(_('remote: %s\n') % (', '.join(t)))
3174 ui.write(_('remote: %s\n') % (', '.join(t)))
3175 else:
3175 else:
3176 ui.status(_('remote: (synced)\n'))
3176 ui.status(_('remote: (synced)\n'))
3177
3177
3178 def tag(ui, repo, name1, *names, **opts):
3178 def tag(ui, repo, name1, *names, **opts):
3179 """add one or more tags for the current or given revision
3179 """add one or more tags for the current or given revision
3180
3180
3181 Name a particular revision using <name>.
3181 Name a particular revision using <name>.
3182
3182
3183 Tags are used to name particular revisions of the repository and are
3183 Tags are used to name particular revisions of the repository and are
3184 very useful to compare different revisions, to go back to significant
3184 very useful to compare different revisions, to go back to significant
3185 earlier versions or to mark branch points as releases, etc.
3185 earlier versions or to mark branch points as releases, etc.
3186
3186
3187 If no revision is given, the parent of the working directory is
3187 If no revision is given, the parent of the working directory is
3188 used, or tip if no revision is checked out.
3188 used, or tip if no revision is checked out.
3189
3189
3190 To facilitate version control, distribution, and merging of tags,
3190 To facilitate version control, distribution, and merging of tags,
3191 they are stored as a file named ".hgtags" which is managed
3191 they are stored as a file named ".hgtags" which is managed
3192 similarly to other project files and can be hand-edited if
3192 similarly to other project files and can be hand-edited if
3193 necessary. The file '.hg/localtags' is used for local tags (not
3193 necessary. The file '.hg/localtags' is used for local tags (not
3194 shared among repositories).
3194 shared among repositories).
3195
3195
3196 See 'hg help dates' for a list of formats valid for -d/--date.
3196 See 'hg help dates' for a list of formats valid for -d/--date.
3197 """
3197 """
3198
3198
3199 rev_ = "."
3199 rev_ = "."
3200 names = (name1,) + names
3200 names = (name1,) + names
3201 if len(names) != len(set(names)):
3201 if len(names) != len(set(names)):
3202 raise util.Abort(_('tag names must be unique'))
3202 raise util.Abort(_('tag names must be unique'))
3203 for n in names:
3203 for n in names:
3204 if n in ['tip', '.', 'null']:
3204 if n in ['tip', '.', 'null']:
3205 raise util.Abort(_('the name \'%s\' is reserved') % n)
3205 raise util.Abort(_('the name \'%s\' is reserved') % n)
3206 if opts.get('rev') and opts.get('remove'):
3206 if opts.get('rev') and opts.get('remove'):
3207 raise util.Abort(_("--rev and --remove are incompatible"))
3207 raise util.Abort(_("--rev and --remove are incompatible"))
3208 if opts.get('rev'):
3208 if opts.get('rev'):
3209 rev_ = opts['rev']
3209 rev_ = opts['rev']
3210 message = opts.get('message')
3210 message = opts.get('message')
3211 if opts.get('remove'):
3211 if opts.get('remove'):
3212 expectedtype = opts.get('local') and 'local' or 'global'
3212 expectedtype = opts.get('local') and 'local' or 'global'
3213 for n in names:
3213 for n in names:
3214 if not repo.tagtype(n):
3214 if not repo.tagtype(n):
3215 raise util.Abort(_('tag \'%s\' does not exist') % n)
3215 raise util.Abort(_('tag \'%s\' does not exist') % n)
3216 if repo.tagtype(n) != expectedtype:
3216 if repo.tagtype(n) != expectedtype:
3217 if expectedtype == 'global':
3217 if expectedtype == 'global':
3218 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3218 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3219 else:
3219 else:
3220 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3220 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3221 rev_ = nullid
3221 rev_ = nullid
3222 if not message:
3222 if not message:
3223 # we don't translate commit messages
3223 # we don't translate commit messages
3224 message = 'Removed tag %s' % ', '.join(names)
3224 message = 'Removed tag %s' % ', '.join(names)
3225 elif not opts.get('force'):
3225 elif not opts.get('force'):
3226 for n in names:
3226 for n in names:
3227 if n in repo.tags():
3227 if n in repo.tags():
3228 raise util.Abort(_('tag \'%s\' already exists '
3228 raise util.Abort(_('tag \'%s\' already exists '
3229 '(use -f to force)') % n)
3229 '(use -f to force)') % n)
3230 if not rev_ and repo.dirstate.parents()[1] != nullid:
3230 if not rev_ and repo.dirstate.parents()[1] != nullid:
3231 raise util.Abort(_('uncommitted merge - please provide a '
3231 raise util.Abort(_('uncommitted merge - please provide a '
3232 'specific revision'))
3232 'specific revision'))
3233 r = repo[rev_].node()
3233 r = repo[rev_].node()
3234
3234
3235 if not message:
3235 if not message:
3236 # we don't translate commit messages
3236 # we don't translate commit messages
3237 message = ('Added tag %s for changeset %s' %
3237 message = ('Added tag %s for changeset %s' %
3238 (', '.join(names), short(r)))
3238 (', '.join(names), short(r)))
3239
3239
3240 date = opts.get('date')
3240 date = opts.get('date')
3241 if date:
3241 if date:
3242 date = util.parsedate(date)
3242 date = util.parsedate(date)
3243
3243
3244 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3244 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3245
3245
3246 def tags(ui, repo):
3246 def tags(ui, repo):
3247 """list repository tags
3247 """list repository tags
3248
3248
3249 This lists both regular and local tags. When the -v/--verbose
3249 This lists both regular and local tags. When the -v/--verbose
3250 switch is used, a third column "local" is printed for local tags.
3250 switch is used, a third column "local" is printed for local tags.
3251 """
3251 """
3252
3252
3253 hexfunc = ui.debugflag and hex or short
3253 hexfunc = ui.debugflag and hex or short
3254 tagtype = ""
3254 tagtype = ""
3255
3255
3256 for t, n in reversed(repo.tagslist()):
3256 for t, n in reversed(repo.tagslist()):
3257 if ui.quiet:
3257 if ui.quiet:
3258 ui.write("%s\n" % t)
3258 ui.write("%s\n" % t)
3259 continue
3259 continue
3260
3260
3261 try:
3261 try:
3262 hn = hexfunc(n)
3262 hn = hexfunc(n)
3263 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3263 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3264 except error.LookupError:
3264 except error.LookupError:
3265 r = " ?:%s" % hn
3265 r = " ?:%s" % hn
3266 else:
3266 else:
3267 spaces = " " * (30 - encoding.colwidth(t))
3267 spaces = " " * (30 - encoding.colwidth(t))
3268 if ui.verbose:
3268 if ui.verbose:
3269 if repo.tagtype(t) == 'local':
3269 if repo.tagtype(t) == 'local':
3270 tagtype = " local"
3270 tagtype = " local"
3271 else:
3271 else:
3272 tagtype = ""
3272 tagtype = ""
3273 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3273 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3274
3274
3275 def tip(ui, repo, **opts):
3275 def tip(ui, repo, **opts):
3276 """show the tip revision
3276 """show the tip revision
3277
3277
3278 The tip revision (usually just called the tip) is the changeset
3278 The tip revision (usually just called the tip) is the changeset
3279 most recently added to the repository (and therefore the most
3279 most recently added to the repository (and therefore the most
3280 recently changed head).
3280 recently changed head).
3281
3281
3282 If you have just made a commit, that commit will be the tip. If
3282 If you have just made a commit, that commit will be the tip. If
3283 you have just pulled changes from another repository, the tip of
3283 you have just pulled changes from another repository, the tip of
3284 that repository becomes the current tip. The "tip" tag is special
3284 that repository becomes the current tip. The "tip" tag is special
3285 and cannot be renamed or assigned to a different changeset.
3285 and cannot be renamed or assigned to a different changeset.
3286 """
3286 """
3287 displayer = cmdutil.show_changeset(ui, repo, opts)
3287 displayer = cmdutil.show_changeset(ui, repo, opts)
3288 displayer.show(repo[len(repo) - 1])
3288 displayer.show(repo[len(repo) - 1])
3289 displayer.close()
3289 displayer.close()
3290
3290
3291 def unbundle(ui, repo, fname1, *fnames, **opts):
3291 def unbundle(ui, repo, fname1, *fnames, **opts):
3292 """apply one or more changegroup files
3292 """apply one or more changegroup files
3293
3293
3294 Apply one or more compressed changegroup files generated by the
3294 Apply one or more compressed changegroup files generated by the
3295 bundle command.
3295 bundle command.
3296 """
3296 """
3297 fnames = (fname1,) + fnames
3297 fnames = (fname1,) + fnames
3298
3298
3299 lock = repo.lock()
3299 lock = repo.lock()
3300 try:
3300 try:
3301 for fname in fnames:
3301 for fname in fnames:
3302 f = url.open(ui, fname)
3302 f = url.open(ui, fname)
3303 gen = changegroup.readbundle(f, fname)
3303 gen = changegroup.readbundle(f, fname)
3304 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
3304 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
3305 finally:
3305 finally:
3306 lock.release()
3306 lock.release()
3307
3307
3308 return postincoming(ui, repo, modheads, opts.get('update'), None)
3308 return postincoming(ui, repo, modheads, opts.get('update'), None)
3309
3309
3310 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3310 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3311 """update working directory
3311 """update working directory
3312
3312
3313 Update the repository's working directory to the specified
3313 Update the repository's working directory to the specified
3314 changeset.
3314 changeset.
3315
3315
3316 If no changeset is specified, attempt to update to the head of the
3316 If no changeset is specified, attempt to update to the head of the
3317 current branch. If this head is a descendant of the working
3317 current branch. If this head is a descendant of the working
3318 directory's parent, update to it, otherwise abort.
3318 directory's parent, update to it, otherwise abort.
3319
3319
3320 The following rules apply when the working directory contains
3320 The following rules apply when the working directory contains
3321 uncommitted changes:
3321 uncommitted changes:
3322
3322
3323 1. If neither -c/--check nor -C/--clean is specified, and if
3323 1. If neither -c/--check nor -C/--clean is specified, and if
3324 the requested changeset is an ancestor or descendant of
3324 the requested changeset is an ancestor or descendant of
3325 the working directory's parent, the uncommitted changes
3325 the working directory's parent, the uncommitted changes
3326 are merged into the requested changeset and the merged
3326 are merged into the requested changeset and the merged
3327 result is left uncommitted. If the requested changeset is
3327 result is left uncommitted. If the requested changeset is
3328 not an ancestor or descendant (that is, it is on another
3328 not an ancestor or descendant (that is, it is on another
3329 branch), the update is aborted and the uncommitted changes
3329 branch), the update is aborted and the uncommitted changes
3330 are preserved.
3330 are preserved.
3331
3331
3332 2. With the -c/--check option, the update is aborted and the
3332 2. With the -c/--check option, the update is aborted and the
3333 uncommitted changes are preserved.
3333 uncommitted changes are preserved.
3334
3334
3335 3. With the -C/--clean option, uncommitted changes are discarded and
3335 3. With the -C/--clean option, uncommitted changes are discarded and
3336 the working directory is updated to the requested changeset.
3336 the working directory is updated to the requested changeset.
3337
3337
3338 Use null as the changeset to remove the working directory (like 'hg
3338 Use null as the changeset to remove the working directory (like 'hg
3339 clone -U').
3339 clone -U').
3340
3340
3341 If you want to update just one file to an older changeset, use 'hg revert'.
3341 If you want to update just one file to an older changeset, use 'hg revert'.
3342
3342
3343 See 'hg help dates' for a list of formats valid for -d/--date.
3343 See 'hg help dates' for a list of formats valid for -d/--date.
3344 """
3344 """
3345 if rev and node:
3345 if rev and node:
3346 raise util.Abort(_("please specify just one revision"))
3346 raise util.Abort(_("please specify just one revision"))
3347
3347
3348 if not rev:
3348 if not rev:
3349 rev = node
3349 rev = node
3350
3350
3351 if check and clean:
3351 if check and clean:
3352 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3352 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3353
3353
3354 if check:
3354 if check:
3355 # we could use dirty() but we can ignore merge and branch trivia
3355 # we could use dirty() but we can ignore merge and branch trivia
3356 c = repo[None]
3356 c = repo[None]
3357 if c.modified() or c.added() or c.removed():
3357 if c.modified() or c.added() or c.removed():
3358 raise util.Abort(_("uncommitted local changes"))
3358 raise util.Abort(_("uncommitted local changes"))
3359
3359
3360 if date:
3360 if date:
3361 if rev:
3361 if rev:
3362 raise util.Abort(_("you can't specify a revision and a date"))
3362 raise util.Abort(_("you can't specify a revision and a date"))
3363 rev = cmdutil.finddate(ui, repo, date)
3363 rev = cmdutil.finddate(ui, repo, date)
3364
3364
3365 if clean or check:
3365 if clean or check:
3366 return hg.clean(repo, rev)
3366 return hg.clean(repo, rev)
3367 else:
3367 else:
3368 return hg.update(repo, rev)
3368 return hg.update(repo, rev)
3369
3369
3370 def verify(ui, repo):
3370 def verify(ui, repo):
3371 """verify the integrity of the repository
3371 """verify the integrity of the repository
3372
3372
3373 Verify the integrity of the current repository.
3373 Verify the integrity of the current repository.
3374
3374
3375 This will perform an extensive check of the repository's
3375 This will perform an extensive check of the repository's
3376 integrity, validating the hashes and checksums of each entry in
3376 integrity, validating the hashes and checksums of each entry in
3377 the changelog, manifest, and tracked files, as well as the
3377 the changelog, manifest, and tracked files, as well as the
3378 integrity of their crosslinks and indices.
3378 integrity of their crosslinks and indices.
3379 """
3379 """
3380 return hg.verify(repo)
3380 return hg.verify(repo)
3381
3381
3382 def version_(ui):
3382 def version_(ui):
3383 """output version and copyright information"""
3383 """output version and copyright information"""
3384 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3384 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3385 % util.version())
3385 % util.version())
3386 ui.status(_(
3386 ui.status(_(
3387 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3387 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3388 "This is free software; see the source for copying conditions. "
3388 "This is free software; see the source for copying conditions. "
3389 "There is NO\nwarranty; "
3389 "There is NO\nwarranty; "
3390 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3390 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3391 ))
3391 ))
3392
3392
3393 # Command options and aliases are listed here, alphabetically
3393 # Command options and aliases are listed here, alphabetically
3394
3394
3395 globalopts = [
3395 globalopts = [
3396 ('R', 'repository', '',
3396 ('R', 'repository', '',
3397 _('repository root directory or name of overlay bundle file')),
3397 _('repository root directory or name of overlay bundle file')),
3398 ('', 'cwd', '', _('change working directory')),
3398 ('', 'cwd', '', _('change working directory')),
3399 ('y', 'noninteractive', None,
3399 ('y', 'noninteractive', None,
3400 _('do not prompt, assume \'yes\' for any required answers')),
3400 _('do not prompt, assume \'yes\' for any required answers')),
3401 ('q', 'quiet', None, _('suppress output')),
3401 ('q', 'quiet', None, _('suppress output')),
3402 ('v', 'verbose', None, _('enable additional output')),
3402 ('v', 'verbose', None, _('enable additional output')),
3403 ('', 'config', [],
3403 ('', 'config', [],
3404 _('set/override config option (use \'section.name=value\')')),
3404 _('set/override config option (use \'section.name=value\')')),
3405 ('', 'debug', None, _('enable debugging output')),
3405 ('', 'debug', None, _('enable debugging output')),
3406 ('', 'debugger', None, _('start debugger')),
3406 ('', 'debugger', None, _('start debugger')),
3407 ('', 'encoding', encoding.encoding, _('set the charset encoding')),
3407 ('', 'encoding', encoding.encoding, _('set the charset encoding')),
3408 ('', 'encodingmode', encoding.encodingmode,
3408 ('', 'encodingmode', encoding.encodingmode,
3409 _('set the charset encoding mode')),
3409 _('set the charset encoding mode')),
3410 ('', 'traceback', None, _('always print a traceback on exception')),
3410 ('', 'traceback', None, _('always print a traceback on exception')),
3411 ('', 'time', None, _('time how long the command takes')),
3411 ('', 'time', None, _('time how long the command takes')),
3412 ('', 'profile', None, _('print command execution profile')),
3412 ('', 'profile', None, _('print command execution profile')),
3413 ('', 'version', None, _('output version information and exit')),
3413 ('', 'version', None, _('output version information and exit')),
3414 ('h', 'help', None, _('display help and exit')),
3414 ('h', 'help', None, _('display help and exit')),
3415 ]
3415 ]
3416
3416
3417 dryrunopts = [('n', 'dry-run', None,
3417 dryrunopts = [('n', 'dry-run', None,
3418 _('do not perform actions, just print output'))]
3418 _('do not perform actions, just print output'))]
3419
3419
3420 remoteopts = [
3420 remoteopts = [
3421 ('e', 'ssh', '', _('specify ssh command to use')),
3421 ('e', 'ssh', '', _('specify ssh command to use')),
3422 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
3422 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
3423 ]
3423 ]
3424
3424
3425 walkopts = [
3425 walkopts = [
3426 ('I', 'include', [], _('include names matching the given patterns')),
3426 ('I', 'include', [], _('include names matching the given patterns')),
3427 ('X', 'exclude', [], _('exclude names matching the given patterns')),
3427 ('X', 'exclude', [], _('exclude names matching the given patterns')),
3428 ]
3428 ]
3429
3429
3430 commitopts = [
3430 commitopts = [
3431 ('m', 'message', '', _('use <text> as commit message')),
3431 ('m', 'message', '', _('use <text> as commit message')),
3432 ('l', 'logfile', '', _('read commit message from <file>')),
3432 ('l', 'logfile', '', _('read commit message from <file>')),
3433 ]
3433 ]
3434
3434
3435 commitopts2 = [
3435 commitopts2 = [
3436 ('d', 'date', '', _('record datecode as commit date')),
3436 ('d', 'date', '', _('record datecode as commit date')),
3437 ('u', 'user', '', _('record the specified user as committer')),
3437 ('u', 'user', '', _('record the specified user as committer')),
3438 ]
3438 ]
3439
3439
3440 templateopts = [
3440 templateopts = [
3441 ('', 'style', '', _('display using template map file')),
3441 ('', 'style', '', _('display using template map file')),
3442 ('', 'template', '', _('display with template')),
3442 ('', 'template', '', _('display with template')),
3443 ]
3443 ]
3444
3444
3445 logopts = [
3445 logopts = [
3446 ('p', 'patch', None, _('show patch')),
3446 ('p', 'patch', None, _('show patch')),
3447 ('g', 'git', None, _('use git extended diff format')),
3447 ('g', 'git', None, _('use git extended diff format')),
3448 ('l', 'limit', '', _('limit number of changes displayed')),
3448 ('l', 'limit', '', _('limit number of changes displayed')),
3449 ('M', 'no-merges', None, _('do not show merges')),
3449 ('M', 'no-merges', None, _('do not show merges')),
3450 ] + templateopts
3450 ] + templateopts
3451
3451
3452 diffopts = [
3452 diffopts = [
3453 ('a', 'text', None, _('treat all files as text')),
3453 ('a', 'text', None, _('treat all files as text')),
3454 ('g', 'git', None, _('use git extended diff format')),
3454 ('g', 'git', None, _('use git extended diff format')),
3455 ('', 'nodates', None, _('omit dates from diff headers'))
3455 ('', 'nodates', None, _('omit dates from diff headers'))
3456 ]
3456 ]
3457
3457
3458 diffopts2 = [
3458 diffopts2 = [
3459 ('p', 'show-function', None, _('show which function each change is in')),
3459 ('p', 'show-function', None, _('show which function each change is in')),
3460 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3460 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3461 ('w', 'ignore-all-space', None,
3461 ('w', 'ignore-all-space', None,
3462 _('ignore white space when comparing lines')),
3462 _('ignore white space when comparing lines')),
3463 ('b', 'ignore-space-change', None,
3463 ('b', 'ignore-space-change', None,
3464 _('ignore changes in the amount of white space')),
3464 _('ignore changes in the amount of white space')),
3465 ('B', 'ignore-blank-lines', None,
3465 ('B', 'ignore-blank-lines', None,
3466 _('ignore changes whose lines are all blank')),
3466 _('ignore changes whose lines are all blank')),
3467 ('U', 'unified', '', _('number of lines of context to show')),
3467 ('U', 'unified', '', _('number of lines of context to show')),
3468 ('', 'stat', None, _('output diffstat-style summary of changes')),
3468 ('', 'stat', None, _('output diffstat-style summary of changes')),
3469 ]
3469 ]
3470
3470
3471 similarityopts = [
3471 similarityopts = [
3472 ('s', 'similarity', '',
3472 ('s', 'similarity', '',
3473 _('guess renamed files by similarity (0<=s<=100)'))
3473 _('guess renamed files by similarity (0<=s<=100)'))
3474 ]
3474 ]
3475
3475
3476 table = {
3476 table = {
3477 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3477 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3478 "addremove":
3478 "addremove":
3479 (addremove, similarityopts + walkopts + dryrunopts,
3479 (addremove, similarityopts + walkopts + dryrunopts,
3480 _('[OPTION]... [FILE]...')),
3480 _('[OPTION]... [FILE]...')),
3481 "^annotate|blame":
3481 "^annotate|blame":
3482 (annotate,
3482 (annotate,
3483 [('r', 'rev', '', _('annotate the specified revision')),
3483 [('r', 'rev', '', _('annotate the specified revision')),
3484 ('', 'follow', None,
3484 ('', 'follow', None,
3485 _('follow copies/renames and list the filename (DEPRECATED)')),
3485 _('follow copies/renames and list the filename (DEPRECATED)')),
3486 ('', 'no-follow', None, _("don't follow copies and renames")),
3486 ('', 'no-follow', None, _("don't follow copies and renames")),
3487 ('a', 'text', None, _('treat all files as text')),
3487 ('a', 'text', None, _('treat all files as text')),
3488 ('u', 'user', None, _('list the author (long with -v)')),
3488 ('u', 'user', None, _('list the author (long with -v)')),
3489 ('f', 'file', None, _('list the filename')),
3489 ('f', 'file', None, _('list the filename')),
3490 ('d', 'date', None, _('list the date (short with -q)')),
3490 ('d', 'date', None, _('list the date (short with -q)')),
3491 ('n', 'number', None, _('list the revision number (default)')),
3491 ('n', 'number', None, _('list the revision number (default)')),
3492 ('c', 'changeset', None, _('list the changeset')),
3492 ('c', 'changeset', None, _('list the changeset')),
3493 ('l', 'line-number', None,
3493 ('l', 'line-number', None,
3494 _('show line number at the first appearance'))
3494 _('show line number at the first appearance'))
3495 ] + walkopts,
3495 ] + walkopts,
3496 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3496 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3497 "archive":
3497 "archive":
3498 (archive,
3498 (archive,
3499 [('', 'no-decode', None, _('do not pass files through decoders')),
3499 [('', 'no-decode', None, _('do not pass files through decoders')),
3500 ('p', 'prefix', '', _('directory prefix for files in archive')),
3500 ('p', 'prefix', '', _('directory prefix for files in archive')),
3501 ('r', 'rev', '', _('revision to distribute')),
3501 ('r', 'rev', '', _('revision to distribute')),
3502 ('t', 'type', '', _('type of distribution to create')),
3502 ('t', 'type', '', _('type of distribution to create')),
3503 ] + walkopts,
3503 ] + walkopts,
3504 _('[OPTION]... DEST')),
3504 _('[OPTION]... DEST')),
3505 "backout":
3505 "backout":
3506 (backout,
3506 (backout,
3507 [('', 'merge', None,
3507 [('', 'merge', None,
3508 _('merge with old dirstate parent after backout')),
3508 _('merge with old dirstate parent after backout')),
3509 ('', 'parent', '', _('parent to choose when backing out merge')),
3509 ('', 'parent', '', _('parent to choose when backing out merge')),
3510 ('r', 'rev', '', _('revision to backout')),
3510 ('r', 'rev', '', _('revision to backout')),
3511 ] + walkopts + commitopts + commitopts2,
3511 ] + walkopts + commitopts + commitopts2,
3512 _('[OPTION]... [-r] REV')),
3512 _('[OPTION]... [-r] REV')),
3513 "bisect":
3513 "bisect":
3514 (bisect,
3514 (bisect,
3515 [('r', 'reset', False, _('reset bisect state')),
3515 [('r', 'reset', False, _('reset bisect state')),
3516 ('g', 'good', False, _('mark changeset good')),
3516 ('g', 'good', False, _('mark changeset good')),
3517 ('b', 'bad', False, _('mark changeset bad')),
3517 ('b', 'bad', False, _('mark changeset bad')),
3518 ('s', 'skip', False, _('skip testing changeset')),
3518 ('s', 'skip', False, _('skip testing changeset')),
3519 ('c', 'command', '', _('use command to check changeset state')),
3519 ('c', 'command', '', _('use command to check changeset state')),
3520 ('U', 'noupdate', False, _('do not update to target'))],
3520 ('U', 'noupdate', False, _('do not update to target'))],
3521 _("[-gbsr] [-U] [-c CMD] [REV]")),
3521 _("[-gbsr] [-U] [-c CMD] [REV]")),
3522 "branch":
3522 "branch":
3523 (branch,
3523 (branch,
3524 [('f', 'force', None,
3524 [('f', 'force', None,
3525 _('set branch name even if it shadows an existing branch')),
3525 _('set branch name even if it shadows an existing branch')),
3526 ('C', 'clean', None, _('reset branch name to parent branch name'))],
3526 ('C', 'clean', None, _('reset branch name to parent branch name'))],
3527 _('[-fC] [NAME]')),
3527 _('[-fC] [NAME]')),
3528 "branches":
3528 "branches":
3529 (branches,
3529 (branches,
3530 [('a', 'active', False,
3530 [('a', 'active', False,
3531 _('show only branches that have unmerged heads')),
3531 _('show only branches that have unmerged heads')),
3532 ('c', 'closed', False,
3532 ('c', 'closed', False,
3533 _('show normal and closed branches'))],
3533 _('show normal and closed branches'))],
3534 _('[-ac]')),
3534 _('[-ac]')),
3535 "bundle":
3535 "bundle":
3536 (bundle,
3536 (bundle,
3537 [('f', 'force', None,
3537 [('f', 'force', None,
3538 _('run even when the destination is unrelated')),
3538 _('run even when the destination is unrelated')),
3539 ('r', 'rev', [],
3539 ('r', 'rev', [],
3540 _('a changeset intended to be added to the destination')),
3540 _('a changeset intended to be added to the destination')),
3541 ('b', 'branch', [],
3541 ('b', 'branch', [],
3542 _('a specific branch you would like to bundle')),
3542 _('a specific branch you would like to bundle')),
3543 ('', 'base', [],
3543 ('', 'base', [],
3544 _('a base changeset assumed to be available at the destination')),
3544 _('a base changeset assumed to be available at the destination')),
3545 ('a', 'all', None, _('bundle all changesets in the repository')),
3545 ('a', 'all', None, _('bundle all changesets in the repository')),
3546 ('t', 'type', 'bzip2', _('bundle compression type to use')),
3546 ('t', 'type', 'bzip2', _('bundle compression type to use')),
3547 ] + remoteopts,
3547 ] + remoteopts,
3548 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
3548 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
3549 "cat":
3549 "cat":
3550 (cat,
3550 (cat,
3551 [('o', 'output', '', _('print output to file with formatted name')),
3551 [('o', 'output', '', _('print output to file with formatted name')),
3552 ('r', 'rev', '', _('print the given revision')),
3552 ('r', 'rev', '', _('print the given revision')),
3553 ('', 'decode', None, _('apply any matching decode filter')),
3553 ('', 'decode', None, _('apply any matching decode filter')),
3554 ] + walkopts,
3554 ] + walkopts,
3555 _('[OPTION]... FILE...')),
3555 _('[OPTION]... FILE...')),
3556 "^clone":
3556 "^clone":
3557 (clone,
3557 (clone,
3558 [('U', 'noupdate', None,
3558 [('U', 'noupdate', None,
3559 _('the clone will include an empty working copy (only a repository)')),
3559 _('the clone will include an empty working copy (only a repository)')),
3560 ('u', 'updaterev', '',
3560 ('u', 'updaterev', '',
3561 _('revision, tag or branch to check out')),
3561 _('revision, tag or branch to check out')),
3562 ('r', 'rev', [],
3562 ('r', 'rev', [],
3563 _('include the specified changeset')),
3563 _('include the specified changeset')),
3564 ('b', 'branch', [],
3564 ('b', 'branch', [],
3565 _('clone only the specified branch')),
3565 _('clone only the specified branch')),
3566 ('', 'pull', None, _('use pull protocol to copy metadata')),
3566 ('', 'pull', None, _('use pull protocol to copy metadata')),
3567 ('', 'uncompressed', None,
3567 ('', 'uncompressed', None,
3568 _('use uncompressed transfer (fast over LAN)')),
3568 _('use uncompressed transfer (fast over LAN)')),
3569 ] + remoteopts,
3569 ] + remoteopts,
3570 _('[OPTION]... SOURCE [DEST]')),
3570 _('[OPTION]... SOURCE [DEST]')),
3571 "^commit|ci":
3571 "^commit|ci":
3572 (commit,
3572 (commit,
3573 [('A', 'addremove', None,
3573 [('A', 'addremove', None,
3574 _('mark new/missing files as added/removed before committing')),
3574 _('mark new/missing files as added/removed before committing')),
3575 ('', 'close-branch', None,
3575 ('', 'close-branch', None,
3576 _('mark a branch as closed, hiding it from the branch list')),
3576 _('mark a branch as closed, hiding it from the branch list')),
3577 ] + walkopts + commitopts + commitopts2,
3577 ] + walkopts + commitopts + commitopts2,
3578 _('[OPTION]... [FILE]...')),
3578 _('[OPTION]... [FILE]...')),
3579 "copy|cp":
3579 "copy|cp":
3580 (copy,
3580 (copy,
3581 [('A', 'after', None, _('record a copy that has already occurred')),
3581 [('A', 'after', None, _('record a copy that has already occurred')),
3582 ('f', 'force', None,
3582 ('f', 'force', None,
3583 _('forcibly copy over an existing managed file')),
3583 _('forcibly copy over an existing managed file')),
3584 ] + walkopts + dryrunopts,
3584 ] + walkopts + dryrunopts,
3585 _('[OPTION]... [SOURCE]... DEST')),
3585 _('[OPTION]... [SOURCE]... DEST')),
3586 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
3586 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
3587 "debugcheckstate": (debugcheckstate, [], ''),
3587 "debugcheckstate": (debugcheckstate, [], ''),
3588 "debugcommands": (debugcommands, [], _('[COMMAND]')),
3588 "debugcommands": (debugcommands, [], _('[COMMAND]')),
3589 "debugcomplete":
3589 "debugcomplete":
3590 (debugcomplete,
3590 (debugcomplete,
3591 [('o', 'options', None, _('show the command options'))],
3591 [('o', 'options', None, _('show the command options'))],
3592 _('[-o] CMD')),
3592 _('[-o] CMD')),
3593 "debugdate":
3593 "debugdate":
3594 (debugdate,
3594 (debugdate,
3595 [('e', 'extended', None, _('try extended date formats'))],
3595 [('e', 'extended', None, _('try extended date formats'))],
3596 _('[-e] DATE [RANGE]')),
3596 _('[-e] DATE [RANGE]')),
3597 "debugdata": (debugdata, [], _('FILE REV')),
3597 "debugdata": (debugdata, [], _('FILE REV')),
3598 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
3598 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
3599 "debugindex": (debugindex, [], _('FILE')),
3599 "debugindex": (debugindex, [], _('FILE')),
3600 "debugindexdot": (debugindexdot, [], _('FILE')),
3600 "debugindexdot": (debugindexdot, [], _('FILE')),
3601 "debuginstall": (debuginstall, [], ''),
3601 "debuginstall": (debuginstall, [], ''),
3602 "debugrebuildstate":
3602 "debugrebuildstate":
3603 (debugrebuildstate,
3603 (debugrebuildstate,
3604 [('r', 'rev', '', _('revision to rebuild to'))],
3604 [('r', 'rev', '', _('revision to rebuild to'))],
3605 _('[-r REV] [REV]')),
3605 _('[-r REV] [REV]')),
3606 "debugrename":
3606 "debugrename":
3607 (debugrename,
3607 (debugrename,
3608 [('r', 'rev', '', _('revision to debug'))],
3608 [('r', 'rev', '', _('revision to debug'))],
3609 _('[-r REV] FILE')),
3609 _('[-r REV] FILE')),
3610 "debugsetparents":
3610 "debugsetparents":
3611 (debugsetparents, [], _('REV1 [REV2]')),
3611 (debugsetparents, [], _('REV1 [REV2]')),
3612 "debugstate":
3612 "debugstate":
3613 (debugstate,
3613 (debugstate,
3614 [('', 'nodates', None, _('do not display the saved mtime'))],
3614 [('', 'nodates', None, _('do not display the saved mtime'))],
3615 _('[OPTION]...')),
3615 _('[OPTION]...')),
3616 "debugsub":
3616 "debugsub":
3617 (debugsub,
3617 (debugsub,
3618 [('r', 'rev', '', _('revision to check'))],
3618 [('r', 'rev', '', _('revision to check'))],
3619 _('[-r REV] [REV]')),
3619 _('[-r REV] [REV]')),
3620 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
3620 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
3621 "^diff":
3621 "^diff":
3622 (diff,
3622 (diff,
3623 [('r', 'rev', [], _('revision')),
3623 [('r', 'rev', [], _('revision')),
3624 ('c', 'change', '', _('change made by revision'))
3624 ('c', 'change', '', _('change made by revision'))
3625 ] + diffopts + diffopts2 + walkopts,
3625 ] + diffopts + diffopts2 + walkopts,
3626 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
3626 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
3627 "^export":
3627 "^export":
3628 (export,
3628 (export,
3629 [('o', 'output', '', _('print output to file with formatted name')),
3629 [('o', 'output', '', _('print output to file with formatted name')),
3630 ('', 'switch-parent', None, _('diff against the second parent')),
3630 ('', 'switch-parent', None, _('diff against the second parent')),
3631 ('r', 'rev', [], _('revisions to export')),
3631 ('r', 'rev', [], _('revisions to export')),
3632 ] + diffopts,
3632 ] + diffopts,
3633 _('[OPTION]... [-o OUTFILESPEC] REV...')),
3633 _('[OPTION]... [-o OUTFILESPEC] REV...')),
3634 "^forget":
3634 "^forget":
3635 (forget,
3635 (forget,
3636 [] + walkopts,
3636 [] + walkopts,
3637 _('[OPTION]... FILE...')),
3637 _('[OPTION]... FILE...')),
3638 "grep":
3638 "grep":
3639 (grep,
3639 (grep,
3640 [('0', 'print0', None, _('end fields with NUL')),
3640 [('0', 'print0', None, _('end fields with NUL')),
3641 ('', 'all', None, _('print all revisions that match')),
3641 ('', 'all', None, _('print all revisions that match')),
3642 ('f', 'follow', None,
3642 ('f', 'follow', None,
3643 _('follow changeset history,'
3643 _('follow changeset history,'
3644 ' or file history across copies and renames')),
3644 ' or file history across copies and renames')),
3645 ('i', 'ignore-case', None, _('ignore case when matching')),
3645 ('i', 'ignore-case', None, _('ignore case when matching')),
3646 ('l', 'files-with-matches', None,
3646 ('l', 'files-with-matches', None,
3647 _('print only filenames and revisions that match')),
3647 _('print only filenames and revisions that match')),
3648 ('n', 'line-number', None, _('print matching line numbers')),
3648 ('n', 'line-number', None, _('print matching line numbers')),
3649 ('r', 'rev', [], _('search in given revision range')),
3649 ('r', 'rev', [], _('search in given revision range')),
3650 ('u', 'user', None, _('list the author (long with -v)')),
3650 ('u', 'user', None, _('list the author (long with -v)')),
3651 ('d', 'date', None, _('list the date (short with -q)')),
3651 ('d', 'date', None, _('list the date (short with -q)')),
3652 ] + walkopts,
3652 ] + walkopts,
3653 _('[OPTION]... PATTERN [FILE]...')),
3653 _('[OPTION]... PATTERN [FILE]...')),
3654 "heads":
3654 "heads":
3655 (heads,
3655 (heads,
3656 [('r', 'rev', '', _('show only heads which are descendants of REV')),
3656 [('r', 'rev', '', _('show only heads which are descendants of REV')),
3657 ('t', 'topo', False, _('show topological heads only')),
3657 ('t', 'topo', False, _('show topological heads only')),
3658 ('a', 'active', False,
3658 ('a', 'active', False,
3659 _('show active branchheads only [DEPRECATED]')),
3659 _('show active branchheads only [DEPRECATED]')),
3660 ('c', 'closed', False,
3660 ('c', 'closed', False,
3661 _('show normal and closed branch heads')),
3661 _('show normal and closed branch heads')),
3662 ] + templateopts,
3662 ] + templateopts,
3663 _('[-ac] [-r STARTREV] [REV]...')),
3663 _('[-ac] [-r STARTREV] [REV]...')),
3664 "help": (help_, [], _('[TOPIC]')),
3664 "help": (help_, [], _('[TOPIC]')),
3665 "identify|id":
3665 "identify|id":
3666 (identify,
3666 (identify,
3667 [('r', 'rev', '', _('identify the specified revision')),
3667 [('r', 'rev', '', _('identify the specified revision')),
3668 ('n', 'num', None, _('show local revision number')),
3668 ('n', 'num', None, _('show local revision number')),
3669 ('i', 'id', None, _('show global revision id')),
3669 ('i', 'id', None, _('show global revision id')),
3670 ('b', 'branch', None, _('show branch')),
3670 ('b', 'branch', None, _('show branch')),
3671 ('t', 'tags', None, _('show tags'))],
3671 ('t', 'tags', None, _('show tags'))],
3672 _('[-nibt] [-r REV] [SOURCE]')),
3672 _('[-nibt] [-r REV] [SOURCE]')),
3673 "import|patch":
3673 "import|patch":
3674 (import_,
3674 (import_,
3675 [('p', 'strip', 1,
3675 [('p', 'strip', 1,
3676 _('directory strip option for patch. This has the same '
3676 _('directory strip option for patch. This has the same '
3677 'meaning as the corresponding patch option')),
3677 'meaning as the corresponding patch option')),
3678 ('b', 'base', '', _('base path')),
3678 ('b', 'base', '', _('base path')),
3679 ('f', 'force', None,
3679 ('f', 'force', None,
3680 _('skip check for outstanding uncommitted changes')),
3680 _('skip check for outstanding uncommitted changes')),
3681 ('', 'no-commit', None,
3681 ('', 'no-commit', None,
3682 _("don't commit, just update the working directory")),
3682 _("don't commit, just update the working directory")),
3683 ('', 'exact', None,
3683 ('', 'exact', None,
3684 _('apply patch to the nodes from which it was generated')),
3684 _('apply patch to the nodes from which it was generated')),
3685 ('', 'import-branch', None,
3685 ('', 'import-branch', None,
3686 _('use any branch information in patch (implied by --exact)'))] +
3686 _('use any branch information in patch (implied by --exact)'))] +
3687 commitopts + commitopts2 + similarityopts,
3687 commitopts + commitopts2 + similarityopts,
3688 _('[OPTION]... PATCH...')),
3688 _('[OPTION]... PATCH...')),
3689 "incoming|in":
3689 "incoming|in":
3690 (incoming,
3690 (incoming,
3691 [('f', 'force', None,
3691 [('f', 'force', None,
3692 _('run even if remote repository is unrelated')),
3692 _('run even if remote repository is unrelated')),
3693 ('n', 'newest-first', None, _('show newest record first')),
3693 ('n', 'newest-first', None, _('show newest record first')),
3694 ('', 'bundle', '', _('file to store the bundles into')),
3694 ('', 'bundle', '', _('file to store the bundles into')),
3695 ('r', 'rev', [],
3695 ('r', 'rev', [],
3696 _('a remote changeset intended to be added')),
3696 _('a remote changeset intended to be added')),
3697 ('b', 'branch', [],
3697 ('b', 'branch', [],
3698 _('a specific branch you would like to pull')),
3698 _('a specific branch you would like to pull')),
3699 ] + logopts + remoteopts,
3699 ] + logopts + remoteopts,
3700 _('[-p] [-n] [-M] [-f] [-r REV]...'
3700 _('[-p] [-n] [-M] [-f] [-r REV]...'
3701 ' [--bundle FILENAME] [SOURCE]')),
3701 ' [--bundle FILENAME] [SOURCE]')),
3702 "^init":
3702 "^init":
3703 (init,
3703 (init,
3704 remoteopts,
3704 remoteopts,
3705 _('[-e CMD] [--remotecmd CMD] [DEST]')),
3705 _('[-e CMD] [--remotecmd CMD] [DEST]')),
3706 "locate":
3706 "locate":
3707 (locate,
3707 (locate,
3708 [('r', 'rev', '', _('search the repository as it is in REV')),
3708 [('r', 'rev', '', _('search the repository as it is in REV')),
3709 ('0', 'print0', None,
3709 ('0', 'print0', None,
3710 _('end filenames with NUL, for use with xargs')),
3710 _('end filenames with NUL, for use with xargs')),
3711 ('f', 'fullpath', None,
3711 ('f', 'fullpath', None,
3712 _('print complete paths from the filesystem root')),
3712 _('print complete paths from the filesystem root')),
3713 ] + walkopts,
3713 ] + walkopts,
3714 _('[OPTION]... [PATTERN]...')),
3714 _('[OPTION]... [PATTERN]...')),
3715 "^log|history":
3715 "^log|history":
3716 (log,
3716 (log,
3717 [('f', 'follow', None,
3717 [('f', 'follow', None,
3718 _('follow changeset history,'
3718 _('follow changeset history,'
3719 ' or file history across copies and renames')),
3719 ' or file history across copies and renames')),
3720 ('', 'follow-first', None,
3720 ('', 'follow-first', None,
3721 _('only follow the first parent of merge changesets')),
3721 _('only follow the first parent of merge changesets')),
3722 ('d', 'date', '', _('show revisions matching date spec')),
3722 ('d', 'date', '', _('show revisions matching date spec')),
3723 ('C', 'copies', None, _('show copied files')),
3723 ('C', 'copies', None, _('show copied files')),
3724 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
3724 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
3725 ('r', 'rev', [], _('show the specified revision or range')),
3725 ('r', 'rev', [], _('show the specified revision or range')),
3726 ('', 'removed', None, _('include revisions where files were removed')),
3726 ('', 'removed', None, _('include revisions where files were removed')),
3727 ('m', 'only-merges', None, _('show only merges')),
3727 ('m', 'only-merges', None, _('show only merges')),
3728 ('u', 'user', [], _('revisions committed by user')),
3728 ('u', 'user', [], _('revisions committed by user')),
3729 ('b', 'only-branch', [],
3729 ('b', 'only-branch', [],
3730 _('show only changesets within the given named branch')),
3730 _('show only changesets within the given named branch')),
3731 ('P', 'prune', [],
3731 ('P', 'prune', [],
3732 _('do not display revision or any of its ancestors')),
3732 _('do not display revision or any of its ancestors')),
3733 ] + logopts + walkopts,
3733 ] + logopts + walkopts,
3734 _('[OPTION]... [FILE]')),
3734 _('[OPTION]... [FILE]')),
3735 "manifest":
3735 "manifest":
3736 (manifest,
3736 (manifest,
3737 [('r', 'rev', '', _('revision to display'))],
3737 [('r', 'rev', '', _('revision to display'))],
3738 _('[-r REV]')),
3738 _('[-r REV]')),
3739 "^merge":
3739 "^merge":
3740 (merge,
3740 (merge,
3741 [('f', 'force', None, _('force a merge with outstanding changes')),
3741 [('f', 'force', None, _('force a merge with outstanding changes')),
3742 ('r', 'rev', '', _('revision to merge')),
3742 ('r', 'rev', '', _('revision to merge')),
3743 ('P', 'preview', None,
3743 ('P', 'preview', None,
3744 _('review revisions to merge (no merge is performed)'))],
3744 _('review revisions to merge (no merge is performed)'))],
3745 _('[-P] [-f] [[-r] REV]')),
3745 _('[-P] [-f] [[-r] REV]')),
3746 "outgoing|out":
3746 "outgoing|out":
3747 (outgoing,
3747 (outgoing,
3748 [('f', 'force', None,
3748 [('f', 'force', None,
3749 _('run even when the destination is unrelated')),
3749 _('run even when the destination is unrelated')),
3750 ('r', 'rev', [],
3750 ('r', 'rev', [],
3751 _('a changeset intended to be included in the destination')),
3751 _('a changeset intended to be included in the destination')),
3752 ('n', 'newest-first', None, _('show newest record first')),
3752 ('n', 'newest-first', None, _('show newest record first')),
3753 ('b', 'branch', [],
3753 ('b', 'branch', [],
3754 _('a specific branch you would like to push')),
3754 _('a specific branch you would like to push')),
3755 ] + logopts + remoteopts,
3755 ] + logopts + remoteopts,
3756 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
3756 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
3757 "parents":
3757 "parents":
3758 (parents,
3758 (parents,
3759 [('r', 'rev', '', _('show parents of the specified revision')),
3759 [('r', 'rev', '', _('show parents of the specified revision')),
3760 ] + templateopts,
3760 ] + templateopts,
3761 _('[-r REV] [FILE]')),
3761 _('[-r REV] [FILE]')),
3762 "paths": (paths, [], _('[NAME]')),
3762 "paths": (paths, [], _('[NAME]')),
3763 "^pull":
3763 "^pull":
3764 (pull,
3764 (pull,
3765 [('u', 'update', None,
3765 [('u', 'update', None,
3766 _('update to new branch head if changesets were pulled')),
3766 _('update to new branch head if changesets were pulled')),
3767 ('f', 'force', None,
3767 ('f', 'force', None,
3768 _('run even when remote repository is unrelated')),
3768 _('run even when remote repository is unrelated')),
3769 ('r', 'rev', [],
3769 ('r', 'rev', [],
3770 _('a remote changeset intended to be added')),
3770 _('a remote changeset intended to be added')),
3771 ('b', 'branch', [],
3771 ('b', 'branch', [],
3772 _('a specific branch you would like to pull')),
3772 _('a specific branch you would like to pull')),
3773 ] + remoteopts,
3773 ] + remoteopts,
3774 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
3774 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
3775 "^push":
3775 "^push":
3776 (push,
3776 (push,
3777 [('f', 'force', None, _('force push')),
3777 [('f', 'force', None, _('force push')),
3778 ('r', 'rev', [],
3778 ('r', 'rev', [],
3779 _('a changeset intended to be included in the destination')),
3779 _('a changeset intended to be included in the destination')),
3780 ('b', 'branch', [],
3780 ('b', 'branch', [],
3781 _('a specific branch you would like to push')),
3781 _('a specific branch you would like to push')),
3782 ] + remoteopts,
3782 ] + remoteopts,
3783 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3783 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3784 "recover": (recover, []),
3784 "recover": (recover, []),
3785 "^remove|rm":
3785 "^remove|rm":
3786 (remove,
3786 (remove,
3787 [('A', 'after', None, _('record delete for missing files')),
3787 [('A', 'after', None, _('record delete for missing files')),
3788 ('f', 'force', None,
3788 ('f', 'force', None,
3789 _('remove (and delete) file even if added or modified')),
3789 _('remove (and delete) file even if added or modified')),
3790 ] + walkopts,
3790 ] + walkopts,
3791 _('[OPTION]... FILE...')),
3791 _('[OPTION]... FILE...')),
3792 "rename|mv":
3792 "rename|mv":
3793 (rename,
3793 (rename,
3794 [('A', 'after', None, _('record a rename that has already occurred')),
3794 [('A', 'after', None, _('record a rename that has already occurred')),
3795 ('f', 'force', None,
3795 ('f', 'force', None,
3796 _('forcibly copy over an existing managed file')),
3796 _('forcibly copy over an existing managed file')),
3797 ] + walkopts + dryrunopts,
3797 ] + walkopts + dryrunopts,
3798 _('[OPTION]... SOURCE... DEST')),
3798 _('[OPTION]... SOURCE... DEST')),
3799 "resolve":
3799 "resolve":
3800 (resolve,
3800 (resolve,
3801 [('a', 'all', None, _('select all unresolved files')),
3801 [('a', 'all', None, _('select all unresolved files')),
3802 ('l', 'list', None, _('list state of files needing merge')),
3802 ('l', 'list', None, _('list state of files needing merge')),
3803 ('m', 'mark', None, _('mark files as resolved')),
3803 ('m', 'mark', None, _('mark files as resolved')),
3804 ('u', 'unmark', None, _('unmark files as resolved')),
3804 ('u', 'unmark', None, _('unmark files as resolved')),
3805 ('n', 'no-status', None, _('hide status prefix'))]
3805 ('n', 'no-status', None, _('hide status prefix'))]
3806 + walkopts,
3806 + walkopts,
3807 _('[OPTION]... [FILE]...')),
3807 _('[OPTION]... [FILE]...')),
3808 "revert":
3808 "revert":
3809 (revert,
3809 (revert,
3810 [('a', 'all', None, _('revert all changes when no arguments given')),
3810 [('a', 'all', None, _('revert all changes when no arguments given')),
3811 ('d', 'date', '', _('tipmost revision matching date')),
3811 ('d', 'date', '', _('tipmost revision matching date')),
3812 ('r', 'rev', '', _('revert to the specified revision')),
3812 ('r', 'rev', '', _('revert to the specified revision')),
3813 ('', 'no-backup', None, _('do not save backup copies of files')),
3813 ('', 'no-backup', None, _('do not save backup copies of files')),
3814 ] + walkopts + dryrunopts,
3814 ] + walkopts + dryrunopts,
3815 _('[OPTION]... [-r REV] [NAME]...')),
3815 _('[OPTION]... [-r REV] [NAME]...')),
3816 "rollback": (rollback, []),
3816 "rollback": (rollback, []),
3817 "root": (root, []),
3817 "root": (root, []),
3818 "^serve":
3818 "^serve":
3819 (serve,
3819 (serve,
3820 [('A', 'accesslog', '', _('name of access log file to write to')),
3820 [('A', 'accesslog', '', _('name of access log file to write to')),
3821 ('d', 'daemon', None, _('run server in background')),
3821 ('d', 'daemon', None, _('run server in background')),
3822 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3822 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3823 ('E', 'errorlog', '', _('name of error log file to write to')),
3823 ('E', 'errorlog', '', _('name of error log file to write to')),
3824 # use string type, then we can check if something was passed
3824 # use string type, then we can check if something was passed
3825 ('p', 'port', '', _('port to listen on (default: 8000')),
3825 ('p', 'port', '', _('port to listen on (default: 8000)')),
3826 ('a', 'address', '',
3826 ('a', 'address', '',
3827 _('address to listen on (default: all interfaces)')),
3827 _('address to listen on (default: all interfaces)')),
3828 ('', 'prefix', '',
3828 ('', 'prefix', '',
3829 _('prefix path to serve from (default: server root)')),
3829 _('prefix path to serve from (default: server root)')),
3830 ('n', 'name', '',
3830 ('n', 'name', '',
3831 _('name to show in web pages (default: working directory)')),
3831 _('name to show in web pages (default: working directory)')),
3832 ('', 'webdir-conf', '', _('name of the webdir config file'
3832 ('', 'webdir-conf', '', _('name of the webdir config file'
3833 ' (serve more than one repository)')),
3833 ' (serve more than one repository)')),
3834 ('', 'pid-file', '', _('name of file to write process ID to')),
3834 ('', 'pid-file', '', _('name of file to write process ID to')),
3835 ('', 'stdio', None, _('for remote clients')),
3835 ('', 'stdio', None, _('for remote clients')),
3836 ('t', 'templates', '', _('web templates to use')),
3836 ('t', 'templates', '', _('web templates to use')),
3837 ('', 'style', '', _('template style to use')),
3837 ('', 'style', '', _('template style to use')),
3838 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3838 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3839 ('', 'certificate', '', _('SSL certificate file'))],
3839 ('', 'certificate', '', _('SSL certificate file'))],
3840 _('[OPTION]...')),
3840 _('[OPTION]...')),
3841 "showconfig|debugconfig":
3841 "showconfig|debugconfig":
3842 (showconfig,
3842 (showconfig,
3843 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3843 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3844 _('[-u] [NAME]...')),
3844 _('[-u] [NAME]...')),
3845 "^summary|sum":
3845 "^summary|sum":
3846 (summary,
3846 (summary,
3847 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
3847 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
3848 "^status|st":
3848 "^status|st":
3849 (status,
3849 (status,
3850 [('A', 'all', None, _('show status of all files')),
3850 [('A', 'all', None, _('show status of all files')),
3851 ('m', 'modified', None, _('show only modified files')),
3851 ('m', 'modified', None, _('show only modified files')),
3852 ('a', 'added', None, _('show only added files')),
3852 ('a', 'added', None, _('show only added files')),
3853 ('r', 'removed', None, _('show only removed files')),
3853 ('r', 'removed', None, _('show only removed files')),
3854 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3854 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3855 ('c', 'clean', None, _('show only files without changes')),
3855 ('c', 'clean', None, _('show only files without changes')),
3856 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3856 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3857 ('i', 'ignored', None, _('show only ignored files')),
3857 ('i', 'ignored', None, _('show only ignored files')),
3858 ('n', 'no-status', None, _('hide status prefix')),
3858 ('n', 'no-status', None, _('hide status prefix')),
3859 ('C', 'copies', None, _('show source of copied files')),
3859 ('C', 'copies', None, _('show source of copied files')),
3860 ('0', 'print0', None,
3860 ('0', 'print0', None,
3861 _('end filenames with NUL, for use with xargs')),
3861 _('end filenames with NUL, for use with xargs')),
3862 ('', 'rev', [], _('show difference from revision')),
3862 ('', 'rev', [], _('show difference from revision')),
3863 ('', 'change', '', _('list the changed files of a revision')),
3863 ('', 'change', '', _('list the changed files of a revision')),
3864 ] + walkopts,
3864 ] + walkopts,
3865 _('[OPTION]... [FILE]...')),
3865 _('[OPTION]... [FILE]...')),
3866 "tag":
3866 "tag":
3867 (tag,
3867 (tag,
3868 [('f', 'force', None, _('replace existing tag')),
3868 [('f', 'force', None, _('replace existing tag')),
3869 ('l', 'local', None, _('make the tag local')),
3869 ('l', 'local', None, _('make the tag local')),
3870 ('r', 'rev', '', _('revision to tag')),
3870 ('r', 'rev', '', _('revision to tag')),
3871 ('', 'remove', None, _('remove a tag')),
3871 ('', 'remove', None, _('remove a tag')),
3872 # -l/--local is already there, commitopts cannot be used
3872 # -l/--local is already there, commitopts cannot be used
3873 ('m', 'message', '', _('use <text> as commit message')),
3873 ('m', 'message', '', _('use <text> as commit message')),
3874 ] + commitopts2,
3874 ] + commitopts2,
3875 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
3875 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
3876 "tags": (tags, [], ''),
3876 "tags": (tags, [], ''),
3877 "tip":
3877 "tip":
3878 (tip,
3878 (tip,
3879 [('p', 'patch', None, _('show patch')),
3879 [('p', 'patch', None, _('show patch')),
3880 ('g', 'git', None, _('use git extended diff format')),
3880 ('g', 'git', None, _('use git extended diff format')),
3881 ] + templateopts,
3881 ] + templateopts,
3882 _('[-p] [-g]')),
3882 _('[-p] [-g]')),
3883 "unbundle":
3883 "unbundle":
3884 (unbundle,
3884 (unbundle,
3885 [('u', 'update', None,
3885 [('u', 'update', None,
3886 _('update to new branch head if changesets were unbundled'))],
3886 _('update to new branch head if changesets were unbundled'))],
3887 _('[-u] FILE...')),
3887 _('[-u] FILE...')),
3888 "^update|up|checkout|co":
3888 "^update|up|checkout|co":
3889 (update,
3889 (update,
3890 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
3890 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
3891 ('c', 'check', None, _('check for uncommitted changes')),
3891 ('c', 'check', None, _('check for uncommitted changes')),
3892 ('d', 'date', '', _('tipmost revision matching date')),
3892 ('d', 'date', '', _('tipmost revision matching date')),
3893 ('r', 'rev', '', _('revision'))],
3893 ('r', 'rev', '', _('revision'))],
3894 _('[-c] [-C] [-d DATE] [[-r] REV]')),
3894 _('[-c] [-C] [-d DATE] [[-r] REV]')),
3895 "verify": (verify, []),
3895 "verify": (verify, []),
3896 "version": (version_, []),
3896 "version": (version_, []),
3897 }
3897 }
3898
3898
3899 norepo = ("clone init version help debugcommands debugcomplete debugdata"
3899 norepo = ("clone init version help debugcommands debugcomplete debugdata"
3900 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3900 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3901 optionalrepo = ("identify paths serve showconfig debugancestor")
3901 optionalrepo = ("identify paths serve showconfig debugancestor")
General Comments 0
You need to be logged in to leave comments. Login now