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