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