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