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