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