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