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