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