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