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