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