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