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