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