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