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