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