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