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