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