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