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