##// END OF EJS Templates
merge: allow smarter tool configuration...
Matt Mackall -
r6004:5af5f0f9 default
parent child Browse files
Show More
@@ -1,3114 +1,3080 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
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from i18n import _
9 from i18n import _
10 import os, re, sys, urllib
10 import os, re, sys, urllib
11 import hg, util, revlog, bundlerepo, extensions
11 import hg, util, revlog, bundlerepo, extensions
12 import difflib, patch, time, help, mdiff, tempfile
12 import difflib, patch, time, help, mdiff, tempfile
13 import errno, version, socket
13 import errno, version, socket
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
15
15
16 # Commands start here, listed alphabetically
16 # Commands start here, listed alphabetically
17
17
18 def add(ui, repo, *pats, **opts):
18 def add(ui, repo, *pats, **opts):
19 """add the specified files on the next commit
19 """add the specified files on the next commit
20
20
21 Schedule files to be version controlled and added to the repository.
21 Schedule files to be version controlled and added to the repository.
22
22
23 The files will be added to the repository at the next commit. To
23 The files will be added to the repository at the next commit. To
24 undo an add before that, see hg revert.
24 undo an add before that, see hg revert.
25
25
26 If no names are given, add all files in the repository.
26 If no names are given, add all files in the repository.
27 """
27 """
28
28
29 rejected = None
29 rejected = None
30 exacts = {}
30 exacts = {}
31 names = []
31 names = []
32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
33 badmatch=util.always):
33 badmatch=util.always):
34 if exact:
34 if exact:
35 if ui.verbose:
35 if ui.verbose:
36 ui.status(_('adding %s\n') % rel)
36 ui.status(_('adding %s\n') % rel)
37 names.append(abs)
37 names.append(abs)
38 exacts[abs] = 1
38 exacts[abs] = 1
39 elif abs not in repo.dirstate:
39 elif abs not in repo.dirstate:
40 ui.status(_('adding %s\n') % rel)
40 ui.status(_('adding %s\n') % rel)
41 names.append(abs)
41 names.append(abs)
42 if not opts.get('dry_run'):
42 if not opts.get('dry_run'):
43 rejected = repo.add(names)
43 rejected = repo.add(names)
44 rejected = [p for p in rejected if p in exacts]
44 rejected = [p for p in rejected if p in exacts]
45 return rejected and 1 or 0
45 return rejected and 1 or 0
46
46
47 def addremove(ui, repo, *pats, **opts):
47 def addremove(ui, repo, *pats, **opts):
48 """add all new files, delete all missing files
48 """add all new files, delete all missing files
49
49
50 Add all new files and remove all missing files from the repository.
50 Add all new files and remove all missing files from the repository.
51
51
52 New files are ignored if they match any of the patterns in .hgignore. As
52 New files are ignored if they match any of the patterns in .hgignore. As
53 with add, these changes take effect at the next commit.
53 with add, these changes take effect at the next commit.
54
54
55 Use the -s option to detect renamed files. With a parameter > 0,
55 Use the -s option to detect renamed files. With a parameter > 0,
56 this compares every removed file with every added file and records
56 this compares every removed file with every added file and records
57 those similar enough as renames. This option takes a percentage
57 those similar enough as renames. This option takes a percentage
58 between 0 (disabled) and 100 (files must be identical) as its
58 between 0 (disabled) and 100 (files must be identical) as its
59 parameter. Detecting renamed files this way can be expensive.
59 parameter. Detecting renamed files this way can be expensive.
60 """
60 """
61 try:
61 try:
62 sim = float(opts.get('similarity') or 0)
62 sim = float(opts.get('similarity') or 0)
63 except ValueError:
63 except ValueError:
64 raise util.Abort(_('similarity must be a number'))
64 raise util.Abort(_('similarity must be a number'))
65 if sim < 0 or sim > 100:
65 if sim < 0 or sim > 100:
66 raise util.Abort(_('similarity must be between 0 and 100'))
66 raise util.Abort(_('similarity must be between 0 and 100'))
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
68
68
69 def annotate(ui, repo, *pats, **opts):
69 def annotate(ui, repo, *pats, **opts):
70 """show changeset information per file line
70 """show changeset information per file line
71
71
72 List changes in files, showing the revision id responsible for each line
72 List changes in files, showing the revision id responsible for each line
73
73
74 This command is useful to discover who did a change or when a change took
74 This command is useful to discover who did a change or when a change took
75 place.
75 place.
76
76
77 Without the -a option, annotate will avoid processing files it
77 Without the -a option, annotate will avoid processing files it
78 detects as binary. With -a, annotate will generate an annotation
78 detects as binary. With -a, annotate will generate an annotation
79 anyway, probably with undesirable results.
79 anyway, probably with undesirable results.
80 """
80 """
81 getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
81 getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
82
82
83 if not pats:
83 if not pats:
84 raise util.Abort(_('at least one file name or pattern required'))
84 raise util.Abort(_('at least one file name or pattern required'))
85
85
86 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
86 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
87 ('number', lambda x: str(x[0].rev())),
87 ('number', lambda x: str(x[0].rev())),
88 ('changeset', lambda x: short(x[0].node())),
88 ('changeset', lambda x: short(x[0].node())),
89 ('date', getdate),
89 ('date', getdate),
90 ('follow', lambda x: x[0].path()),
90 ('follow', lambda x: x[0].path()),
91 ]
91 ]
92
92
93 if (not opts['user'] and not opts['changeset'] and not opts['date']
93 if (not opts['user'] and not opts['changeset'] and not opts['date']
94 and not opts['follow']):
94 and not opts['follow']):
95 opts['number'] = 1
95 opts['number'] = 1
96
96
97 linenumber = opts.get('line_number') is not None
97 linenumber = opts.get('line_number') is not None
98 if (linenumber and (not opts['changeset']) and (not opts['number'])):
98 if (linenumber and (not opts['changeset']) and (not opts['number'])):
99 raise util.Abort(_('at least one of -n/-c is required for -l'))
99 raise util.Abort(_('at least one of -n/-c is required for -l'))
100
100
101 funcmap = [func for op, func in opmap if opts.get(op)]
101 funcmap = [func for op, func in opmap if opts.get(op)]
102 if linenumber:
102 if linenumber:
103 lastfunc = funcmap[-1]
103 lastfunc = funcmap[-1]
104 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
104 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
105
105
106 ctx = repo.changectx(opts['rev'])
106 ctx = repo.changectx(opts['rev'])
107
107
108 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
108 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
109 node=ctx.node()):
109 node=ctx.node()):
110 fctx = ctx.filectx(abs)
110 fctx = ctx.filectx(abs)
111 if not opts['text'] and util.binary(fctx.data()):
111 if not opts['text'] and util.binary(fctx.data()):
112 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
112 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
113 continue
113 continue
114
114
115 lines = fctx.annotate(follow=opts.get('follow'),
115 lines = fctx.annotate(follow=opts.get('follow'),
116 linenumber=linenumber)
116 linenumber=linenumber)
117 pieces = []
117 pieces = []
118
118
119 for f in funcmap:
119 for f in funcmap:
120 l = [f(n) for n, dummy in lines]
120 l = [f(n) for n, dummy in lines]
121 if l:
121 if l:
122 m = max(map(len, l))
122 m = max(map(len, l))
123 pieces.append(["%*s" % (m, x) for x in l])
123 pieces.append(["%*s" % (m, x) for x in l])
124
124
125 if pieces:
125 if pieces:
126 for p, l in zip(zip(*pieces), lines):
126 for p, l in zip(zip(*pieces), lines):
127 ui.write("%s: %s" % (" ".join(p), l[1]))
127 ui.write("%s: %s" % (" ".join(p), l[1]))
128
128
129 def archive(ui, repo, dest, **opts):
129 def archive(ui, repo, dest, **opts):
130 '''create unversioned archive of a repository revision
130 '''create unversioned archive of a repository revision
131
131
132 By default, the revision used is the parent of the working
132 By default, the revision used is the parent of the working
133 directory; use "-r" to specify a different revision.
133 directory; use "-r" to specify a different revision.
134
134
135 To specify the type of archive to create, use "-t". Valid
135 To specify the type of archive to create, use "-t". Valid
136 types are:
136 types are:
137
137
138 "files" (default): a directory full of files
138 "files" (default): a directory full of files
139 "tar": tar archive, uncompressed
139 "tar": tar archive, uncompressed
140 "tbz2": tar archive, compressed using bzip2
140 "tbz2": tar archive, compressed using bzip2
141 "tgz": tar archive, compressed using gzip
141 "tgz": tar archive, compressed using gzip
142 "uzip": zip archive, uncompressed
142 "uzip": zip archive, uncompressed
143 "zip": zip archive, compressed using deflate
143 "zip": zip archive, compressed using deflate
144
144
145 The exact name of the destination archive or directory is given
145 The exact name of the destination archive or directory is given
146 using a format string; see "hg help export" for details.
146 using a format string; see "hg help export" for details.
147
147
148 Each member added to an archive file has a directory prefix
148 Each member added to an archive file has a directory prefix
149 prepended. Use "-p" to specify a format string for the prefix.
149 prepended. Use "-p" to specify a format string for the prefix.
150 The default is the basename of the archive, with suffixes removed.
150 The default is the basename of the archive, with suffixes removed.
151 '''
151 '''
152
152
153 ctx = repo.changectx(opts['rev'])
153 ctx = repo.changectx(opts['rev'])
154 if not ctx:
154 if not ctx:
155 raise util.Abort(_('repository has no revisions'))
155 raise util.Abort(_('repository has no revisions'))
156 node = ctx.node()
156 node = ctx.node()
157 dest = cmdutil.make_filename(repo, dest, node)
157 dest = cmdutil.make_filename(repo, dest, node)
158 if os.path.realpath(dest) == repo.root:
158 if os.path.realpath(dest) == repo.root:
159 raise util.Abort(_('repository root cannot be destination'))
159 raise util.Abort(_('repository root cannot be destination'))
160 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
160 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
161 kind = opts.get('type') or 'files'
161 kind = opts.get('type') or 'files'
162 prefix = opts['prefix']
162 prefix = opts['prefix']
163 if dest == '-':
163 if dest == '-':
164 if kind == 'files':
164 if kind == 'files':
165 raise util.Abort(_('cannot archive plain files to stdout'))
165 raise util.Abort(_('cannot archive plain files to stdout'))
166 dest = sys.stdout
166 dest = sys.stdout
167 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
167 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
168 prefix = cmdutil.make_filename(repo, prefix, node)
168 prefix = cmdutil.make_filename(repo, prefix, node)
169 archival.archive(repo, dest, node, kind, not opts['no_decode'],
169 archival.archive(repo, dest, node, kind, not opts['no_decode'],
170 matchfn, prefix)
170 matchfn, prefix)
171
171
172 def backout(ui, repo, node=None, rev=None, **opts):
172 def backout(ui, repo, node=None, rev=None, **opts):
173 '''reverse effect of earlier changeset
173 '''reverse effect of earlier changeset
174
174
175 Commit the backed out changes as a new changeset. The new
175 Commit the backed out changes as a new changeset. The new
176 changeset is a child of the backed out changeset.
176 changeset is a child of the backed out changeset.
177
177
178 If you back out a changeset other than the tip, a new head is
178 If you back out a changeset other than the tip, a new head is
179 created. This head is the parent of the working directory. If
179 created. This head is the parent of the working directory. If
180 you back out an old changeset, your working directory will appear
180 you back out an old changeset, your working directory will appear
181 old after the backout. You should merge the backout changeset
181 old after the backout. You should merge the backout changeset
182 with another head.
182 with another head.
183
183
184 The --merge option remembers the parent of the working directory
184 The --merge option remembers the parent of the working directory
185 before starting the backout, then merges the new head with that
185 before starting the backout, then merges the new head with that
186 changeset afterwards. This saves you from doing the merge by
186 changeset afterwards. This saves you from doing the merge by
187 hand. The result of this merge is not committed, as for a normal
187 hand. The result of this merge is not committed, as for a normal
188 merge.'''
188 merge.'''
189 if rev and node:
189 if rev and node:
190 raise util.Abort(_("please specify just one revision"))
190 raise util.Abort(_("please specify just one revision"))
191
191
192 if not rev:
192 if not rev:
193 rev = node
193 rev = node
194
194
195 if not rev:
195 if not rev:
196 raise util.Abort(_("please specify a revision to backout"))
196 raise util.Abort(_("please specify a revision to backout"))
197
197
198 cmdutil.bail_if_changed(repo)
198 cmdutil.bail_if_changed(repo)
199 node = repo.lookup(rev)
199 node = repo.lookup(rev)
200
200
201 op1, op2 = repo.dirstate.parents()
201 op1, op2 = repo.dirstate.parents()
202 a = repo.changelog.ancestor(op1, node)
202 a = repo.changelog.ancestor(op1, node)
203 if a != node:
203 if a != node:
204 raise util.Abort(_('cannot back out change on a different branch'))
204 raise util.Abort(_('cannot back out change on a different branch'))
205
205
206 p1, p2 = repo.changelog.parents(node)
206 p1, p2 = repo.changelog.parents(node)
207 if p1 == nullid:
207 if p1 == nullid:
208 raise util.Abort(_('cannot back out a change with no parents'))
208 raise util.Abort(_('cannot back out a change with no parents'))
209 if p2 != nullid:
209 if p2 != nullid:
210 if not opts['parent']:
210 if not opts['parent']:
211 raise util.Abort(_('cannot back out a merge changeset without '
211 raise util.Abort(_('cannot back out a merge changeset without '
212 '--parent'))
212 '--parent'))
213 p = repo.lookup(opts['parent'])
213 p = repo.lookup(opts['parent'])
214 if p not in (p1, p2):
214 if p not in (p1, p2):
215 raise util.Abort(_('%s is not a parent of %s') %
215 raise util.Abort(_('%s is not a parent of %s') %
216 (short(p), short(node)))
216 (short(p), short(node)))
217 parent = p
217 parent = p
218 else:
218 else:
219 if opts['parent']:
219 if opts['parent']:
220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
221 parent = p1
221 parent = p1
222
222
223 hg.clean(repo, node, show_stats=False)
223 hg.clean(repo, node, show_stats=False)
224 revert_opts = opts.copy()
224 revert_opts = opts.copy()
225 revert_opts['date'] = None
225 revert_opts['date'] = None
226 revert_opts['all'] = True
226 revert_opts['all'] = True
227 revert_opts['rev'] = hex(parent)
227 revert_opts['rev'] = hex(parent)
228 revert(ui, repo, **revert_opts)
228 revert(ui, repo, **revert_opts)
229 commit_opts = opts.copy()
229 commit_opts = opts.copy()
230 commit_opts['addremove'] = False
230 commit_opts['addremove'] = False
231 if not commit_opts['message'] and not commit_opts['logfile']:
231 if not commit_opts['message'] and not commit_opts['logfile']:
232 commit_opts['message'] = _("Backed out changeset %s") % (short(node))
232 commit_opts['message'] = _("Backed out changeset %s") % (short(node))
233 commit_opts['force_editor'] = True
233 commit_opts['force_editor'] = True
234 commit(ui, repo, **commit_opts)
234 commit(ui, repo, **commit_opts)
235 def nice(node):
235 def nice(node):
236 return '%d:%s' % (repo.changelog.rev(node), short(node))
236 return '%d:%s' % (repo.changelog.rev(node), short(node))
237 ui.status(_('changeset %s backs out changeset %s\n') %
237 ui.status(_('changeset %s backs out changeset %s\n') %
238 (nice(repo.changelog.tip()), nice(node)))
238 (nice(repo.changelog.tip()), nice(node)))
239 if op1 != node:
239 if op1 != node:
240 if opts['merge']:
240 if opts['merge']:
241 ui.status(_('merging with changeset %s\n') % nice(op1))
241 ui.status(_('merging with changeset %s\n') % nice(op1))
242 hg.merge(repo, hex(op1))
242 hg.merge(repo, hex(op1))
243 else:
243 else:
244 ui.status(_('the backout changeset is a new head - '
244 ui.status(_('the backout changeset is a new head - '
245 'do not forget to merge\n'))
245 'do not forget to merge\n'))
246 ui.status(_('(use "backout --merge" '
246 ui.status(_('(use "backout --merge" '
247 'if you want to auto-merge)\n'))
247 'if you want to auto-merge)\n'))
248
248
249 def bisect(ui, repo, rev=None, extra=None,
249 def bisect(ui, repo, rev=None, extra=None,
250 reset=None, good=None, bad=None, skip=None, noupdate=None):
250 reset=None, good=None, bad=None, skip=None, noupdate=None):
251 """subdivision search of changesets
251 """subdivision search of changesets
252
252
253 This command helps to find changesets which introduce problems.
253 This command helps to find changesets which introduce problems.
254 To use, mark the earliest changeset you know exhibits the problem
254 To use, mark the earliest changeset you know exhibits the problem
255 as bad, then mark the latest changeset which is free from the
255 as bad, then mark the latest changeset which is free from the
256 problem as good. Bisect will update your working directory to a
256 problem as good. Bisect will update your working directory to a
257 revision for testing. Once you have performed tests, mark the
257 revision for testing. Once you have performed tests, mark the
258 working directory as bad or good and bisect will either update to
258 working directory as bad or good and bisect will either update to
259 another candidate changeset or announce that it has found the bad
259 another candidate changeset or announce that it has found the bad
260 revision.
260 revision.
261 """
261 """
262 # backward compatibility
262 # backward compatibility
263 if rev in "good bad reset init".split():
263 if rev in "good bad reset init".split():
264 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
264 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
265 cmd, rev, extra = rev, extra, None
265 cmd, rev, extra = rev, extra, None
266 if cmd == "good":
266 if cmd == "good":
267 good = True
267 good = True
268 elif cmd == "bad":
268 elif cmd == "bad":
269 bad = True
269 bad = True
270 else:
270 else:
271 reset = True
271 reset = True
272 elif extra or good + bad + skip + reset > 1:
272 elif extra or good + bad + skip + reset > 1:
273 raise util.Abort("Incompatible arguments")
273 raise util.Abort("Incompatible arguments")
274
274
275 if reset:
275 if reset:
276 p = repo.join("bisect.state")
276 p = repo.join("bisect.state")
277 if os.path.exists(p):
277 if os.path.exists(p):
278 os.unlink(p)
278 os.unlink(p)
279 return
279 return
280
280
281 # load state
281 # load state
282 state = {'good': [], 'bad': [], 'skip': []}
282 state = {'good': [], 'bad': [], 'skip': []}
283 if os.path.exists(repo.join("bisect.state")):
283 if os.path.exists(repo.join("bisect.state")):
284 for l in repo.opener("bisect.state"):
284 for l in repo.opener("bisect.state"):
285 kind, node = l[:-1].split()
285 kind, node = l[:-1].split()
286 node = repo.lookup(node)
286 node = repo.lookup(node)
287 if kind not in state:
287 if kind not in state:
288 raise util.Abort(_("unknown bisect kind %s") % kind)
288 raise util.Abort(_("unknown bisect kind %s") % kind)
289 state[kind].append(node)
289 state[kind].append(node)
290
290
291 # update state
291 # update state
292 node = repo.lookup(rev or '.')
292 node = repo.lookup(rev or '.')
293 if good:
293 if good:
294 state['good'].append(node)
294 state['good'].append(node)
295 elif bad:
295 elif bad:
296 state['bad'].append(node)
296 state['bad'].append(node)
297 elif skip:
297 elif skip:
298 state['skip'].append(node)
298 state['skip'].append(node)
299
299
300 # save state
300 # save state
301 f = repo.opener("bisect.state", "w", atomictemp=True)
301 f = repo.opener("bisect.state", "w", atomictemp=True)
302 wlock = repo.wlock()
302 wlock = repo.wlock()
303 try:
303 try:
304 for kind in state:
304 for kind in state:
305 for node in state[kind]:
305 for node in state[kind]:
306 f.write("%s %s\n" % (kind, hg.hex(node)))
306 f.write("%s %s\n" % (kind, hg.hex(node)))
307 f.rename()
307 f.rename()
308 finally:
308 finally:
309 del wlock
309 del wlock
310
310
311 if not state['good'] or not state['bad']:
311 if not state['good'] or not state['bad']:
312 return
312 return
313
313
314 # actually bisect
314 # actually bisect
315 node, changesets, good = hbisect.bisect(repo.changelog, state)
315 node, changesets, good = hbisect.bisect(repo.changelog, state)
316 if changesets == 0:
316 if changesets == 0:
317 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
317 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
318 displayer = cmdutil.show_changeset(ui, repo, {})
318 displayer = cmdutil.show_changeset(ui, repo, {})
319 displayer.show(changenode=node)
319 displayer.show(changenode=node)
320 elif node is not None:
320 elif node is not None:
321 # compute the approximate number of remaining tests
321 # compute the approximate number of remaining tests
322 tests, size = 0, 2
322 tests, size = 0, 2
323 while size <= changesets:
323 while size <= changesets:
324 tests, size = tests + 1, size * 2
324 tests, size = tests + 1, size * 2
325 rev = repo.changelog.rev(node)
325 rev = repo.changelog.rev(node)
326 ui.write(_("Testing changeset %s:%s "
326 ui.write(_("Testing changeset %s:%s "
327 "(%s changesets remaining, ~%s tests)\n")
327 "(%s changesets remaining, ~%s tests)\n")
328 % (rev, hg.short(node), changesets, tests))
328 % (rev, hg.short(node), changesets, tests))
329 if not noupdate:
329 if not noupdate:
330 cmdutil.bail_if_changed(repo)
330 cmdutil.bail_if_changed(repo)
331 return hg.clean(repo, node)
331 return hg.clean(repo, node)
332
332
333 def branch(ui, repo, label=None, **opts):
333 def branch(ui, repo, label=None, **opts):
334 """set or show the current branch name
334 """set or show the current branch name
335
335
336 With no argument, show the current branch name. With one argument,
336 With no argument, show the current branch name. With one argument,
337 set the working directory branch name (the branch does not exist in
337 set the working directory branch name (the branch does not exist in
338 the repository until the next commit).
338 the repository until the next commit).
339
339
340 Unless --force is specified, branch will not let you set a
340 Unless --force is specified, branch will not let you set a
341 branch name that shadows an existing branch.
341 branch name that shadows an existing branch.
342
342
343 Use the command 'hg update' to switch to an existing branch.
343 Use the command 'hg update' to switch to an existing branch.
344 """
344 """
345
345
346 if label:
346 if label:
347 if not opts.get('force') and label in repo.branchtags():
347 if not opts.get('force') and label in repo.branchtags():
348 if label not in [p.branch() for p in repo.workingctx().parents()]:
348 if label not in [p.branch() for p in repo.workingctx().parents()]:
349 raise util.Abort(_('a branch of the same name already exists'
349 raise util.Abort(_('a branch of the same name already exists'
350 ' (use --force to override)'))
350 ' (use --force to override)'))
351 repo.dirstate.setbranch(util.fromlocal(label))
351 repo.dirstate.setbranch(util.fromlocal(label))
352 ui.status(_('marked working directory as branch %s\n') % label)
352 ui.status(_('marked working directory as branch %s\n') % label)
353 else:
353 else:
354 ui.write("%s\n" % util.tolocal(repo.dirstate.branch()))
354 ui.write("%s\n" % util.tolocal(repo.dirstate.branch()))
355
355
356 def branches(ui, repo, active=False):
356 def branches(ui, repo, active=False):
357 """list repository named branches
357 """list repository named branches
358
358
359 List the repository's named branches, indicating which ones are
359 List the repository's named branches, indicating which ones are
360 inactive. If active is specified, only show active branches.
360 inactive. If active is specified, only show active branches.
361
361
362 A branch is considered active if it contains unmerged heads.
362 A branch is considered active if it contains unmerged heads.
363
363
364 Use the command 'hg update' to switch to an existing branch.
364 Use the command 'hg update' to switch to an existing branch.
365 """
365 """
366 b = repo.branchtags()
366 b = repo.branchtags()
367 heads = dict.fromkeys(repo.heads(), 1)
367 heads = dict.fromkeys(repo.heads(), 1)
368 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
368 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
369 l.sort()
369 l.sort()
370 l.reverse()
370 l.reverse()
371 for ishead, r, n, t in l:
371 for ishead, r, n, t in l:
372 if active and not ishead:
372 if active and not ishead:
373 # If we're only displaying active branches, abort the loop on
373 # If we're only displaying active branches, abort the loop on
374 # encountering the first inactive head
374 # encountering the first inactive head
375 break
375 break
376 else:
376 else:
377 hexfunc = ui.debugflag and hex or short
377 hexfunc = ui.debugflag and hex or short
378 if ui.quiet:
378 if ui.quiet:
379 ui.write("%s\n" % t)
379 ui.write("%s\n" % t)
380 else:
380 else:
381 spaces = " " * (30 - util.locallen(t))
381 spaces = " " * (30 - util.locallen(t))
382 # The code only gets here if inactive branches are being
382 # The code only gets here if inactive branches are being
383 # displayed or the branch is active.
383 # displayed or the branch is active.
384 isinactive = ((not ishead) and " (inactive)") or ''
384 isinactive = ((not ishead) and " (inactive)") or ''
385 ui.write("%s%s %s:%s%s\n" % (t, spaces, r, hexfunc(n), isinactive))
385 ui.write("%s%s %s:%s%s\n" % (t, spaces, r, hexfunc(n), isinactive))
386
386
387 def bundle(ui, repo, fname, dest=None, **opts):
387 def bundle(ui, repo, fname, dest=None, **opts):
388 """create a changegroup file
388 """create a changegroup file
389
389
390 Generate a compressed changegroup file collecting changesets not
390 Generate a compressed changegroup file collecting changesets not
391 found in the other repository.
391 found in the other repository.
392
392
393 If no destination repository is specified the destination is assumed
393 If no destination repository is specified the destination is assumed
394 to have all the nodes specified by one or more --base parameters.
394 to have all the nodes specified by one or more --base parameters.
395 To create a bundle containing all changesets, use --base null.
395 To create a bundle containing all changesets, use --base null.
396
396
397 The bundle file can then be transferred using conventional means and
397 The bundle file can then be transferred using conventional means and
398 applied to another repository with the unbundle or pull command.
398 applied to another repository with the unbundle or pull command.
399 This is useful when direct push and pull are not available or when
399 This is useful when direct push and pull are not available or when
400 exporting an entire repository is undesirable.
400 exporting an entire repository is undesirable.
401
401
402 Applying bundles preserves all changeset contents including
402 Applying bundles preserves all changeset contents including
403 permissions, copy/rename information, and revision history.
403 permissions, copy/rename information, and revision history.
404 """
404 """
405 revs = opts.get('rev') or None
405 revs = opts.get('rev') or None
406 if revs:
406 if revs:
407 revs = [repo.lookup(rev) for rev in revs]
407 revs = [repo.lookup(rev) for rev in revs]
408 base = opts.get('base')
408 base = opts.get('base')
409 if base:
409 if base:
410 if dest:
410 if dest:
411 raise util.Abort(_("--base is incompatible with specifiying "
411 raise util.Abort(_("--base is incompatible with specifiying "
412 "a destination"))
412 "a destination"))
413 base = [repo.lookup(rev) for rev in base]
413 base = [repo.lookup(rev) for rev in base]
414 # create the right base
414 # create the right base
415 # XXX: nodesbetween / changegroup* should be "fixed" instead
415 # XXX: nodesbetween / changegroup* should be "fixed" instead
416 o = []
416 o = []
417 has = {nullid: None}
417 has = {nullid: None}
418 for n in base:
418 for n in base:
419 has.update(repo.changelog.reachable(n))
419 has.update(repo.changelog.reachable(n))
420 if revs:
420 if revs:
421 visit = list(revs)
421 visit = list(revs)
422 else:
422 else:
423 visit = repo.changelog.heads()
423 visit = repo.changelog.heads()
424 seen = {}
424 seen = {}
425 while visit:
425 while visit:
426 n = visit.pop(0)
426 n = visit.pop(0)
427 parents = [p for p in repo.changelog.parents(n) if p not in has]
427 parents = [p for p in repo.changelog.parents(n) if p not in has]
428 if len(parents) == 0:
428 if len(parents) == 0:
429 o.insert(0, n)
429 o.insert(0, n)
430 else:
430 else:
431 for p in parents:
431 for p in parents:
432 if p not in seen:
432 if p not in seen:
433 seen[p] = 1
433 seen[p] = 1
434 visit.append(p)
434 visit.append(p)
435 else:
435 else:
436 cmdutil.setremoteconfig(ui, opts)
436 cmdutil.setremoteconfig(ui, opts)
437 dest, revs, checkout = hg.parseurl(
437 dest, revs, checkout = hg.parseurl(
438 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
438 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
439 other = hg.repository(ui, dest)
439 other = hg.repository(ui, dest)
440 o = repo.findoutgoing(other, force=opts['force'])
440 o = repo.findoutgoing(other, force=opts['force'])
441
441
442 if revs:
442 if revs:
443 cg = repo.changegroupsubset(o, revs, 'bundle')
443 cg = repo.changegroupsubset(o, revs, 'bundle')
444 else:
444 else:
445 cg = repo.changegroup(o, 'bundle')
445 cg = repo.changegroup(o, 'bundle')
446 changegroup.writebundle(cg, fname, "HG10BZ")
446 changegroup.writebundle(cg, fname, "HG10BZ")
447
447
448 def cat(ui, repo, file1, *pats, **opts):
448 def cat(ui, repo, file1, *pats, **opts):
449 """output the current or given revision of files
449 """output the current or given revision of files
450
450
451 Print the specified files as they were at the given revision.
451 Print the specified files as they were at the given revision.
452 If no revision is given, the parent of the working directory is used,
452 If no revision is given, the parent of the working directory is used,
453 or tip if no revision is checked out.
453 or tip if no revision is checked out.
454
454
455 Output may be to a file, in which case the name of the file is
455 Output may be to a file, in which case the name of the file is
456 given using a format string. The formatting rules are the same as
456 given using a format string. The formatting rules are the same as
457 for the export command, with the following additions:
457 for the export command, with the following additions:
458
458
459 %s basename of file being printed
459 %s basename of file being printed
460 %d dirname of file being printed, or '.' if in repo root
460 %d dirname of file being printed, or '.' if in repo root
461 %p root-relative path name of file being printed
461 %p root-relative path name of file being printed
462 """
462 """
463 ctx = repo.changectx(opts['rev'])
463 ctx = repo.changectx(opts['rev'])
464 err = 1
464 err = 1
465 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
465 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
466 ctx.node()):
466 ctx.node()):
467 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
467 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
468 fp.write(ctx.filectx(abs).data())
468 fp.write(ctx.filectx(abs).data())
469 err = 0
469 err = 0
470 return err
470 return err
471
471
472 def clone(ui, source, dest=None, **opts):
472 def clone(ui, source, dest=None, **opts):
473 """make a copy of an existing repository
473 """make a copy of an existing repository
474
474
475 Create a copy of an existing repository in a new directory.
475 Create a copy of an existing repository in a new directory.
476
476
477 If no destination directory name is specified, it defaults to the
477 If no destination directory name is specified, it defaults to the
478 basename of the source.
478 basename of the source.
479
479
480 The location of the source is added to the new repository's
480 The location of the source is added to the new repository's
481 .hg/hgrc file, as the default to be used for future pulls.
481 .hg/hgrc file, as the default to be used for future pulls.
482
482
483 For efficiency, hardlinks are used for cloning whenever the source
483 For efficiency, hardlinks are used for cloning whenever the source
484 and destination are on the same filesystem (note this applies only
484 and destination are on the same filesystem (note this applies only
485 to the repository data, not to the checked out files). Some
485 to the repository data, not to the checked out files). Some
486 filesystems, such as AFS, implement hardlinking incorrectly, but
486 filesystems, such as AFS, implement hardlinking incorrectly, but
487 do not report errors. In these cases, use the --pull option to
487 do not report errors. In these cases, use the --pull option to
488 avoid hardlinking.
488 avoid hardlinking.
489
489
490 You can safely clone repositories and checked out files using full
490 You can safely clone repositories and checked out files using full
491 hardlinks with
491 hardlinks with
492
492
493 $ cp -al REPO REPOCLONE
493 $ cp -al REPO REPOCLONE
494
494
495 which is the fastest way to clone. However, the operation is not
495 which is the fastest way to clone. However, the operation is not
496 atomic (making sure REPO is not modified during the operation is
496 atomic (making sure REPO is not modified during the operation is
497 up to you) and you have to make sure your editor breaks hardlinks
497 up to you) and you have to make sure your editor breaks hardlinks
498 (Emacs and most Linux Kernel tools do so).
498 (Emacs and most Linux Kernel tools do so).
499
499
500 If you use the -r option to clone up to a specific revision, no
500 If you use the -r option to clone up to a specific revision, no
501 subsequent revisions will be present in the cloned repository.
501 subsequent revisions will be present in the cloned repository.
502 This option implies --pull, even on local repositories.
502 This option implies --pull, even on local repositories.
503
503
504 See pull for valid source format details.
504 See pull for valid source format details.
505
505
506 It is possible to specify an ssh:// URL as the destination, but no
506 It is possible to specify an ssh:// URL as the destination, but no
507 .hg/hgrc and working directory will be created on the remote side.
507 .hg/hgrc and working directory will be created on the remote side.
508 Look at the help text for the pull command for important details
508 Look at the help text for the pull command for important details
509 about ssh:// URLs.
509 about ssh:// URLs.
510 """
510 """
511 cmdutil.setremoteconfig(ui, opts)
511 cmdutil.setremoteconfig(ui, opts)
512 hg.clone(ui, source, dest,
512 hg.clone(ui, source, dest,
513 pull=opts['pull'],
513 pull=opts['pull'],
514 stream=opts['uncompressed'],
514 stream=opts['uncompressed'],
515 rev=opts['rev'],
515 rev=opts['rev'],
516 update=not opts['noupdate'])
516 update=not opts['noupdate'])
517
517
518 def commit(ui, repo, *pats, **opts):
518 def commit(ui, repo, *pats, **opts):
519 """commit the specified files or all outstanding changes
519 """commit the specified files or all outstanding changes
520
520
521 Commit changes to the given files into the repository.
521 Commit changes to the given files into the repository.
522
522
523 If a list of files is omitted, all changes reported by "hg status"
523 If a list of files is omitted, all changes reported by "hg status"
524 will be committed.
524 will be committed.
525
525
526 If no commit message is specified, the configured editor is started to
526 If no commit message is specified, the configured editor is started to
527 enter a message.
527 enter a message.
528 """
528 """
529 def commitfunc(ui, repo, files, message, match, opts):
529 def commitfunc(ui, repo, files, message, match, opts):
530 return repo.commit(files, message, opts['user'], opts['date'], match,
530 return repo.commit(files, message, opts['user'], opts['date'], match,
531 force_editor=opts.get('force_editor'))
531 force_editor=opts.get('force_editor'))
532 cmdutil.commit(ui, repo, commitfunc, pats, opts)
532 cmdutil.commit(ui, repo, commitfunc, pats, opts)
533
533
534 def copy(ui, repo, *pats, **opts):
534 def copy(ui, repo, *pats, **opts):
535 """mark files as copied for the next commit
535 """mark files as copied for the next commit
536
536
537 Mark dest as having copies of source files. If dest is a
537 Mark dest as having copies of source files. If dest is a
538 directory, copies are put in that directory. If dest is a file,
538 directory, copies are put in that directory. If dest is a file,
539 there can only be one source.
539 there can only be one source.
540
540
541 By default, this command copies the contents of files as they
541 By default, this command copies the contents of files as they
542 stand in the working directory. If invoked with --after, the
542 stand in the working directory. If invoked with --after, the
543 operation is recorded, but no copying is performed.
543 operation is recorded, but no copying is performed.
544
544
545 This command takes effect in the next commit. To undo a copy
545 This command takes effect in the next commit. To undo a copy
546 before that, see hg revert.
546 before that, see hg revert.
547 """
547 """
548 wlock = repo.wlock(False)
548 wlock = repo.wlock(False)
549 try:
549 try:
550 return cmdutil.copy(ui, repo, pats, opts)
550 return cmdutil.copy(ui, repo, pats, opts)
551 finally:
551 finally:
552 del wlock
552 del wlock
553
553
554 def debugancestor(ui, index, rev1, rev2):
554 def debugancestor(ui, index, rev1, rev2):
555 """find the ancestor revision of two revisions in a given index"""
555 """find the ancestor revision of two revisions in a given index"""
556 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
556 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
557 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
557 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
558 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
558 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
559
559
560 def debugcomplete(ui, cmd='', **opts):
560 def debugcomplete(ui, cmd='', **opts):
561 """returns the completion list associated with the given command"""
561 """returns the completion list associated with the given command"""
562
562
563 if opts['options']:
563 if opts['options']:
564 options = []
564 options = []
565 otables = [globalopts]
565 otables = [globalopts]
566 if cmd:
566 if cmd:
567 aliases, entry = cmdutil.findcmd(ui, cmd, table)
567 aliases, entry = cmdutil.findcmd(ui, cmd, table)
568 otables.append(entry[1])
568 otables.append(entry[1])
569 for t in otables:
569 for t in otables:
570 for o in t:
570 for o in t:
571 if o[0]:
571 if o[0]:
572 options.append('-%s' % o[0])
572 options.append('-%s' % o[0])
573 options.append('--%s' % o[1])
573 options.append('--%s' % o[1])
574 ui.write("%s\n" % "\n".join(options))
574 ui.write("%s\n" % "\n".join(options))
575 return
575 return
576
576
577 clist = cmdutil.findpossible(ui, cmd, table).keys()
577 clist = cmdutil.findpossible(ui, cmd, table).keys()
578 clist.sort()
578 clist.sort()
579 ui.write("%s\n" % "\n".join(clist))
579 ui.write("%s\n" % "\n".join(clist))
580
580
581 def debugfsinfo(ui, path = "."):
581 def debugfsinfo(ui, path = "."):
582 file('.debugfsinfo', 'w').write('')
582 file('.debugfsinfo', 'w').write('')
583 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
583 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
584 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
584 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
585 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
585 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
586 and 'yes' or 'no'))
586 and 'yes' or 'no'))
587 os.unlink('.debugfsinfo')
587 os.unlink('.debugfsinfo')
588
588
589 def debugrebuildstate(ui, repo, rev=""):
589 def debugrebuildstate(ui, repo, rev=""):
590 """rebuild the dirstate as it would look like for the given revision"""
590 """rebuild the dirstate as it would look like for the given revision"""
591 if rev == "":
591 if rev == "":
592 rev = repo.changelog.tip()
592 rev = repo.changelog.tip()
593 ctx = repo.changectx(rev)
593 ctx = repo.changectx(rev)
594 files = ctx.manifest()
594 files = ctx.manifest()
595 wlock = repo.wlock()
595 wlock = repo.wlock()
596 try:
596 try:
597 repo.dirstate.rebuild(rev, files)
597 repo.dirstate.rebuild(rev, files)
598 finally:
598 finally:
599 del wlock
599 del wlock
600
600
601 def debugcheckstate(ui, repo):
601 def debugcheckstate(ui, repo):
602 """validate the correctness of the current dirstate"""
602 """validate the correctness of the current dirstate"""
603 parent1, parent2 = repo.dirstate.parents()
603 parent1, parent2 = repo.dirstate.parents()
604 m1 = repo.changectx(parent1).manifest()
604 m1 = repo.changectx(parent1).manifest()
605 m2 = repo.changectx(parent2).manifest()
605 m2 = repo.changectx(parent2).manifest()
606 errors = 0
606 errors = 0
607 for f in repo.dirstate:
607 for f in repo.dirstate:
608 state = repo.dirstate[f]
608 state = repo.dirstate[f]
609 if state in "nr" and f not in m1:
609 if state in "nr" and f not in m1:
610 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
610 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
611 errors += 1
611 errors += 1
612 if state in "a" and f in m1:
612 if state in "a" and f in m1:
613 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
613 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
614 errors += 1
614 errors += 1
615 if state in "m" and f not in m1 and f not in m2:
615 if state in "m" and f not in m1 and f not in m2:
616 ui.warn(_("%s in state %s, but not in either manifest\n") %
616 ui.warn(_("%s in state %s, but not in either manifest\n") %
617 (f, state))
617 (f, state))
618 errors += 1
618 errors += 1
619 for f in m1:
619 for f in m1:
620 state = repo.dirstate[f]
620 state = repo.dirstate[f]
621 if state not in "nrm":
621 if state not in "nrm":
622 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
622 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
623 errors += 1
623 errors += 1
624 if errors:
624 if errors:
625 error = _(".hg/dirstate inconsistent with current parent's manifest")
625 error = _(".hg/dirstate inconsistent with current parent's manifest")
626 raise util.Abort(error)
626 raise util.Abort(error)
627
627
628 def showconfig(ui, repo, *values, **opts):
628 def showconfig(ui, repo, *values, **opts):
629 """show combined config settings from all hgrc files
629 """show combined config settings from all hgrc files
630
630
631 With no args, print names and values of all config items.
631 With no args, print names and values of all config items.
632
632
633 With one arg of the form section.name, print just the value of
633 With one arg of the form section.name, print just the value of
634 that config item.
634 that config item.
635
635
636 With multiple args, print names and values of all config items
636 With multiple args, print names and values of all config items
637 with matching section names."""
637 with matching section names."""
638
638
639 untrusted = bool(opts.get('untrusted'))
639 untrusted = bool(opts.get('untrusted'))
640 if values:
640 if values:
641 if len([v for v in values if '.' in v]) > 1:
641 if len([v for v in values if '.' in v]) > 1:
642 raise util.Abort(_('only one config item permitted'))
642 raise util.Abort(_('only one config item permitted'))
643 for section, name, value in ui.walkconfig(untrusted=untrusted):
643 for section, name, value in ui.walkconfig(untrusted=untrusted):
644 sectname = section + '.' + name
644 sectname = section + '.' + name
645 if values:
645 if values:
646 for v in values:
646 for v in values:
647 if v == section:
647 if v == section:
648 ui.write('%s=%s\n' % (sectname, value))
648 ui.write('%s=%s\n' % (sectname, value))
649 elif v == sectname:
649 elif v == sectname:
650 ui.write(value, '\n')
650 ui.write(value, '\n')
651 else:
651 else:
652 ui.write('%s=%s\n' % (sectname, value))
652 ui.write('%s=%s\n' % (sectname, value))
653
653
654 def debugsetparents(ui, repo, rev1, rev2=None):
654 def debugsetparents(ui, repo, rev1, rev2=None):
655 """manually set the parents of the current working directory
655 """manually set the parents of the current working directory
656
656
657 This is useful for writing repository conversion tools, but should
657 This is useful for writing repository conversion tools, but should
658 be used with care.
658 be used with care.
659 """
659 """
660
660
661 if not rev2:
661 if not rev2:
662 rev2 = hex(nullid)
662 rev2 = hex(nullid)
663
663
664 wlock = repo.wlock()
664 wlock = repo.wlock()
665 try:
665 try:
666 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
666 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
667 finally:
667 finally:
668 del wlock
668 del wlock
669
669
670 def debugstate(ui, repo):
670 def debugstate(ui, repo):
671 """show the contents of the current dirstate"""
671 """show the contents of the current dirstate"""
672 k = repo.dirstate._map.items()
672 k = repo.dirstate._map.items()
673 k.sort()
673 k.sort()
674 for file_, ent in k:
674 for file_, ent in k:
675 if ent[3] == -1:
675 if ent[3] == -1:
676 # Pad or slice to locale representation
676 # Pad or slice to locale representation
677 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(0)))
677 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(0)))
678 timestr = 'unset'
678 timestr = 'unset'
679 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
679 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
680 else:
680 else:
681 timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ent[3]))
681 timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ent[3]))
682 if ent[1] & 020000:
682 if ent[1] & 020000:
683 mode = 'lnk'
683 mode = 'lnk'
684 else:
684 else:
685 mode = '%3o' % (ent[1] & 0777)
685 mode = '%3o' % (ent[1] & 0777)
686 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
686 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
687 for f in repo.dirstate.copies():
687 for f in repo.dirstate.copies():
688 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
688 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
689
689
690 def debugdata(ui, file_, rev):
690 def debugdata(ui, file_, rev):
691 """dump the contents of a data file revision"""
691 """dump the contents of a data file revision"""
692 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
692 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
693 try:
693 try:
694 ui.write(r.revision(r.lookup(rev)))
694 ui.write(r.revision(r.lookup(rev)))
695 except KeyError:
695 except KeyError:
696 raise util.Abort(_('invalid revision identifier %s') % rev)
696 raise util.Abort(_('invalid revision identifier %s') % rev)
697
697
698 def debugdate(ui, date, range=None, **opts):
698 def debugdate(ui, date, range=None, **opts):
699 """parse and display a date"""
699 """parse and display a date"""
700 if opts["extended"]:
700 if opts["extended"]:
701 d = util.parsedate(date, util.extendeddateformats)
701 d = util.parsedate(date, util.extendeddateformats)
702 else:
702 else:
703 d = util.parsedate(date)
703 d = util.parsedate(date)
704 ui.write("internal: %s %s\n" % d)
704 ui.write("internal: %s %s\n" % d)
705 ui.write("standard: %s\n" % util.datestr(d))
705 ui.write("standard: %s\n" % util.datestr(d))
706 if range:
706 if range:
707 m = util.matchdate(range)
707 m = util.matchdate(range)
708 ui.write("match: %s\n" % m(d[0]))
708 ui.write("match: %s\n" % m(d[0]))
709
709
710 def debugindex(ui, file_):
710 def debugindex(ui, file_):
711 """dump the contents of an index file"""
711 """dump the contents of an index file"""
712 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
712 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
713 ui.write(" rev offset length base linkrev" +
713 ui.write(" rev offset length base linkrev" +
714 " nodeid p1 p2\n")
714 " nodeid p1 p2\n")
715 for i in xrange(r.count()):
715 for i in xrange(r.count()):
716 node = r.node(i)
716 node = r.node(i)
717 try:
717 try:
718 pp = r.parents(node)
718 pp = r.parents(node)
719 except:
719 except:
720 pp = [nullid, nullid]
720 pp = [nullid, nullid]
721 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
721 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
722 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
722 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
723 short(node), short(pp[0]), short(pp[1])))
723 short(node), short(pp[0]), short(pp[1])))
724
724
725 def debugindexdot(ui, file_):
725 def debugindexdot(ui, file_):
726 """dump an index DAG as a .dot file"""
726 """dump an index DAG as a .dot file"""
727 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
727 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
728 ui.write("digraph G {\n")
728 ui.write("digraph G {\n")
729 for i in xrange(r.count()):
729 for i in xrange(r.count()):
730 node = r.node(i)
730 node = r.node(i)
731 pp = r.parents(node)
731 pp = r.parents(node)
732 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
732 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
733 if pp[1] != nullid:
733 if pp[1] != nullid:
734 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
734 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
735 ui.write("}\n")
735 ui.write("}\n")
736
736
737 def debuginstall(ui):
737 def debuginstall(ui):
738 '''test Mercurial installation'''
738 '''test Mercurial installation'''
739
739
740 def writetemp(contents):
740 def writetemp(contents):
741 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
741 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
742 f = os.fdopen(fd, "wb")
742 f = os.fdopen(fd, "wb")
743 f.write(contents)
743 f.write(contents)
744 f.close()
744 f.close()
745 return name
745 return name
746
746
747 problems = 0
747 problems = 0
748
748
749 # encoding
749 # encoding
750 ui.status(_("Checking encoding (%s)...\n") % util._encoding)
750 ui.status(_("Checking encoding (%s)...\n") % util._encoding)
751 try:
751 try:
752 util.fromlocal("test")
752 util.fromlocal("test")
753 except util.Abort, inst:
753 except util.Abort, inst:
754 ui.write(" %s\n" % inst)
754 ui.write(" %s\n" % inst)
755 ui.write(_(" (check that your locale is properly set)\n"))
755 ui.write(_(" (check that your locale is properly set)\n"))
756 problems += 1
756 problems += 1
757
757
758 # compiled modules
758 # compiled modules
759 ui.status(_("Checking extensions...\n"))
759 ui.status(_("Checking extensions...\n"))
760 try:
760 try:
761 import bdiff, mpatch, base85
761 import bdiff, mpatch, base85
762 except Exception, inst:
762 except Exception, inst:
763 ui.write(" %s\n" % inst)
763 ui.write(" %s\n" % inst)
764 ui.write(_(" One or more extensions could not be found"))
764 ui.write(_(" One or more extensions could not be found"))
765 ui.write(_(" (check that you compiled the extensions)\n"))
765 ui.write(_(" (check that you compiled the extensions)\n"))
766 problems += 1
766 problems += 1
767
767
768 # templates
768 # templates
769 ui.status(_("Checking templates...\n"))
769 ui.status(_("Checking templates...\n"))
770 try:
770 try:
771 import templater
771 import templater
772 t = templater.templater(templater.templatepath("map-cmdline.default"))
772 t = templater.templater(templater.templatepath("map-cmdline.default"))
773 except Exception, inst:
773 except Exception, inst:
774 ui.write(" %s\n" % inst)
774 ui.write(" %s\n" % inst)
775 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
775 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
776 problems += 1
776 problems += 1
777
777
778 # patch
778 # patch
779 ui.status(_("Checking patch...\n"))
779 ui.status(_("Checking patch...\n"))
780 patchproblems = 0
780 patchproblems = 0
781 a = "1\n2\n3\n4\n"
781 a = "1\n2\n3\n4\n"
782 b = "1\n2\n3\ninsert\n4\n"
782 b = "1\n2\n3\ninsert\n4\n"
783 fa = writetemp(a)
783 fa = writetemp(a)
784 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
784 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
785 os.path.basename(fa))
785 os.path.basename(fa))
786 fd = writetemp(d)
786 fd = writetemp(d)
787
787
788 files = {}
788 files = {}
789 try:
789 try:
790 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
790 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
791 except util.Abort, e:
791 except util.Abort, e:
792 ui.write(_(" patch call failed:\n"))
792 ui.write(_(" patch call failed:\n"))
793 ui.write(" " + str(e) + "\n")
793 ui.write(" " + str(e) + "\n")
794 patchproblems += 1
794 patchproblems += 1
795 else:
795 else:
796 if list(files) != [os.path.basename(fa)]:
796 if list(files) != [os.path.basename(fa)]:
797 ui.write(_(" unexpected patch output!\n"))
797 ui.write(_(" unexpected patch output!\n"))
798 patchproblems += 1
798 patchproblems += 1
799 a = file(fa).read()
799 a = file(fa).read()
800 if a != b:
800 if a != b:
801 ui.write(_(" patch test failed!\n"))
801 ui.write(_(" patch test failed!\n"))
802 patchproblems += 1
802 patchproblems += 1
803
803
804 if patchproblems:
804 if patchproblems:
805 if ui.config('ui', 'patch'):
805 if ui.config('ui', 'patch'):
806 ui.write(_(" (Current patch tool may be incompatible with patch,"
806 ui.write(_(" (Current patch tool may be incompatible with patch,"
807 " or misconfigured. Please check your .hgrc file)\n"))
807 " or misconfigured. Please check your .hgrc file)\n"))
808 else:
808 else:
809 ui.write(_(" Internal patcher failure, please report this error"
809 ui.write(_(" Internal patcher failure, please report this error"
810 " to http://www.selenic.com/mercurial/bts\n"))
810 " to http://www.selenic.com/mercurial/bts\n"))
811 problems += patchproblems
811 problems += patchproblems
812
812
813 os.unlink(fa)
813 os.unlink(fa)
814 os.unlink(fd)
814 os.unlink(fd)
815
815
816 # merge helper
817 ui.status(_("Checking merge helper...\n"))
818 cmd = (os.environ.get("HGMERGE") or ui.config("ui", "merge")
819 or "hgmerge")
820 cmdpath = util.find_exe(cmd) or util.find_exe(cmd.split()[0])
821 if not cmdpath:
822 if cmd == 'hgmerge':
823 ui.write(_(" No merge helper set and can't find default"
824 " hgmerge script in PATH\n"))
825 ui.write(_(" (specify a merge helper in your .hgrc file)\n"))
826 else:
827 ui.write(_(" Can't find merge helper '%s' in PATH\n") % cmd)
828 ui.write(_(" (specify a merge helper in your .hgrc file)\n"))
829 problems += 1
830 else:
831 # actually attempt a patch here
832 fa = writetemp("1\n2\n3\n4\n")
833 fl = writetemp("1\n2\n3\ninsert\n4\n")
834 fr = writetemp("begin\n1\n2\n3\n4\n")
835 r = util.system('%s "%s" "%s" "%s"' % (cmd, fl, fa, fr))
836 if r:
837 ui.write(_(" Got unexpected merge error %d!\n") % r)
838 problems += 1
839 m = file(fl).read()
840 if m != "begin\n1\n2\n3\ninsert\n4\n":
841 ui.write(_(" Got unexpected merge results!\n"))
842 ui.write(_(" (your merge helper may have the"
843 " wrong argument order)\n"))
844 ui.write(_(" Result: %r\n") % m)
845 problems += 1
846 os.unlink(fa)
847 os.unlink(fl)
848 os.unlink(fr)
849
850 # editor
816 # editor
851 ui.status(_("Checking commit editor...\n"))
817 ui.status(_("Checking commit editor...\n"))
852 editor = ui.geteditor()
818 editor = ui.geteditor()
853 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
819 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
854 if not cmdpath:
820 if not cmdpath:
855 if editor == 'vi':
821 if editor == 'vi':
856 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
822 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
857 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
823 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
858 else:
824 else:
859 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
825 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
860 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
826 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
861 problems += 1
827 problems += 1
862
828
863 # check username
829 # check username
864 ui.status(_("Checking username...\n"))
830 ui.status(_("Checking username...\n"))
865 user = os.environ.get("HGUSER")
831 user = os.environ.get("HGUSER")
866 if user is None:
832 if user is None:
867 user = ui.config("ui", "username")
833 user = ui.config("ui", "username")
868 if user is None:
834 if user is None:
869 user = os.environ.get("EMAIL")
835 user = os.environ.get("EMAIL")
870 if not user:
836 if not user:
871 ui.warn(" ")
837 ui.warn(" ")
872 ui.username()
838 ui.username()
873 ui.write(_(" (specify a username in your .hgrc file)\n"))
839 ui.write(_(" (specify a username in your .hgrc file)\n"))
874
840
875 if not problems:
841 if not problems:
876 ui.status(_("No problems detected\n"))
842 ui.status(_("No problems detected\n"))
877 else:
843 else:
878 ui.write(_("%s problems detected,"
844 ui.write(_("%s problems detected,"
879 " please check your install!\n") % problems)
845 " please check your install!\n") % problems)
880
846
881 return problems
847 return problems
882
848
883 def debugrename(ui, repo, file1, *pats, **opts):
849 def debugrename(ui, repo, file1, *pats, **opts):
884 """dump rename information"""
850 """dump rename information"""
885
851
886 ctx = repo.changectx(opts.get('rev', 'tip'))
852 ctx = repo.changectx(opts.get('rev', 'tip'))
887 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
853 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
888 ctx.node()):
854 ctx.node()):
889 fctx = ctx.filectx(abs)
855 fctx = ctx.filectx(abs)
890 m = fctx.filelog().renamed(fctx.filenode())
856 m = fctx.filelog().renamed(fctx.filenode())
891 if m:
857 if m:
892 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
858 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
893 else:
859 else:
894 ui.write(_("%s not renamed\n") % rel)
860 ui.write(_("%s not renamed\n") % rel)
895
861
896 def debugwalk(ui, repo, *pats, **opts):
862 def debugwalk(ui, repo, *pats, **opts):
897 """show how files match on given patterns"""
863 """show how files match on given patterns"""
898 items = list(cmdutil.walk(repo, pats, opts))
864 items = list(cmdutil.walk(repo, pats, opts))
899 if not items:
865 if not items:
900 return
866 return
901 fmt = '%%s %%-%ds %%-%ds %%s' % (
867 fmt = '%%s %%-%ds %%-%ds %%s' % (
902 max([len(abs) for (src, abs, rel, exact) in items]),
868 max([len(abs) for (src, abs, rel, exact) in items]),
903 max([len(rel) for (src, abs, rel, exact) in items]))
869 max([len(rel) for (src, abs, rel, exact) in items]))
904 for src, abs, rel, exact in items:
870 for src, abs, rel, exact in items:
905 line = fmt % (src, abs, rel, exact and 'exact' or '')
871 line = fmt % (src, abs, rel, exact and 'exact' or '')
906 ui.write("%s\n" % line.rstrip())
872 ui.write("%s\n" % line.rstrip())
907
873
908 def diff(ui, repo, *pats, **opts):
874 def diff(ui, repo, *pats, **opts):
909 """diff repository (or selected files)
875 """diff repository (or selected files)
910
876
911 Show differences between revisions for the specified files.
877 Show differences between revisions for the specified files.
912
878
913 Differences between files are shown using the unified diff format.
879 Differences between files are shown using the unified diff format.
914
880
915 NOTE: diff may generate unexpected results for merges, as it will
881 NOTE: diff may generate unexpected results for merges, as it will
916 default to comparing against the working directory's first parent
882 default to comparing against the working directory's first parent
917 changeset if no revisions are specified.
883 changeset if no revisions are specified.
918
884
919 When two revision arguments are given, then changes are shown
885 When two revision arguments are given, then changes are shown
920 between those revisions. If only one revision is specified then
886 between those revisions. If only one revision is specified then
921 that revision is compared to the working directory, and, when no
887 that revision is compared to the working directory, and, when no
922 revisions are specified, the working directory files are compared
888 revisions are specified, the working directory files are compared
923 to its parent.
889 to its parent.
924
890
925 Without the -a option, diff will avoid generating diffs of files
891 Without the -a option, diff will avoid generating diffs of files
926 it detects as binary. With -a, diff will generate a diff anyway,
892 it detects as binary. With -a, diff will generate a diff anyway,
927 probably with undesirable results.
893 probably with undesirable results.
928 """
894 """
929 node1, node2 = cmdutil.revpair(repo, opts['rev'])
895 node1, node2 = cmdutil.revpair(repo, opts['rev'])
930
896
931 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
897 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
932
898
933 patch.diff(repo, node1, node2, fns, match=matchfn,
899 patch.diff(repo, node1, node2, fns, match=matchfn,
934 opts=patch.diffopts(ui, opts))
900 opts=patch.diffopts(ui, opts))
935
901
936 def export(ui, repo, *changesets, **opts):
902 def export(ui, repo, *changesets, **opts):
937 """dump the header and diffs for one or more changesets
903 """dump the header and diffs for one or more changesets
938
904
939 Print the changeset header and diffs for one or more revisions.
905 Print the changeset header and diffs for one or more revisions.
940
906
941 The information shown in the changeset header is: author,
907 The information shown in the changeset header is: author,
942 changeset hash, parent(s) and commit comment.
908 changeset hash, parent(s) and commit comment.
943
909
944 NOTE: export may generate unexpected diff output for merge changesets,
910 NOTE: export may generate unexpected diff output for merge changesets,
945 as it will compare the merge changeset against its first parent only.
911 as it will compare the merge changeset against its first parent only.
946
912
947 Output may be to a file, in which case the name of the file is
913 Output may be to a file, in which case the name of the file is
948 given using a format string. The formatting rules are as follows:
914 given using a format string. The formatting rules are as follows:
949
915
950 %% literal "%" character
916 %% literal "%" character
951 %H changeset hash (40 bytes of hexadecimal)
917 %H changeset hash (40 bytes of hexadecimal)
952 %N number of patches being generated
918 %N number of patches being generated
953 %R changeset revision number
919 %R changeset revision number
954 %b basename of the exporting repository
920 %b basename of the exporting repository
955 %h short-form changeset hash (12 bytes of hexadecimal)
921 %h short-form changeset hash (12 bytes of hexadecimal)
956 %n zero-padded sequence number, starting at 1
922 %n zero-padded sequence number, starting at 1
957 %r zero-padded changeset revision number
923 %r zero-padded changeset revision number
958
924
959 Without the -a option, export will avoid generating diffs of files
925 Without the -a option, export will avoid generating diffs of files
960 it detects as binary. With -a, export will generate a diff anyway,
926 it detects as binary. With -a, export will generate a diff anyway,
961 probably with undesirable results.
927 probably with undesirable results.
962
928
963 With the --switch-parent option, the diff will be against the second
929 With the --switch-parent option, the diff will be against the second
964 parent. It can be useful to review a merge.
930 parent. It can be useful to review a merge.
965 """
931 """
966 if not changesets:
932 if not changesets:
967 raise util.Abort(_("export requires at least one changeset"))
933 raise util.Abort(_("export requires at least one changeset"))
968 revs = cmdutil.revrange(repo, changesets)
934 revs = cmdutil.revrange(repo, changesets)
969 if len(revs) > 1:
935 if len(revs) > 1:
970 ui.note(_('exporting patches:\n'))
936 ui.note(_('exporting patches:\n'))
971 else:
937 else:
972 ui.note(_('exporting patch:\n'))
938 ui.note(_('exporting patch:\n'))
973 patch.export(repo, revs, template=opts['output'],
939 patch.export(repo, revs, template=opts['output'],
974 switch_parent=opts['switch_parent'],
940 switch_parent=opts['switch_parent'],
975 opts=patch.diffopts(ui, opts))
941 opts=patch.diffopts(ui, opts))
976
942
977 def grep(ui, repo, pattern, *pats, **opts):
943 def grep(ui, repo, pattern, *pats, **opts):
978 """search for a pattern in specified files and revisions
944 """search for a pattern in specified files and revisions
979
945
980 Search revisions of files for a regular expression.
946 Search revisions of files for a regular expression.
981
947
982 This command behaves differently than Unix grep. It only accepts
948 This command behaves differently than Unix grep. It only accepts
983 Python/Perl regexps. It searches repository history, not the
949 Python/Perl regexps. It searches repository history, not the
984 working directory. It always prints the revision number in which
950 working directory. It always prints the revision number in which
985 a match appears.
951 a match appears.
986
952
987 By default, grep only prints output for the first revision of a
953 By default, grep only prints output for the first revision of a
988 file in which it finds a match. To get it to print every revision
954 file in which it finds a match. To get it to print every revision
989 that contains a change in match status ("-" for a match that
955 that contains a change in match status ("-" for a match that
990 becomes a non-match, or "+" for a non-match that becomes a match),
956 becomes a non-match, or "+" for a non-match that becomes a match),
991 use the --all flag.
957 use the --all flag.
992 """
958 """
993 reflags = 0
959 reflags = 0
994 if opts['ignore_case']:
960 if opts['ignore_case']:
995 reflags |= re.I
961 reflags |= re.I
996 try:
962 try:
997 regexp = re.compile(pattern, reflags)
963 regexp = re.compile(pattern, reflags)
998 except Exception, inst:
964 except Exception, inst:
999 ui.warn(_("grep: invalid match pattern: %s!\n") % inst)
965 ui.warn(_("grep: invalid match pattern: %s!\n") % inst)
1000 return None
966 return None
1001 sep, eol = ':', '\n'
967 sep, eol = ':', '\n'
1002 if opts['print0']:
968 if opts['print0']:
1003 sep = eol = '\0'
969 sep = eol = '\0'
1004
970
1005 fcache = {}
971 fcache = {}
1006 def getfile(fn):
972 def getfile(fn):
1007 if fn not in fcache:
973 if fn not in fcache:
1008 fcache[fn] = repo.file(fn)
974 fcache[fn] = repo.file(fn)
1009 return fcache[fn]
975 return fcache[fn]
1010
976
1011 def matchlines(body):
977 def matchlines(body):
1012 begin = 0
978 begin = 0
1013 linenum = 0
979 linenum = 0
1014 while True:
980 while True:
1015 match = regexp.search(body, begin)
981 match = regexp.search(body, begin)
1016 if not match:
982 if not match:
1017 break
983 break
1018 mstart, mend = match.span()
984 mstart, mend = match.span()
1019 linenum += body.count('\n', begin, mstart) + 1
985 linenum += body.count('\n', begin, mstart) + 1
1020 lstart = body.rfind('\n', begin, mstart) + 1 or begin
986 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1021 lend = body.find('\n', mend)
987 lend = body.find('\n', mend)
1022 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
988 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1023 begin = lend + 1
989 begin = lend + 1
1024
990
1025 class linestate(object):
991 class linestate(object):
1026 def __init__(self, line, linenum, colstart, colend):
992 def __init__(self, line, linenum, colstart, colend):
1027 self.line = line
993 self.line = line
1028 self.linenum = linenum
994 self.linenum = linenum
1029 self.colstart = colstart
995 self.colstart = colstart
1030 self.colend = colend
996 self.colend = colend
1031
997
1032 def __eq__(self, other):
998 def __eq__(self, other):
1033 return self.line == other.line
999 return self.line == other.line
1034
1000
1035 matches = {}
1001 matches = {}
1036 copies = {}
1002 copies = {}
1037 def grepbody(fn, rev, body):
1003 def grepbody(fn, rev, body):
1038 matches[rev].setdefault(fn, [])
1004 matches[rev].setdefault(fn, [])
1039 m = matches[rev][fn]
1005 m = matches[rev][fn]
1040 for lnum, cstart, cend, line in matchlines(body):
1006 for lnum, cstart, cend, line in matchlines(body):
1041 s = linestate(line, lnum, cstart, cend)
1007 s = linestate(line, lnum, cstart, cend)
1042 m.append(s)
1008 m.append(s)
1043
1009
1044 def difflinestates(a, b):
1010 def difflinestates(a, b):
1045 sm = difflib.SequenceMatcher(None, a, b)
1011 sm = difflib.SequenceMatcher(None, a, b)
1046 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1012 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1047 if tag == 'insert':
1013 if tag == 'insert':
1048 for i in xrange(blo, bhi):
1014 for i in xrange(blo, bhi):
1049 yield ('+', b[i])
1015 yield ('+', b[i])
1050 elif tag == 'delete':
1016 elif tag == 'delete':
1051 for i in xrange(alo, ahi):
1017 for i in xrange(alo, ahi):
1052 yield ('-', a[i])
1018 yield ('-', a[i])
1053 elif tag == 'replace':
1019 elif tag == 'replace':
1054 for i in xrange(alo, ahi):
1020 for i in xrange(alo, ahi):
1055 yield ('-', a[i])
1021 yield ('-', a[i])
1056 for i in xrange(blo, bhi):
1022 for i in xrange(blo, bhi):
1057 yield ('+', b[i])
1023 yield ('+', b[i])
1058
1024
1059 prev = {}
1025 prev = {}
1060 def display(fn, rev, states, prevstates):
1026 def display(fn, rev, states, prevstates):
1061 found = False
1027 found = False
1062 filerevmatches = {}
1028 filerevmatches = {}
1063 r = prev.get(fn, -1)
1029 r = prev.get(fn, -1)
1064 if opts['all']:
1030 if opts['all']:
1065 iter = difflinestates(states, prevstates)
1031 iter = difflinestates(states, prevstates)
1066 else:
1032 else:
1067 iter = [('', l) for l in prevstates]
1033 iter = [('', l) for l in prevstates]
1068 for change, l in iter:
1034 for change, l in iter:
1069 cols = [fn, str(r)]
1035 cols = [fn, str(r)]
1070 if opts['line_number']:
1036 if opts['line_number']:
1071 cols.append(str(l.linenum))
1037 cols.append(str(l.linenum))
1072 if opts['all']:
1038 if opts['all']:
1073 cols.append(change)
1039 cols.append(change)
1074 if opts['user']:
1040 if opts['user']:
1075 cols.append(ui.shortuser(get(r)[1]))
1041 cols.append(ui.shortuser(get(r)[1]))
1076 if opts['files_with_matches']:
1042 if opts['files_with_matches']:
1077 c = (fn, r)
1043 c = (fn, r)
1078 if c in filerevmatches:
1044 if c in filerevmatches:
1079 continue
1045 continue
1080 filerevmatches[c] = 1
1046 filerevmatches[c] = 1
1081 else:
1047 else:
1082 cols.append(l.line)
1048 cols.append(l.line)
1083 ui.write(sep.join(cols), eol)
1049 ui.write(sep.join(cols), eol)
1084 found = True
1050 found = True
1085 return found
1051 return found
1086
1052
1087 fstate = {}
1053 fstate = {}
1088 skip = {}
1054 skip = {}
1089 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1055 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1090 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1056 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1091 found = False
1057 found = False
1092 follow = opts.get('follow')
1058 follow = opts.get('follow')
1093 for st, rev, fns in changeiter:
1059 for st, rev, fns in changeiter:
1094 if st == 'window':
1060 if st == 'window':
1095 matches.clear()
1061 matches.clear()
1096 elif st == 'add':
1062 elif st == 'add':
1097 mf = repo.changectx(rev).manifest()
1063 mf = repo.changectx(rev).manifest()
1098 matches[rev] = {}
1064 matches[rev] = {}
1099 for fn in fns:
1065 for fn in fns:
1100 if fn in skip:
1066 if fn in skip:
1101 continue
1067 continue
1102 try:
1068 try:
1103 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1069 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1104 fstate.setdefault(fn, [])
1070 fstate.setdefault(fn, [])
1105 if follow:
1071 if follow:
1106 copied = getfile(fn).renamed(mf[fn])
1072 copied = getfile(fn).renamed(mf[fn])
1107 if copied:
1073 if copied:
1108 copies.setdefault(rev, {})[fn] = copied[0]
1074 copies.setdefault(rev, {})[fn] = copied[0]
1109 except KeyError:
1075 except KeyError:
1110 pass
1076 pass
1111 elif st == 'iter':
1077 elif st == 'iter':
1112 states = matches[rev].items()
1078 states = matches[rev].items()
1113 states.sort()
1079 states.sort()
1114 for fn, m in states:
1080 for fn, m in states:
1115 copy = copies.get(rev, {}).get(fn)
1081 copy = copies.get(rev, {}).get(fn)
1116 if fn in skip:
1082 if fn in skip:
1117 if copy:
1083 if copy:
1118 skip[copy] = True
1084 skip[copy] = True
1119 continue
1085 continue
1120 if fn in prev or fstate[fn]:
1086 if fn in prev or fstate[fn]:
1121 r = display(fn, rev, m, fstate[fn])
1087 r = display(fn, rev, m, fstate[fn])
1122 found = found or r
1088 found = found or r
1123 if r and not opts['all']:
1089 if r and not opts['all']:
1124 skip[fn] = True
1090 skip[fn] = True
1125 if copy:
1091 if copy:
1126 skip[copy] = True
1092 skip[copy] = True
1127 fstate[fn] = m
1093 fstate[fn] = m
1128 if copy:
1094 if copy:
1129 fstate[copy] = m
1095 fstate[copy] = m
1130 prev[fn] = rev
1096 prev[fn] = rev
1131
1097
1132 fstate = fstate.items()
1098 fstate = fstate.items()
1133 fstate.sort()
1099 fstate.sort()
1134 for fn, state in fstate:
1100 for fn, state in fstate:
1135 if fn in skip:
1101 if fn in skip:
1136 continue
1102 continue
1137 if fn not in copies.get(prev[fn], {}):
1103 if fn not in copies.get(prev[fn], {}):
1138 found = display(fn, rev, {}, state) or found
1104 found = display(fn, rev, {}, state) or found
1139 return (not found and 1) or 0
1105 return (not found and 1) or 0
1140
1106
1141 def heads(ui, repo, *branchrevs, **opts):
1107 def heads(ui, repo, *branchrevs, **opts):
1142 """show current repository heads or show branch heads
1108 """show current repository heads or show branch heads
1143
1109
1144 With no arguments, show all repository head changesets.
1110 With no arguments, show all repository head changesets.
1145
1111
1146 If branch or revisions names are given this will show the heads of
1112 If branch or revisions names are given this will show the heads of
1147 the specified branches or the branches those revisions are tagged
1113 the specified branches or the branches those revisions are tagged
1148 with.
1114 with.
1149
1115
1150 Repository "heads" are changesets that don't have child
1116 Repository "heads" are changesets that don't have child
1151 changesets. They are where development generally takes place and
1117 changesets. They are where development generally takes place and
1152 are the usual targets for update and merge operations.
1118 are the usual targets for update and merge operations.
1153
1119
1154 Branch heads are changesets that have a given branch tag, but have
1120 Branch heads are changesets that have a given branch tag, but have
1155 no child changesets with that tag. They are usually where
1121 no child changesets with that tag. They are usually where
1156 development on the given branch takes place.
1122 development on the given branch takes place.
1157 """
1123 """
1158 if opts['rev']:
1124 if opts['rev']:
1159 start = repo.lookup(opts['rev'])
1125 start = repo.lookup(opts['rev'])
1160 else:
1126 else:
1161 start = None
1127 start = None
1162 if not branchrevs:
1128 if not branchrevs:
1163 # Assume we're looking repo-wide heads if no revs were specified.
1129 # Assume we're looking repo-wide heads if no revs were specified.
1164 heads = repo.heads(start)
1130 heads = repo.heads(start)
1165 else:
1131 else:
1166 heads = []
1132 heads = []
1167 visitedset = util.set()
1133 visitedset = util.set()
1168 for branchrev in branchrevs:
1134 for branchrev in branchrevs:
1169 branch = repo.changectx(branchrev).branch()
1135 branch = repo.changectx(branchrev).branch()
1170 if branch in visitedset:
1136 if branch in visitedset:
1171 continue
1137 continue
1172 visitedset.add(branch)
1138 visitedset.add(branch)
1173 bheads = repo.branchheads(branch, start)
1139 bheads = repo.branchheads(branch, start)
1174 if not bheads:
1140 if not bheads:
1175 if branch != branchrev:
1141 if branch != branchrev:
1176 ui.warn(_("no changes on branch %s containing %s are "
1142 ui.warn(_("no changes on branch %s containing %s are "
1177 "reachable from %s\n")
1143 "reachable from %s\n")
1178 % (branch, branchrev, opts['rev']))
1144 % (branch, branchrev, opts['rev']))
1179 else:
1145 else:
1180 ui.warn(_("no changes on branch %s are reachable from %s\n")
1146 ui.warn(_("no changes on branch %s are reachable from %s\n")
1181 % (branch, opts['rev']))
1147 % (branch, opts['rev']))
1182 heads.extend(bheads)
1148 heads.extend(bheads)
1183 if not heads:
1149 if not heads:
1184 return 1
1150 return 1
1185 displayer = cmdutil.show_changeset(ui, repo, opts)
1151 displayer = cmdutil.show_changeset(ui, repo, opts)
1186 for n in heads:
1152 for n in heads:
1187 displayer.show(changenode=n)
1153 displayer.show(changenode=n)
1188
1154
1189 def help_(ui, name=None, with_version=False):
1155 def help_(ui, name=None, with_version=False):
1190 """show help for a command, extension, or list of commands
1156 """show help for a command, extension, or list of commands
1191
1157
1192 With no arguments, print a list of commands and short help.
1158 With no arguments, print a list of commands and short help.
1193
1159
1194 Given a command name, print help for that command.
1160 Given a command name, print help for that command.
1195
1161
1196 Given an extension name, print help for that extension, and the
1162 Given an extension name, print help for that extension, and the
1197 commands it provides."""
1163 commands it provides."""
1198 option_lists = []
1164 option_lists = []
1199
1165
1200 def addglobalopts(aliases):
1166 def addglobalopts(aliases):
1201 if ui.verbose:
1167 if ui.verbose:
1202 option_lists.append((_("global options:"), globalopts))
1168 option_lists.append((_("global options:"), globalopts))
1203 if name == 'shortlist':
1169 if name == 'shortlist':
1204 option_lists.append((_('use "hg help" for the full list '
1170 option_lists.append((_('use "hg help" for the full list '
1205 'of commands'), ()))
1171 'of commands'), ()))
1206 else:
1172 else:
1207 if name == 'shortlist':
1173 if name == 'shortlist':
1208 msg = _('use "hg help" for the full list of commands '
1174 msg = _('use "hg help" for the full list of commands '
1209 'or "hg -v" for details')
1175 'or "hg -v" for details')
1210 elif aliases:
1176 elif aliases:
1211 msg = _('use "hg -v help%s" to show aliases and '
1177 msg = _('use "hg -v help%s" to show aliases and '
1212 'global options') % (name and " " + name or "")
1178 'global options') % (name and " " + name or "")
1213 else:
1179 else:
1214 msg = _('use "hg -v help %s" to show global options') % name
1180 msg = _('use "hg -v help %s" to show global options') % name
1215 option_lists.append((msg, ()))
1181 option_lists.append((msg, ()))
1216
1182
1217 def helpcmd(name):
1183 def helpcmd(name):
1218 if with_version:
1184 if with_version:
1219 version_(ui)
1185 version_(ui)
1220 ui.write('\n')
1186 ui.write('\n')
1221 aliases, i = cmdutil.findcmd(ui, name, table)
1187 aliases, i = cmdutil.findcmd(ui, name, table)
1222 # synopsis
1188 # synopsis
1223 ui.write("%s\n" % i[2])
1189 ui.write("%s\n" % i[2])
1224
1190
1225 # aliases
1191 # aliases
1226 if not ui.quiet and len(aliases) > 1:
1192 if not ui.quiet and len(aliases) > 1:
1227 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1193 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1228
1194
1229 # description
1195 # description
1230 doc = i[0].__doc__
1196 doc = i[0].__doc__
1231 if not doc:
1197 if not doc:
1232 doc = _("(No help text available)")
1198 doc = _("(No help text available)")
1233 if ui.quiet:
1199 if ui.quiet:
1234 doc = doc.splitlines(0)[0]
1200 doc = doc.splitlines(0)[0]
1235 ui.write("\n%s\n" % doc.rstrip())
1201 ui.write("\n%s\n" % doc.rstrip())
1236
1202
1237 if not ui.quiet:
1203 if not ui.quiet:
1238 # options
1204 # options
1239 if i[1]:
1205 if i[1]:
1240 option_lists.append((_("options:\n"), i[1]))
1206 option_lists.append((_("options:\n"), i[1]))
1241
1207
1242 addglobalopts(False)
1208 addglobalopts(False)
1243
1209
1244 def helplist(header, select=None):
1210 def helplist(header, select=None):
1245 h = {}
1211 h = {}
1246 cmds = {}
1212 cmds = {}
1247 for c, e in table.items():
1213 for c, e in table.items():
1248 f = c.split("|", 1)[0]
1214 f = c.split("|", 1)[0]
1249 if select and not select(f):
1215 if select and not select(f):
1250 continue
1216 continue
1251 if name == "shortlist" and not f.startswith("^"):
1217 if name == "shortlist" and not f.startswith("^"):
1252 continue
1218 continue
1253 f = f.lstrip("^")
1219 f = f.lstrip("^")
1254 if not ui.debugflag and f.startswith("debug"):
1220 if not ui.debugflag and f.startswith("debug"):
1255 continue
1221 continue
1256 doc = e[0].__doc__
1222 doc = e[0].__doc__
1257 if not doc:
1223 if not doc:
1258 doc = _("(No help text available)")
1224 doc = _("(No help text available)")
1259 h[f] = doc.splitlines(0)[0].rstrip()
1225 h[f] = doc.splitlines(0)[0].rstrip()
1260 cmds[f] = c.lstrip("^")
1226 cmds[f] = c.lstrip("^")
1261
1227
1262 if not h:
1228 if not h:
1263 ui.status(_('no commands defined\n'))
1229 ui.status(_('no commands defined\n'))
1264 return
1230 return
1265
1231
1266 ui.status(header)
1232 ui.status(header)
1267 fns = h.keys()
1233 fns = h.keys()
1268 fns.sort()
1234 fns.sort()
1269 m = max(map(len, fns))
1235 m = max(map(len, fns))
1270 for f in fns:
1236 for f in fns:
1271 if ui.verbose:
1237 if ui.verbose:
1272 commands = cmds[f].replace("|",", ")
1238 commands = cmds[f].replace("|",", ")
1273 ui.write(" %s:\n %s\n"%(commands, h[f]))
1239 ui.write(" %s:\n %s\n"%(commands, h[f]))
1274 else:
1240 else:
1275 ui.write(' %-*s %s\n' % (m, f, h[f]))
1241 ui.write(' %-*s %s\n' % (m, f, h[f]))
1276
1242
1277 if not ui.quiet:
1243 if not ui.quiet:
1278 addglobalopts(True)
1244 addglobalopts(True)
1279
1245
1280 def helptopic(name):
1246 def helptopic(name):
1281 v = None
1247 v = None
1282 for i in help.helptable:
1248 for i in help.helptable:
1283 l = i.split('|')
1249 l = i.split('|')
1284 if name in l:
1250 if name in l:
1285 v = i
1251 v = i
1286 header = l[-1]
1252 header = l[-1]
1287 if not v:
1253 if not v:
1288 raise cmdutil.UnknownCommand(name)
1254 raise cmdutil.UnknownCommand(name)
1289
1255
1290 # description
1256 # description
1291 doc = help.helptable[v]
1257 doc = help.helptable[v]
1292 if not doc:
1258 if not doc:
1293 doc = _("(No help text available)")
1259 doc = _("(No help text available)")
1294 if callable(doc):
1260 if callable(doc):
1295 doc = doc()
1261 doc = doc()
1296
1262
1297 ui.write("%s\n" % header)
1263 ui.write("%s\n" % header)
1298 ui.write("%s\n" % doc.rstrip())
1264 ui.write("%s\n" % doc.rstrip())
1299
1265
1300 def helpext(name):
1266 def helpext(name):
1301 try:
1267 try:
1302 mod = extensions.find(name)
1268 mod = extensions.find(name)
1303 except KeyError:
1269 except KeyError:
1304 raise cmdutil.UnknownCommand(name)
1270 raise cmdutil.UnknownCommand(name)
1305
1271
1306 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1272 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1307 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1273 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1308 for d in doc[1:]:
1274 for d in doc[1:]:
1309 ui.write(d, '\n')
1275 ui.write(d, '\n')
1310
1276
1311 ui.status('\n')
1277 ui.status('\n')
1312
1278
1313 try:
1279 try:
1314 ct = mod.cmdtable
1280 ct = mod.cmdtable
1315 except AttributeError:
1281 except AttributeError:
1316 ct = {}
1282 ct = {}
1317
1283
1318 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1284 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1319 helplist(_('list of commands:\n\n'), modcmds.has_key)
1285 helplist(_('list of commands:\n\n'), modcmds.has_key)
1320
1286
1321 if name and name != 'shortlist':
1287 if name and name != 'shortlist':
1322 i = None
1288 i = None
1323 for f in (helpcmd, helptopic, helpext):
1289 for f in (helpcmd, helptopic, helpext):
1324 try:
1290 try:
1325 f(name)
1291 f(name)
1326 i = None
1292 i = None
1327 break
1293 break
1328 except cmdutil.UnknownCommand, inst:
1294 except cmdutil.UnknownCommand, inst:
1329 i = inst
1295 i = inst
1330 if i:
1296 if i:
1331 raise i
1297 raise i
1332
1298
1333 else:
1299 else:
1334 # program name
1300 # program name
1335 if ui.verbose or with_version:
1301 if ui.verbose or with_version:
1336 version_(ui)
1302 version_(ui)
1337 else:
1303 else:
1338 ui.status(_("Mercurial Distributed SCM\n"))
1304 ui.status(_("Mercurial Distributed SCM\n"))
1339 ui.status('\n')
1305 ui.status('\n')
1340
1306
1341 # list of commands
1307 # list of commands
1342 if name == "shortlist":
1308 if name == "shortlist":
1343 header = _('basic commands:\n\n')
1309 header = _('basic commands:\n\n')
1344 else:
1310 else:
1345 header = _('list of commands:\n\n')
1311 header = _('list of commands:\n\n')
1346
1312
1347 helplist(header)
1313 helplist(header)
1348
1314
1349 # list all option lists
1315 # list all option lists
1350 opt_output = []
1316 opt_output = []
1351 for title, options in option_lists:
1317 for title, options in option_lists:
1352 opt_output.append(("\n%s" % title, None))
1318 opt_output.append(("\n%s" % title, None))
1353 for shortopt, longopt, default, desc in options:
1319 for shortopt, longopt, default, desc in options:
1354 if "DEPRECATED" in desc and not ui.verbose: continue
1320 if "DEPRECATED" in desc and not ui.verbose: continue
1355 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1321 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1356 longopt and " --%s" % longopt),
1322 longopt and " --%s" % longopt),
1357 "%s%s" % (desc,
1323 "%s%s" % (desc,
1358 default
1324 default
1359 and _(" (default: %s)") % default
1325 and _(" (default: %s)") % default
1360 or "")))
1326 or "")))
1361
1327
1362 if opt_output:
1328 if opt_output:
1363 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1329 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1364 for first, second in opt_output:
1330 for first, second in opt_output:
1365 if second:
1331 if second:
1366 ui.write(" %-*s %s\n" % (opts_len, first, second))
1332 ui.write(" %-*s %s\n" % (opts_len, first, second))
1367 else:
1333 else:
1368 ui.write("%s\n" % first)
1334 ui.write("%s\n" % first)
1369
1335
1370 def identify(ui, repo, source=None,
1336 def identify(ui, repo, source=None,
1371 rev=None, num=None, id=None, branch=None, tags=None):
1337 rev=None, num=None, id=None, branch=None, tags=None):
1372 """identify the working copy or specified revision
1338 """identify the working copy or specified revision
1373
1339
1374 With no revision, print a summary of the current state of the repo.
1340 With no revision, print a summary of the current state of the repo.
1375
1341
1376 With a path, do a lookup in another repository.
1342 With a path, do a lookup in another repository.
1377
1343
1378 This summary identifies the repository state using one or two parent
1344 This summary identifies the repository state using one or two parent
1379 hash identifiers, followed by a "+" if there are uncommitted changes
1345 hash identifiers, followed by a "+" if there are uncommitted changes
1380 in the working directory, a list of tags for this revision and a branch
1346 in the working directory, a list of tags for this revision and a branch
1381 name for non-default branches.
1347 name for non-default branches.
1382 """
1348 """
1383
1349
1384 if not repo and not source:
1350 if not repo and not source:
1385 raise util.Abort(_("There is no Mercurial repository here "
1351 raise util.Abort(_("There is no Mercurial repository here "
1386 "(.hg not found)"))
1352 "(.hg not found)"))
1387
1353
1388 hexfunc = ui.debugflag and hex or short
1354 hexfunc = ui.debugflag and hex or short
1389 default = not (num or id or branch or tags)
1355 default = not (num or id or branch or tags)
1390 output = []
1356 output = []
1391
1357
1392 if source:
1358 if source:
1393 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1359 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1394 srepo = hg.repository(ui, source)
1360 srepo = hg.repository(ui, source)
1395 if not rev and revs:
1361 if not rev and revs:
1396 rev = revs[0]
1362 rev = revs[0]
1397 if not rev:
1363 if not rev:
1398 rev = "tip"
1364 rev = "tip"
1399 if num or branch or tags:
1365 if num or branch or tags:
1400 raise util.Abort(
1366 raise util.Abort(
1401 "can't query remote revision number, branch, or tags")
1367 "can't query remote revision number, branch, or tags")
1402 output = [hexfunc(srepo.lookup(rev))]
1368 output = [hexfunc(srepo.lookup(rev))]
1403 elif not rev:
1369 elif not rev:
1404 ctx = repo.workingctx()
1370 ctx = repo.workingctx()
1405 parents = ctx.parents()
1371 parents = ctx.parents()
1406 changed = False
1372 changed = False
1407 if default or id or num:
1373 if default or id or num:
1408 changed = ctx.files() + ctx.deleted()
1374 changed = ctx.files() + ctx.deleted()
1409 if default or id:
1375 if default or id:
1410 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1376 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1411 (changed) and "+" or "")]
1377 (changed) and "+" or "")]
1412 if num:
1378 if num:
1413 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1379 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1414 (changed) and "+" or ""))
1380 (changed) and "+" or ""))
1415 else:
1381 else:
1416 ctx = repo.changectx(rev)
1382 ctx = repo.changectx(rev)
1417 if default or id:
1383 if default or id:
1418 output = [hexfunc(ctx.node())]
1384 output = [hexfunc(ctx.node())]
1419 if num:
1385 if num:
1420 output.append(str(ctx.rev()))
1386 output.append(str(ctx.rev()))
1421
1387
1422 if not source and default and not ui.quiet:
1388 if not source and default and not ui.quiet:
1423 b = util.tolocal(ctx.branch())
1389 b = util.tolocal(ctx.branch())
1424 if b != 'default':
1390 if b != 'default':
1425 output.append("(%s)" % b)
1391 output.append("(%s)" % b)
1426
1392
1427 # multiple tags for a single parent separated by '/'
1393 # multiple tags for a single parent separated by '/'
1428 t = "/".join(ctx.tags())
1394 t = "/".join(ctx.tags())
1429 if t:
1395 if t:
1430 output.append(t)
1396 output.append(t)
1431
1397
1432 if branch:
1398 if branch:
1433 output.append(util.tolocal(ctx.branch()))
1399 output.append(util.tolocal(ctx.branch()))
1434
1400
1435 if tags:
1401 if tags:
1436 output.extend(ctx.tags())
1402 output.extend(ctx.tags())
1437
1403
1438 ui.write("%s\n" % ' '.join(output))
1404 ui.write("%s\n" % ' '.join(output))
1439
1405
1440 def import_(ui, repo, patch1, *patches, **opts):
1406 def import_(ui, repo, patch1, *patches, **opts):
1441 """import an ordered set of patches
1407 """import an ordered set of patches
1442
1408
1443 Import a list of patches and commit them individually.
1409 Import a list of patches and commit them individually.
1444
1410
1445 If there are outstanding changes in the working directory, import
1411 If there are outstanding changes in the working directory, import
1446 will abort unless given the -f flag.
1412 will abort unless given the -f flag.
1447
1413
1448 You can import a patch straight from a mail message. Even patches
1414 You can import a patch straight from a mail message. Even patches
1449 as attachments work (body part must be type text/plain or
1415 as attachments work (body part must be type text/plain or
1450 text/x-patch to be used). From and Subject headers of email
1416 text/x-patch to be used). From and Subject headers of email
1451 message are used as default committer and commit message. All
1417 message are used as default committer and commit message. All
1452 text/plain body parts before first diff are added to commit
1418 text/plain body parts before first diff are added to commit
1453 message.
1419 message.
1454
1420
1455 If the imported patch was generated by hg export, user and description
1421 If the imported patch was generated by hg export, user and description
1456 from patch override values from message headers and body. Values
1422 from patch override values from message headers and body. Values
1457 given on command line with -m and -u override these.
1423 given on command line with -m and -u override these.
1458
1424
1459 If --exact is specified, import will set the working directory
1425 If --exact is specified, import will set the working directory
1460 to the parent of each patch before applying it, and will abort
1426 to the parent of each patch before applying it, and will abort
1461 if the resulting changeset has a different ID than the one
1427 if the resulting changeset has a different ID than the one
1462 recorded in the patch. This may happen due to character set
1428 recorded in the patch. This may happen due to character set
1463 problems or other deficiencies in the text patch format.
1429 problems or other deficiencies in the text patch format.
1464
1430
1465 To read a patch from standard input, use patch name "-".
1431 To read a patch from standard input, use patch name "-".
1466 """
1432 """
1467 patches = (patch1,) + patches
1433 patches = (patch1,) + patches
1468
1434
1469 if opts.get('exact') or not opts['force']:
1435 if opts.get('exact') or not opts['force']:
1470 cmdutil.bail_if_changed(repo)
1436 cmdutil.bail_if_changed(repo)
1471
1437
1472 d = opts["base"]
1438 d = opts["base"]
1473 strip = opts["strip"]
1439 strip = opts["strip"]
1474 wlock = lock = None
1440 wlock = lock = None
1475 try:
1441 try:
1476 wlock = repo.wlock()
1442 wlock = repo.wlock()
1477 lock = repo.lock()
1443 lock = repo.lock()
1478 for p in patches:
1444 for p in patches:
1479 pf = os.path.join(d, p)
1445 pf = os.path.join(d, p)
1480
1446
1481 if pf == '-':
1447 if pf == '-':
1482 ui.status(_("applying patch from stdin\n"))
1448 ui.status(_("applying patch from stdin\n"))
1483 data = patch.extract(ui, sys.stdin)
1449 data = patch.extract(ui, sys.stdin)
1484 else:
1450 else:
1485 ui.status(_("applying %s\n") % p)
1451 ui.status(_("applying %s\n") % p)
1486 if os.path.exists(pf):
1452 if os.path.exists(pf):
1487 data = patch.extract(ui, file(pf, 'rb'))
1453 data = patch.extract(ui, file(pf, 'rb'))
1488 else:
1454 else:
1489 data = patch.extract(ui, urllib.urlopen(pf))
1455 data = patch.extract(ui, urllib.urlopen(pf))
1490 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1456 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1491
1457
1492 if tmpname is None:
1458 if tmpname is None:
1493 raise util.Abort(_('no diffs found'))
1459 raise util.Abort(_('no diffs found'))
1494
1460
1495 try:
1461 try:
1496 cmdline_message = cmdutil.logmessage(opts)
1462 cmdline_message = cmdutil.logmessage(opts)
1497 if cmdline_message:
1463 if cmdline_message:
1498 # pickup the cmdline msg
1464 # pickup the cmdline msg
1499 message = cmdline_message
1465 message = cmdline_message
1500 elif message:
1466 elif message:
1501 # pickup the patch msg
1467 # pickup the patch msg
1502 message = message.strip()
1468 message = message.strip()
1503 else:
1469 else:
1504 # launch the editor
1470 # launch the editor
1505 message = None
1471 message = None
1506 ui.debug(_('message:\n%s\n') % message)
1472 ui.debug(_('message:\n%s\n') % message)
1507
1473
1508 wp = repo.workingctx().parents()
1474 wp = repo.workingctx().parents()
1509 if opts.get('exact'):
1475 if opts.get('exact'):
1510 if not nodeid or not p1:
1476 if not nodeid or not p1:
1511 raise util.Abort(_('not a mercurial patch'))
1477 raise util.Abort(_('not a mercurial patch'))
1512 p1 = repo.lookup(p1)
1478 p1 = repo.lookup(p1)
1513 p2 = repo.lookup(p2 or hex(nullid))
1479 p2 = repo.lookup(p2 or hex(nullid))
1514
1480
1515 if p1 != wp[0].node():
1481 if p1 != wp[0].node():
1516 hg.clean(repo, p1)
1482 hg.clean(repo, p1)
1517 repo.dirstate.setparents(p1, p2)
1483 repo.dirstate.setparents(p1, p2)
1518 elif p2:
1484 elif p2:
1519 try:
1485 try:
1520 p1 = repo.lookup(p1)
1486 p1 = repo.lookup(p1)
1521 p2 = repo.lookup(p2)
1487 p2 = repo.lookup(p2)
1522 if p1 == wp[0].node():
1488 if p1 == wp[0].node():
1523 repo.dirstate.setparents(p1, p2)
1489 repo.dirstate.setparents(p1, p2)
1524 except hg.RepoError:
1490 except hg.RepoError:
1525 pass
1491 pass
1526 if opts.get('exact') or opts.get('import_branch'):
1492 if opts.get('exact') or opts.get('import_branch'):
1527 repo.dirstate.setbranch(branch or 'default')
1493 repo.dirstate.setbranch(branch or 'default')
1528
1494
1529 files = {}
1495 files = {}
1530 try:
1496 try:
1531 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1497 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1532 files=files)
1498 files=files)
1533 finally:
1499 finally:
1534 files = patch.updatedir(ui, repo, files)
1500 files = patch.updatedir(ui, repo, files)
1535 if not opts.get('no_commit'):
1501 if not opts.get('no_commit'):
1536 n = repo.commit(files, message, opts.get('user') or user,
1502 n = repo.commit(files, message, opts.get('user') or user,
1537 opts.get('date') or date)
1503 opts.get('date') or date)
1538 if opts.get('exact'):
1504 if opts.get('exact'):
1539 if hex(n) != nodeid:
1505 if hex(n) != nodeid:
1540 repo.rollback()
1506 repo.rollback()
1541 raise util.Abort(_('patch is damaged'
1507 raise util.Abort(_('patch is damaged'
1542 ' or loses information'))
1508 ' or loses information'))
1543 # Force a dirstate write so that the next transaction
1509 # Force a dirstate write so that the next transaction
1544 # backups an up-do-date file.
1510 # backups an up-do-date file.
1545 repo.dirstate.write()
1511 repo.dirstate.write()
1546 finally:
1512 finally:
1547 os.unlink(tmpname)
1513 os.unlink(tmpname)
1548 finally:
1514 finally:
1549 del lock, wlock
1515 del lock, wlock
1550
1516
1551 def incoming(ui, repo, source="default", **opts):
1517 def incoming(ui, repo, source="default", **opts):
1552 """show new changesets found in source
1518 """show new changesets found in source
1553
1519
1554 Show new changesets found in the specified path/URL or the default
1520 Show new changesets found in the specified path/URL or the default
1555 pull location. These are the changesets that would be pulled if a pull
1521 pull location. These are the changesets that would be pulled if a pull
1556 was requested.
1522 was requested.
1557
1523
1558 For remote repository, using --bundle avoids downloading the changesets
1524 For remote repository, using --bundle avoids downloading the changesets
1559 twice if the incoming is followed by a pull.
1525 twice if the incoming is followed by a pull.
1560
1526
1561 See pull for valid source format details.
1527 See pull for valid source format details.
1562 """
1528 """
1563 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1529 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1564 cmdutil.setremoteconfig(ui, opts)
1530 cmdutil.setremoteconfig(ui, opts)
1565
1531
1566 other = hg.repository(ui, source)
1532 other = hg.repository(ui, source)
1567 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1533 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1568 if revs:
1534 if revs:
1569 revs = [other.lookup(rev) for rev in revs]
1535 revs = [other.lookup(rev) for rev in revs]
1570 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1536 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1571 if not incoming:
1537 if not incoming:
1572 try:
1538 try:
1573 os.unlink(opts["bundle"])
1539 os.unlink(opts["bundle"])
1574 except:
1540 except:
1575 pass
1541 pass
1576 ui.status(_("no changes found\n"))
1542 ui.status(_("no changes found\n"))
1577 return 1
1543 return 1
1578
1544
1579 cleanup = None
1545 cleanup = None
1580 try:
1546 try:
1581 fname = opts["bundle"]
1547 fname = opts["bundle"]
1582 if fname or not other.local():
1548 if fname or not other.local():
1583 # create a bundle (uncompressed if other repo is not local)
1549 # create a bundle (uncompressed if other repo is not local)
1584 if revs is None:
1550 if revs is None:
1585 cg = other.changegroup(incoming, "incoming")
1551 cg = other.changegroup(incoming, "incoming")
1586 else:
1552 else:
1587 cg = other.changegroupsubset(incoming, revs, 'incoming')
1553 cg = other.changegroupsubset(incoming, revs, 'incoming')
1588 bundletype = other.local() and "HG10BZ" or "HG10UN"
1554 bundletype = other.local() and "HG10BZ" or "HG10UN"
1589 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1555 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1590 # keep written bundle?
1556 # keep written bundle?
1591 if opts["bundle"]:
1557 if opts["bundle"]:
1592 cleanup = None
1558 cleanup = None
1593 if not other.local():
1559 if not other.local():
1594 # use the created uncompressed bundlerepo
1560 # use the created uncompressed bundlerepo
1595 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1561 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1596
1562
1597 o = other.changelog.nodesbetween(incoming, revs)[0]
1563 o = other.changelog.nodesbetween(incoming, revs)[0]
1598 if opts['newest_first']:
1564 if opts['newest_first']:
1599 o.reverse()
1565 o.reverse()
1600 displayer = cmdutil.show_changeset(ui, other, opts)
1566 displayer = cmdutil.show_changeset(ui, other, opts)
1601 for n in o:
1567 for n in o:
1602 parents = [p for p in other.changelog.parents(n) if p != nullid]
1568 parents = [p for p in other.changelog.parents(n) if p != nullid]
1603 if opts['no_merges'] and len(parents) == 2:
1569 if opts['no_merges'] and len(parents) == 2:
1604 continue
1570 continue
1605 displayer.show(changenode=n)
1571 displayer.show(changenode=n)
1606 finally:
1572 finally:
1607 if hasattr(other, 'close'):
1573 if hasattr(other, 'close'):
1608 other.close()
1574 other.close()
1609 if cleanup:
1575 if cleanup:
1610 os.unlink(cleanup)
1576 os.unlink(cleanup)
1611
1577
1612 def init(ui, dest=".", **opts):
1578 def init(ui, dest=".", **opts):
1613 """create a new repository in the given directory
1579 """create a new repository in the given directory
1614
1580
1615 Initialize a new repository in the given directory. If the given
1581 Initialize a new repository in the given directory. If the given
1616 directory does not exist, it is created.
1582 directory does not exist, it is created.
1617
1583
1618 If no directory is given, the current directory is used.
1584 If no directory is given, the current directory is used.
1619
1585
1620 It is possible to specify an ssh:// URL as the destination.
1586 It is possible to specify an ssh:// URL as the destination.
1621 Look at the help text for the pull command for important details
1587 Look at the help text for the pull command for important details
1622 about ssh:// URLs.
1588 about ssh:// URLs.
1623 """
1589 """
1624 cmdutil.setremoteconfig(ui, opts)
1590 cmdutil.setremoteconfig(ui, opts)
1625 hg.repository(ui, dest, create=1)
1591 hg.repository(ui, dest, create=1)
1626
1592
1627 def locate(ui, repo, *pats, **opts):
1593 def locate(ui, repo, *pats, **opts):
1628 """locate files matching specific patterns
1594 """locate files matching specific patterns
1629
1595
1630 Print all files under Mercurial control whose names match the
1596 Print all files under Mercurial control whose names match the
1631 given patterns.
1597 given patterns.
1632
1598
1633 This command searches the entire repository by default. To search
1599 This command searches the entire repository by default. To search
1634 just the current directory and its subdirectories, use
1600 just the current directory and its subdirectories, use
1635 "--include .".
1601 "--include .".
1636
1602
1637 If no patterns are given to match, this command prints all file
1603 If no patterns are given to match, this command prints all file
1638 names.
1604 names.
1639
1605
1640 If you want to feed the output of this command into the "xargs"
1606 If you want to feed the output of this command into the "xargs"
1641 command, use the "-0" option to both this command and "xargs".
1607 command, use the "-0" option to both this command and "xargs".
1642 This will avoid the problem of "xargs" treating single filenames
1608 This will avoid the problem of "xargs" treating single filenames
1643 that contain white space as multiple filenames.
1609 that contain white space as multiple filenames.
1644 """
1610 """
1645 end = opts['print0'] and '\0' or '\n'
1611 end = opts['print0'] and '\0' or '\n'
1646 rev = opts['rev']
1612 rev = opts['rev']
1647 if rev:
1613 if rev:
1648 node = repo.lookup(rev)
1614 node = repo.lookup(rev)
1649 else:
1615 else:
1650 node = None
1616 node = None
1651
1617
1652 ret = 1
1618 ret = 1
1653 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1619 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1654 badmatch=util.always,
1620 badmatch=util.always,
1655 default='relglob'):
1621 default='relglob'):
1656 if src == 'b':
1622 if src == 'b':
1657 continue
1623 continue
1658 if not node and abs not in repo.dirstate:
1624 if not node and abs not in repo.dirstate:
1659 continue
1625 continue
1660 if opts['fullpath']:
1626 if opts['fullpath']:
1661 ui.write(os.path.join(repo.root, abs), end)
1627 ui.write(os.path.join(repo.root, abs), end)
1662 else:
1628 else:
1663 ui.write(((pats and rel) or abs), end)
1629 ui.write(((pats and rel) or abs), end)
1664 ret = 0
1630 ret = 0
1665
1631
1666 return ret
1632 return ret
1667
1633
1668 def log(ui, repo, *pats, **opts):
1634 def log(ui, repo, *pats, **opts):
1669 """show revision history of entire repository or files
1635 """show revision history of entire repository or files
1670
1636
1671 Print the revision history of the specified files or the entire
1637 Print the revision history of the specified files or the entire
1672 project.
1638 project.
1673
1639
1674 File history is shown without following rename or copy history of
1640 File history is shown without following rename or copy history of
1675 files. Use -f/--follow with a file name to follow history across
1641 files. Use -f/--follow with a file name to follow history across
1676 renames and copies. --follow without a file name will only show
1642 renames and copies. --follow without a file name will only show
1677 ancestors or descendants of the starting revision. --follow-first
1643 ancestors or descendants of the starting revision. --follow-first
1678 only follows the first parent of merge revisions.
1644 only follows the first parent of merge revisions.
1679
1645
1680 If no revision range is specified, the default is tip:0 unless
1646 If no revision range is specified, the default is tip:0 unless
1681 --follow is set, in which case the working directory parent is
1647 --follow is set, in which case the working directory parent is
1682 used as the starting revision.
1648 used as the starting revision.
1683
1649
1684 By default this command outputs: changeset id and hash, tags,
1650 By default this command outputs: changeset id and hash, tags,
1685 non-trivial parents, user, date and time, and a summary for each
1651 non-trivial parents, user, date and time, and a summary for each
1686 commit. When the -v/--verbose switch is used, the list of changed
1652 commit. When the -v/--verbose switch is used, the list of changed
1687 files and full commit message is shown.
1653 files and full commit message is shown.
1688
1654
1689 NOTE: log -p may generate unexpected diff output for merge
1655 NOTE: log -p may generate unexpected diff output for merge
1690 changesets, as it will compare the merge changeset against its
1656 changesets, as it will compare the merge changeset against its
1691 first parent only. Also, the files: list will only reflect files
1657 first parent only. Also, the files: list will only reflect files
1692 that are different from BOTH parents.
1658 that are different from BOTH parents.
1693
1659
1694 """
1660 """
1695
1661
1696 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1662 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1697 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1663 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1698
1664
1699 if opts['limit']:
1665 if opts['limit']:
1700 try:
1666 try:
1701 limit = int(opts['limit'])
1667 limit = int(opts['limit'])
1702 except ValueError:
1668 except ValueError:
1703 raise util.Abort(_('limit must be a positive integer'))
1669 raise util.Abort(_('limit must be a positive integer'))
1704 if limit <= 0: raise util.Abort(_('limit must be positive'))
1670 if limit <= 0: raise util.Abort(_('limit must be positive'))
1705 else:
1671 else:
1706 limit = sys.maxint
1672 limit = sys.maxint
1707 count = 0
1673 count = 0
1708
1674
1709 if opts['copies'] and opts['rev']:
1675 if opts['copies'] and opts['rev']:
1710 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1676 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1711 else:
1677 else:
1712 endrev = repo.changelog.count()
1678 endrev = repo.changelog.count()
1713 rcache = {}
1679 rcache = {}
1714 ncache = {}
1680 ncache = {}
1715 def getrenamed(fn, rev):
1681 def getrenamed(fn, rev):
1716 '''looks up all renames for a file (up to endrev) the first
1682 '''looks up all renames for a file (up to endrev) the first
1717 time the file is given. It indexes on the changerev and only
1683 time the file is given. It indexes on the changerev and only
1718 parses the manifest if linkrev != changerev.
1684 parses the manifest if linkrev != changerev.
1719 Returns rename info for fn at changerev rev.'''
1685 Returns rename info for fn at changerev rev.'''
1720 if fn not in rcache:
1686 if fn not in rcache:
1721 rcache[fn] = {}
1687 rcache[fn] = {}
1722 ncache[fn] = {}
1688 ncache[fn] = {}
1723 fl = repo.file(fn)
1689 fl = repo.file(fn)
1724 for i in xrange(fl.count()):
1690 for i in xrange(fl.count()):
1725 node = fl.node(i)
1691 node = fl.node(i)
1726 lr = fl.linkrev(node)
1692 lr = fl.linkrev(node)
1727 renamed = fl.renamed(node)
1693 renamed = fl.renamed(node)
1728 rcache[fn][lr] = renamed
1694 rcache[fn][lr] = renamed
1729 if renamed:
1695 if renamed:
1730 ncache[fn][node] = renamed
1696 ncache[fn][node] = renamed
1731 if lr >= endrev:
1697 if lr >= endrev:
1732 break
1698 break
1733 if rev in rcache[fn]:
1699 if rev in rcache[fn]:
1734 return rcache[fn][rev]
1700 return rcache[fn][rev]
1735
1701
1736 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1702 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1737 # filectx logic.
1703 # filectx logic.
1738
1704
1739 try:
1705 try:
1740 return repo.changectx(rev).filectx(fn).renamed()
1706 return repo.changectx(rev).filectx(fn).renamed()
1741 except revlog.LookupError:
1707 except revlog.LookupError:
1742 pass
1708 pass
1743 return None
1709 return None
1744
1710
1745 df = False
1711 df = False
1746 if opts["date"]:
1712 if opts["date"]:
1747 df = util.matchdate(opts["date"])
1713 df = util.matchdate(opts["date"])
1748
1714
1749 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1715 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1750 for st, rev, fns in changeiter:
1716 for st, rev, fns in changeiter:
1751 if st == 'add':
1717 if st == 'add':
1752 changenode = repo.changelog.node(rev)
1718 changenode = repo.changelog.node(rev)
1753 parents = [p for p in repo.changelog.parentrevs(rev)
1719 parents = [p for p in repo.changelog.parentrevs(rev)
1754 if p != nullrev]
1720 if p != nullrev]
1755 if opts['no_merges'] and len(parents) == 2:
1721 if opts['no_merges'] and len(parents) == 2:
1756 continue
1722 continue
1757 if opts['only_merges'] and len(parents) != 2:
1723 if opts['only_merges'] and len(parents) != 2:
1758 continue
1724 continue
1759
1725
1760 if df:
1726 if df:
1761 changes = get(rev)
1727 changes = get(rev)
1762 if not df(changes[2][0]):
1728 if not df(changes[2][0]):
1763 continue
1729 continue
1764
1730
1765 if opts['keyword']:
1731 if opts['keyword']:
1766 changes = get(rev)
1732 changes = get(rev)
1767 miss = 0
1733 miss = 0
1768 for k in [kw.lower() for kw in opts['keyword']]:
1734 for k in [kw.lower() for kw in opts['keyword']]:
1769 if not (k in changes[1].lower() or
1735 if not (k in changes[1].lower() or
1770 k in changes[4].lower() or
1736 k in changes[4].lower() or
1771 k in " ".join(changes[3]).lower()):
1737 k in " ".join(changes[3]).lower()):
1772 miss = 1
1738 miss = 1
1773 break
1739 break
1774 if miss:
1740 if miss:
1775 continue
1741 continue
1776
1742
1777 copies = []
1743 copies = []
1778 if opts.get('copies') and rev:
1744 if opts.get('copies') and rev:
1779 for fn in get(rev)[3]:
1745 for fn in get(rev)[3]:
1780 rename = getrenamed(fn, rev)
1746 rename = getrenamed(fn, rev)
1781 if rename:
1747 if rename:
1782 copies.append((fn, rename[0]))
1748 copies.append((fn, rename[0]))
1783 displayer.show(rev, changenode, copies=copies)
1749 displayer.show(rev, changenode, copies=copies)
1784 elif st == 'iter':
1750 elif st == 'iter':
1785 if count == limit: break
1751 if count == limit: break
1786 if displayer.flush(rev):
1752 if displayer.flush(rev):
1787 count += 1
1753 count += 1
1788
1754
1789 def manifest(ui, repo, node=None, rev=None):
1755 def manifest(ui, repo, node=None, rev=None):
1790 """output the current or given revision of the project manifest
1756 """output the current or given revision of the project manifest
1791
1757
1792 Print a list of version controlled files for the given revision.
1758 Print a list of version controlled files for the given revision.
1793 If no revision is given, the parent of the working directory is used,
1759 If no revision is given, the parent of the working directory is used,
1794 or tip if no revision is checked out.
1760 or tip if no revision is checked out.
1795
1761
1796 The manifest is the list of files being version controlled. If no revision
1762 The manifest is the list of files being version controlled. If no revision
1797 is given then the first parent of the working directory is used.
1763 is given then the first parent of the working directory is used.
1798
1764
1799 With -v flag, print file permissions, symlink and executable bits. With
1765 With -v flag, print file permissions, symlink and executable bits. With
1800 --debug flag, print file revision hashes.
1766 --debug flag, print file revision hashes.
1801 """
1767 """
1802
1768
1803 if rev and node:
1769 if rev and node:
1804 raise util.Abort(_("please specify just one revision"))
1770 raise util.Abort(_("please specify just one revision"))
1805
1771
1806 if not node:
1772 if not node:
1807 node = rev
1773 node = rev
1808
1774
1809 m = repo.changectx(node).manifest()
1775 m = repo.changectx(node).manifest()
1810 files = m.keys()
1776 files = m.keys()
1811 files.sort()
1777 files.sort()
1812
1778
1813 for f in files:
1779 for f in files:
1814 if ui.debugflag:
1780 if ui.debugflag:
1815 ui.write("%40s " % hex(m[f]))
1781 ui.write("%40s " % hex(m[f]))
1816 if ui.verbose:
1782 if ui.verbose:
1817 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1783 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1818 perm = m.execf(f) and "755" or "644"
1784 perm = m.execf(f) and "755" or "644"
1819 ui.write("%3s %1s " % (perm, type))
1785 ui.write("%3s %1s " % (perm, type))
1820 ui.write("%s\n" % f)
1786 ui.write("%s\n" % f)
1821
1787
1822 def merge(ui, repo, node=None, force=None, rev=None):
1788 def merge(ui, repo, node=None, force=None, rev=None):
1823 """merge working directory with another revision
1789 """merge working directory with another revision
1824
1790
1825 Merge the contents of the current working directory and the
1791 Merge the contents of the current working directory and the
1826 requested revision. Files that changed between either parent are
1792 requested revision. Files that changed between either parent are
1827 marked as changed for the next commit and a commit must be
1793 marked as changed for the next commit and a commit must be
1828 performed before any further updates are allowed.
1794 performed before any further updates are allowed.
1829
1795
1830 If no revision is specified, the working directory's parent is a
1796 If no revision is specified, the working directory's parent is a
1831 head revision, and the repository contains exactly one other head,
1797 head revision, and the repository contains exactly one other head,
1832 the other head is merged with by default. Otherwise, an explicit
1798 the other head is merged with by default. Otherwise, an explicit
1833 revision to merge with must be provided.
1799 revision to merge with must be provided.
1834 """
1800 """
1835
1801
1836 if rev and node:
1802 if rev and node:
1837 raise util.Abort(_("please specify just one revision"))
1803 raise util.Abort(_("please specify just one revision"))
1838 if not node:
1804 if not node:
1839 node = rev
1805 node = rev
1840
1806
1841 if not node:
1807 if not node:
1842 heads = repo.heads()
1808 heads = repo.heads()
1843 if len(heads) > 2:
1809 if len(heads) > 2:
1844 raise util.Abort(_('repo has %d heads - '
1810 raise util.Abort(_('repo has %d heads - '
1845 'please merge with an explicit rev') %
1811 'please merge with an explicit rev') %
1846 len(heads))
1812 len(heads))
1847 parent = repo.dirstate.parents()[0]
1813 parent = repo.dirstate.parents()[0]
1848 if len(heads) == 1:
1814 if len(heads) == 1:
1849 msg = _('there is nothing to merge')
1815 msg = _('there is nothing to merge')
1850 if parent != repo.lookup(repo.workingctx().branch()):
1816 if parent != repo.lookup(repo.workingctx().branch()):
1851 msg = _('%s - use "hg update" instead') % msg
1817 msg = _('%s - use "hg update" instead') % msg
1852 raise util.Abort(msg)
1818 raise util.Abort(msg)
1853
1819
1854 if parent not in heads:
1820 if parent not in heads:
1855 raise util.Abort(_('working dir not at a head rev - '
1821 raise util.Abort(_('working dir not at a head rev - '
1856 'use "hg update" or merge with an explicit rev'))
1822 'use "hg update" or merge with an explicit rev'))
1857 node = parent == heads[0] and heads[-1] or heads[0]
1823 node = parent == heads[0] and heads[-1] or heads[0]
1858 return hg.merge(repo, node, force=force)
1824 return hg.merge(repo, node, force=force)
1859
1825
1860 def outgoing(ui, repo, dest=None, **opts):
1826 def outgoing(ui, repo, dest=None, **opts):
1861 """show changesets not found in destination
1827 """show changesets not found in destination
1862
1828
1863 Show changesets not found in the specified destination repository or
1829 Show changesets not found in the specified destination repository or
1864 the default push location. These are the changesets that would be pushed
1830 the default push location. These are the changesets that would be pushed
1865 if a push was requested.
1831 if a push was requested.
1866
1832
1867 See pull for valid destination format details.
1833 See pull for valid destination format details.
1868 """
1834 """
1869 dest, revs, checkout = hg.parseurl(
1835 dest, revs, checkout = hg.parseurl(
1870 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1836 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1871 cmdutil.setremoteconfig(ui, opts)
1837 cmdutil.setremoteconfig(ui, opts)
1872 if revs:
1838 if revs:
1873 revs = [repo.lookup(rev) for rev in revs]
1839 revs = [repo.lookup(rev) for rev in revs]
1874
1840
1875 other = hg.repository(ui, dest)
1841 other = hg.repository(ui, dest)
1876 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1842 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1877 o = repo.findoutgoing(other, force=opts['force'])
1843 o = repo.findoutgoing(other, force=opts['force'])
1878 if not o:
1844 if not o:
1879 ui.status(_("no changes found\n"))
1845 ui.status(_("no changes found\n"))
1880 return 1
1846 return 1
1881 o = repo.changelog.nodesbetween(o, revs)[0]
1847 o = repo.changelog.nodesbetween(o, revs)[0]
1882 if opts['newest_first']:
1848 if opts['newest_first']:
1883 o.reverse()
1849 o.reverse()
1884 displayer = cmdutil.show_changeset(ui, repo, opts)
1850 displayer = cmdutil.show_changeset(ui, repo, opts)
1885 for n in o:
1851 for n in o:
1886 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1852 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1887 if opts['no_merges'] and len(parents) == 2:
1853 if opts['no_merges'] and len(parents) == 2:
1888 continue
1854 continue
1889 displayer.show(changenode=n)
1855 displayer.show(changenode=n)
1890
1856
1891 def parents(ui, repo, file_=None, **opts):
1857 def parents(ui, repo, file_=None, **opts):
1892 """show the parents of the working dir or revision
1858 """show the parents of the working dir or revision
1893
1859
1894 Print the working directory's parent revisions. If a
1860 Print the working directory's parent revisions. If a
1895 revision is given via --rev, the parent of that revision
1861 revision is given via --rev, the parent of that revision
1896 will be printed. If a file argument is given, revision in
1862 will be printed. If a file argument is given, revision in
1897 which the file was last changed (before the working directory
1863 which the file was last changed (before the working directory
1898 revision or the argument to --rev if given) is printed.
1864 revision or the argument to --rev if given) is printed.
1899 """
1865 """
1900 rev = opts.get('rev')
1866 rev = opts.get('rev')
1901 if rev:
1867 if rev:
1902 ctx = repo.changectx(rev)
1868 ctx = repo.changectx(rev)
1903 else:
1869 else:
1904 ctx = repo.workingctx()
1870 ctx = repo.workingctx()
1905
1871
1906 if file_:
1872 if file_:
1907 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
1873 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
1908 if anypats or len(files) != 1:
1874 if anypats or len(files) != 1:
1909 raise util.Abort(_('can only specify an explicit file name'))
1875 raise util.Abort(_('can only specify an explicit file name'))
1910 file_ = files[0]
1876 file_ = files[0]
1911 filenodes = []
1877 filenodes = []
1912 for cp in ctx.parents():
1878 for cp in ctx.parents():
1913 if not cp:
1879 if not cp:
1914 continue
1880 continue
1915 try:
1881 try:
1916 filenodes.append(cp.filenode(file_))
1882 filenodes.append(cp.filenode(file_))
1917 except revlog.LookupError:
1883 except revlog.LookupError:
1918 pass
1884 pass
1919 if not filenodes:
1885 if not filenodes:
1920 raise util.Abort(_("'%s' not found in manifest!") % file_)
1886 raise util.Abort(_("'%s' not found in manifest!") % file_)
1921 fl = repo.file(file_)
1887 fl = repo.file(file_)
1922 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
1888 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
1923 else:
1889 else:
1924 p = [cp.node() for cp in ctx.parents()]
1890 p = [cp.node() for cp in ctx.parents()]
1925
1891
1926 displayer = cmdutil.show_changeset(ui, repo, opts)
1892 displayer = cmdutil.show_changeset(ui, repo, opts)
1927 for n in p:
1893 for n in p:
1928 if n != nullid:
1894 if n != nullid:
1929 displayer.show(changenode=n)
1895 displayer.show(changenode=n)
1930
1896
1931 def paths(ui, repo, search=None):
1897 def paths(ui, repo, search=None):
1932 """show definition of symbolic path names
1898 """show definition of symbolic path names
1933
1899
1934 Show definition of symbolic path name NAME. If no name is given, show
1900 Show definition of symbolic path name NAME. If no name is given, show
1935 definition of available names.
1901 definition of available names.
1936
1902
1937 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1903 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1938 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1904 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1939 """
1905 """
1940 if search:
1906 if search:
1941 for name, path in ui.configitems("paths"):
1907 for name, path in ui.configitems("paths"):
1942 if name == search:
1908 if name == search:
1943 ui.write("%s\n" % path)
1909 ui.write("%s\n" % path)
1944 return
1910 return
1945 ui.warn(_("not found!\n"))
1911 ui.warn(_("not found!\n"))
1946 return 1
1912 return 1
1947 else:
1913 else:
1948 for name, path in ui.configitems("paths"):
1914 for name, path in ui.configitems("paths"):
1949 ui.write("%s = %s\n" % (name, path))
1915 ui.write("%s = %s\n" % (name, path))
1950
1916
1951 def postincoming(ui, repo, modheads, optupdate, checkout):
1917 def postincoming(ui, repo, modheads, optupdate, checkout):
1952 if modheads == 0:
1918 if modheads == 0:
1953 return
1919 return
1954 if optupdate:
1920 if optupdate:
1955 if modheads <= 1 or checkout:
1921 if modheads <= 1 or checkout:
1956 return hg.update(repo, checkout)
1922 return hg.update(repo, checkout)
1957 else:
1923 else:
1958 ui.status(_("not updating, since new heads added\n"))
1924 ui.status(_("not updating, since new heads added\n"))
1959 if modheads > 1:
1925 if modheads > 1:
1960 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1926 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1961 else:
1927 else:
1962 ui.status(_("(run 'hg update' to get a working copy)\n"))
1928 ui.status(_("(run 'hg update' to get a working copy)\n"))
1963
1929
1964 def pull(ui, repo, source="default", **opts):
1930 def pull(ui, repo, source="default", **opts):
1965 """pull changes from the specified source
1931 """pull changes from the specified source
1966
1932
1967 Pull changes from a remote repository to a local one.
1933 Pull changes from a remote repository to a local one.
1968
1934
1969 This finds all changes from the repository at the specified path
1935 This finds all changes from the repository at the specified path
1970 or URL and adds them to the local repository. By default, this
1936 or URL and adds them to the local repository. By default, this
1971 does not update the copy of the project in the working directory.
1937 does not update the copy of the project in the working directory.
1972
1938
1973 Valid URLs are of the form:
1939 Valid URLs are of the form:
1974
1940
1975 local/filesystem/path (or file://local/filesystem/path)
1941 local/filesystem/path (or file://local/filesystem/path)
1976 http://[user@]host[:port]/[path]
1942 http://[user@]host[:port]/[path]
1977 https://[user@]host[:port]/[path]
1943 https://[user@]host[:port]/[path]
1978 ssh://[user@]host[:port]/[path]
1944 ssh://[user@]host[:port]/[path]
1979 static-http://host[:port]/[path]
1945 static-http://host[:port]/[path]
1980
1946
1981 Paths in the local filesystem can either point to Mercurial
1947 Paths in the local filesystem can either point to Mercurial
1982 repositories or to bundle files (as created by 'hg bundle' or
1948 repositories or to bundle files (as created by 'hg bundle' or
1983 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1949 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1984 allows access to a Mercurial repository where you simply use a web
1950 allows access to a Mercurial repository where you simply use a web
1985 server to publish the .hg directory as static content.
1951 server to publish the .hg directory as static content.
1986
1952
1987 An optional identifier after # indicates a particular branch, tag,
1953 An optional identifier after # indicates a particular branch, tag,
1988 or changeset to pull.
1954 or changeset to pull.
1989
1955
1990 Some notes about using SSH with Mercurial:
1956 Some notes about using SSH with Mercurial:
1991 - SSH requires an accessible shell account on the destination machine
1957 - SSH requires an accessible shell account on the destination machine
1992 and a copy of hg in the remote path or specified with as remotecmd.
1958 and a copy of hg in the remote path or specified with as remotecmd.
1993 - path is relative to the remote user's home directory by default.
1959 - path is relative to the remote user's home directory by default.
1994 Use an extra slash at the start of a path to specify an absolute path:
1960 Use an extra slash at the start of a path to specify an absolute path:
1995 ssh://example.com//tmp/repository
1961 ssh://example.com//tmp/repository
1996 - Mercurial doesn't use its own compression via SSH; the right thing
1962 - Mercurial doesn't use its own compression via SSH; the right thing
1997 to do is to configure it in your ~/.ssh/config, e.g.:
1963 to do is to configure it in your ~/.ssh/config, e.g.:
1998 Host *.mylocalnetwork.example.com
1964 Host *.mylocalnetwork.example.com
1999 Compression no
1965 Compression no
2000 Host *
1966 Host *
2001 Compression yes
1967 Compression yes
2002 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1968 Alternatively specify "ssh -C" as your ssh command in your hgrc or
2003 with the --ssh command line option.
1969 with the --ssh command line option.
2004 """
1970 """
2005 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1971 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
2006 cmdutil.setremoteconfig(ui, opts)
1972 cmdutil.setremoteconfig(ui, opts)
2007
1973
2008 other = hg.repository(ui, source)
1974 other = hg.repository(ui, source)
2009 ui.status(_('pulling from %s\n') % util.hidepassword(source))
1975 ui.status(_('pulling from %s\n') % util.hidepassword(source))
2010 if revs:
1976 if revs:
2011 try:
1977 try:
2012 revs = [other.lookup(rev) for rev in revs]
1978 revs = [other.lookup(rev) for rev in revs]
2013 except repo.NoCapability:
1979 except repo.NoCapability:
2014 error = _("Other repository doesn't support revision lookup, "
1980 error = _("Other repository doesn't support revision lookup, "
2015 "so a rev cannot be specified.")
1981 "so a rev cannot be specified.")
2016 raise util.Abort(error)
1982 raise util.Abort(error)
2017
1983
2018 modheads = repo.pull(other, heads=revs, force=opts['force'])
1984 modheads = repo.pull(other, heads=revs, force=opts['force'])
2019 return postincoming(ui, repo, modheads, opts['update'], checkout)
1985 return postincoming(ui, repo, modheads, opts['update'], checkout)
2020
1986
2021 def push(ui, repo, dest=None, **opts):
1987 def push(ui, repo, dest=None, **opts):
2022 """push changes to the specified destination
1988 """push changes to the specified destination
2023
1989
2024 Push changes from the local repository to the given destination.
1990 Push changes from the local repository to the given destination.
2025
1991
2026 This is the symmetrical operation for pull. It helps to move
1992 This is the symmetrical operation for pull. It helps to move
2027 changes from the current repository to a different one. If the
1993 changes from the current repository to a different one. If the
2028 destination is local this is identical to a pull in that directory
1994 destination is local this is identical to a pull in that directory
2029 from the current one.
1995 from the current one.
2030
1996
2031 By default, push will refuse to run if it detects the result would
1997 By default, push will refuse to run if it detects the result would
2032 increase the number of remote heads. This generally indicates the
1998 increase the number of remote heads. This generally indicates the
2033 the client has forgotten to sync and merge before pushing.
1999 the client has forgotten to sync and merge before pushing.
2034
2000
2035 Valid URLs are of the form:
2001 Valid URLs are of the form:
2036
2002
2037 local/filesystem/path (or file://local/filesystem/path)
2003 local/filesystem/path (or file://local/filesystem/path)
2038 ssh://[user@]host[:port]/[path]
2004 ssh://[user@]host[:port]/[path]
2039 http://[user@]host[:port]/[path]
2005 http://[user@]host[:port]/[path]
2040 https://[user@]host[:port]/[path]
2006 https://[user@]host[:port]/[path]
2041
2007
2042 An optional identifier after # indicates a particular branch, tag,
2008 An optional identifier after # indicates a particular branch, tag,
2043 or changeset to push.
2009 or changeset to push.
2044
2010
2045 Look at the help text for the pull command for important details
2011 Look at the help text for the pull command for important details
2046 about ssh:// URLs.
2012 about ssh:// URLs.
2047
2013
2048 Pushing to http:// and https:// URLs is only possible, if this
2014 Pushing to http:// and https:// URLs is only possible, if this
2049 feature is explicitly enabled on the remote Mercurial server.
2015 feature is explicitly enabled on the remote Mercurial server.
2050 """
2016 """
2051 dest, revs, checkout = hg.parseurl(
2017 dest, revs, checkout = hg.parseurl(
2052 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2018 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2053 cmdutil.setremoteconfig(ui, opts)
2019 cmdutil.setremoteconfig(ui, opts)
2054
2020
2055 other = hg.repository(ui, dest)
2021 other = hg.repository(ui, dest)
2056 ui.status('pushing to %s\n' % util.hidepassword(dest))
2022 ui.status('pushing to %s\n' % util.hidepassword(dest))
2057 if revs:
2023 if revs:
2058 revs = [repo.lookup(rev) for rev in revs]
2024 revs = [repo.lookup(rev) for rev in revs]
2059 r = repo.push(other, opts['force'], revs=revs)
2025 r = repo.push(other, opts['force'], revs=revs)
2060 return r == 0
2026 return r == 0
2061
2027
2062 def rawcommit(ui, repo, *pats, **opts):
2028 def rawcommit(ui, repo, *pats, **opts):
2063 """raw commit interface (DEPRECATED)
2029 """raw commit interface (DEPRECATED)
2064
2030
2065 (DEPRECATED)
2031 (DEPRECATED)
2066 Lowlevel commit, for use in helper scripts.
2032 Lowlevel commit, for use in helper scripts.
2067
2033
2068 This command is not intended to be used by normal users, as it is
2034 This command is not intended to be used by normal users, as it is
2069 primarily useful for importing from other SCMs.
2035 primarily useful for importing from other SCMs.
2070
2036
2071 This command is now deprecated and will be removed in a future
2037 This command is now deprecated and will be removed in a future
2072 release, please use debugsetparents and commit instead.
2038 release, please use debugsetparents and commit instead.
2073 """
2039 """
2074
2040
2075 ui.warn(_("(the rawcommit command is deprecated)\n"))
2041 ui.warn(_("(the rawcommit command is deprecated)\n"))
2076
2042
2077 message = cmdutil.logmessage(opts)
2043 message = cmdutil.logmessage(opts)
2078
2044
2079 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2045 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2080 if opts['files']:
2046 if opts['files']:
2081 files += open(opts['files']).read().splitlines()
2047 files += open(opts['files']).read().splitlines()
2082
2048
2083 parents = [repo.lookup(p) for p in opts['parent']]
2049 parents = [repo.lookup(p) for p in opts['parent']]
2084
2050
2085 try:
2051 try:
2086 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2052 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2087 except ValueError, inst:
2053 except ValueError, inst:
2088 raise util.Abort(str(inst))
2054 raise util.Abort(str(inst))
2089
2055
2090 def recover(ui, repo):
2056 def recover(ui, repo):
2091 """roll back an interrupted transaction
2057 """roll back an interrupted transaction
2092
2058
2093 Recover from an interrupted commit or pull.
2059 Recover from an interrupted commit or pull.
2094
2060
2095 This command tries to fix the repository status after an interrupted
2061 This command tries to fix the repository status after an interrupted
2096 operation. It should only be necessary when Mercurial suggests it.
2062 operation. It should only be necessary when Mercurial suggests it.
2097 """
2063 """
2098 if repo.recover():
2064 if repo.recover():
2099 return hg.verify(repo)
2065 return hg.verify(repo)
2100 return 1
2066 return 1
2101
2067
2102 def remove(ui, repo, *pats, **opts):
2068 def remove(ui, repo, *pats, **opts):
2103 """remove the specified files on the next commit
2069 """remove the specified files on the next commit
2104
2070
2105 Schedule the indicated files for removal from the repository.
2071 Schedule the indicated files for removal from the repository.
2106
2072
2107 This only removes files from the current branch, not from the
2073 This only removes files from the current branch, not from the
2108 entire project history. If the files still exist in the working
2074 entire project history. If the files still exist in the working
2109 directory, they will be deleted from it. If invoked with --after,
2075 directory, they will be deleted from it. If invoked with --after,
2110 files are marked as removed, but not actually unlinked unless --force
2076 files are marked as removed, but not actually unlinked unless --force
2111 is also given. Without exact file names, --after will only mark
2077 is also given. Without exact file names, --after will only mark
2112 files as removed if they are no longer in the working directory.
2078 files as removed if they are no longer in the working directory.
2113
2079
2114 This command schedules the files to be removed at the next commit.
2080 This command schedules the files to be removed at the next commit.
2115 To undo a remove before that, see hg revert.
2081 To undo a remove before that, see hg revert.
2116
2082
2117 Modified files and added files are not removed by default. To
2083 Modified files and added files are not removed by default. To
2118 remove them, use the -f/--force option.
2084 remove them, use the -f/--force option.
2119 """
2085 """
2120 if not opts['after'] and not pats:
2086 if not opts['after'] and not pats:
2121 raise util.Abort(_('no files specified'))
2087 raise util.Abort(_('no files specified'))
2122 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2088 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2123 exact = dict.fromkeys(files)
2089 exact = dict.fromkeys(files)
2124 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2090 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2125 modified, added, removed, deleted, unknown = mardu
2091 modified, added, removed, deleted, unknown = mardu
2126 remove, forget = [], []
2092 remove, forget = [], []
2127 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2093 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2128 reason = None
2094 reason = None
2129 if abs in modified and not opts['force']:
2095 if abs in modified and not opts['force']:
2130 reason = _('is modified (use -f to force removal)')
2096 reason = _('is modified (use -f to force removal)')
2131 elif abs in added:
2097 elif abs in added:
2132 if opts['force']:
2098 if opts['force']:
2133 forget.append(abs)
2099 forget.append(abs)
2134 continue
2100 continue
2135 reason = _('has been marked for add (use -f to force removal)')
2101 reason = _('has been marked for add (use -f to force removal)')
2136 exact = 1 # force the message
2102 exact = 1 # force the message
2137 elif abs not in repo.dirstate:
2103 elif abs not in repo.dirstate:
2138 reason = _('is not managed')
2104 reason = _('is not managed')
2139 elif opts['after'] and not exact and abs not in deleted:
2105 elif opts['after'] and not exact and abs not in deleted:
2140 continue
2106 continue
2141 elif abs in removed:
2107 elif abs in removed:
2142 continue
2108 continue
2143 if reason:
2109 if reason:
2144 if exact:
2110 if exact:
2145 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2111 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2146 else:
2112 else:
2147 if ui.verbose or not exact:
2113 if ui.verbose or not exact:
2148 ui.status(_('removing %s\n') % rel)
2114 ui.status(_('removing %s\n') % rel)
2149 remove.append(abs)
2115 remove.append(abs)
2150 repo.forget(forget)
2116 repo.forget(forget)
2151 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2117 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2152
2118
2153 def rename(ui, repo, *pats, **opts):
2119 def rename(ui, repo, *pats, **opts):
2154 """rename files; equivalent of copy + remove
2120 """rename files; equivalent of copy + remove
2155
2121
2156 Mark dest as copies of sources; mark sources for deletion. If
2122 Mark dest as copies of sources; mark sources for deletion. If
2157 dest is a directory, copies are put in that directory. If dest is
2123 dest is a directory, copies are put in that directory. If dest is
2158 a file, there can only be one source.
2124 a file, there can only be one source.
2159
2125
2160 By default, this command copies the contents of files as they
2126 By default, this command copies the contents of files as they
2161 stand in the working directory. If invoked with --after, the
2127 stand in the working directory. If invoked with --after, the
2162 operation is recorded, but no copying is performed.
2128 operation is recorded, but no copying is performed.
2163
2129
2164 This command takes effect in the next commit. To undo a rename
2130 This command takes effect in the next commit. To undo a rename
2165 before that, see hg revert.
2131 before that, see hg revert.
2166 """
2132 """
2167 wlock = repo.wlock(False)
2133 wlock = repo.wlock(False)
2168 try:
2134 try:
2169 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2135 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2170 finally:
2136 finally:
2171 del wlock
2137 del wlock
2172
2138
2173 def revert(ui, repo, *pats, **opts):
2139 def revert(ui, repo, *pats, **opts):
2174 """restore individual files or dirs to an earlier state
2140 """restore individual files or dirs to an earlier state
2175
2141
2176 (use update -r to check out earlier revisions, revert does not
2142 (use update -r to check out earlier revisions, revert does not
2177 change the working dir parents)
2143 change the working dir parents)
2178
2144
2179 With no revision specified, revert the named files or directories
2145 With no revision specified, revert the named files or directories
2180 to the contents they had in the parent of the working directory.
2146 to the contents they had in the parent of the working directory.
2181 This restores the contents of the affected files to an unmodified
2147 This restores the contents of the affected files to an unmodified
2182 state and unschedules adds, removes, copies, and renames. If the
2148 state and unschedules adds, removes, copies, and renames. If the
2183 working directory has two parents, you must explicitly specify the
2149 working directory has two parents, you must explicitly specify the
2184 revision to revert to.
2150 revision to revert to.
2185
2151
2186 Using the -r option, revert the given files or directories to their
2152 Using the -r option, revert the given files or directories to their
2187 contents as of a specific revision. This can be helpful to "roll
2153 contents as of a specific revision. This can be helpful to "roll
2188 back" some or all of an earlier change.
2154 back" some or all of an earlier change.
2189
2155
2190 Revert modifies the working directory. It does not commit any
2156 Revert modifies the working directory. It does not commit any
2191 changes, or change the parent of the working directory. If you
2157 changes, or change the parent of the working directory. If you
2192 revert to a revision other than the parent of the working
2158 revert to a revision other than the parent of the working
2193 directory, the reverted files will thus appear modified
2159 directory, the reverted files will thus appear modified
2194 afterwards.
2160 afterwards.
2195
2161
2196 If a file has been deleted, it is restored. If the executable
2162 If a file has been deleted, it is restored. If the executable
2197 mode of a file was changed, it is reset.
2163 mode of a file was changed, it is reset.
2198
2164
2199 If names are given, all files matching the names are reverted.
2165 If names are given, all files matching the names are reverted.
2200
2166
2201 If no arguments are given, no files are reverted.
2167 If no arguments are given, no files are reverted.
2202
2168
2203 Modified files are saved with a .orig suffix before reverting.
2169 Modified files are saved with a .orig suffix before reverting.
2204 To disable these backups, use --no-backup.
2170 To disable these backups, use --no-backup.
2205 """
2171 """
2206
2172
2207 if opts["date"]:
2173 if opts["date"]:
2208 if opts["rev"]:
2174 if opts["rev"]:
2209 raise util.Abort(_("you can't specify a revision and a date"))
2175 raise util.Abort(_("you can't specify a revision and a date"))
2210 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2176 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2211
2177
2212 if not pats and not opts['all']:
2178 if not pats and not opts['all']:
2213 raise util.Abort(_('no files or directories specified; '
2179 raise util.Abort(_('no files or directories specified; '
2214 'use --all to revert the whole repo'))
2180 'use --all to revert the whole repo'))
2215
2181
2216 parent, p2 = repo.dirstate.parents()
2182 parent, p2 = repo.dirstate.parents()
2217 if not opts['rev'] and p2 != nullid:
2183 if not opts['rev'] and p2 != nullid:
2218 raise util.Abort(_('uncommitted merge - please provide a '
2184 raise util.Abort(_('uncommitted merge - please provide a '
2219 'specific revision'))
2185 'specific revision'))
2220 ctx = repo.changectx(opts['rev'])
2186 ctx = repo.changectx(opts['rev'])
2221 node = ctx.node()
2187 node = ctx.node()
2222 mf = ctx.manifest()
2188 mf = ctx.manifest()
2223 if node == parent:
2189 if node == parent:
2224 pmf = mf
2190 pmf = mf
2225 else:
2191 else:
2226 pmf = None
2192 pmf = None
2227
2193
2228 # need all matching names in dirstate and manifest of target rev,
2194 # need all matching names in dirstate and manifest of target rev,
2229 # so have to walk both. do not print errors if files exist in one
2195 # so have to walk both. do not print errors if files exist in one
2230 # but not other.
2196 # but not other.
2231
2197
2232 names = {}
2198 names = {}
2233 target_only = {}
2199 target_only = {}
2234
2200
2235 wlock = repo.wlock()
2201 wlock = repo.wlock()
2236 try:
2202 try:
2237 # walk dirstate.
2203 # walk dirstate.
2238 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2204 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2239 badmatch=mf.has_key):
2205 badmatch=mf.has_key):
2240 names[abs] = (rel, exact)
2206 names[abs] = (rel, exact)
2241 if src == 'b':
2207 if src == 'b':
2242 target_only[abs] = True
2208 target_only[abs] = True
2243
2209
2244 # walk target manifest.
2210 # walk target manifest.
2245
2211
2246 def badmatch(path):
2212 def badmatch(path):
2247 if path in names:
2213 if path in names:
2248 return True
2214 return True
2249 path_ = path + '/'
2215 path_ = path + '/'
2250 for f in names:
2216 for f in names:
2251 if f.startswith(path_):
2217 if f.startswith(path_):
2252 return True
2218 return True
2253 return False
2219 return False
2254
2220
2255 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2221 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2256 badmatch=badmatch):
2222 badmatch=badmatch):
2257 if abs in names or src == 'b':
2223 if abs in names or src == 'b':
2258 continue
2224 continue
2259 names[abs] = (rel, exact)
2225 names[abs] = (rel, exact)
2260 target_only[abs] = True
2226 target_only[abs] = True
2261
2227
2262 changes = repo.status(match=names.has_key)[:5]
2228 changes = repo.status(match=names.has_key)[:5]
2263 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2229 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2264
2230
2265 # if f is a rename, also revert the source
2231 # if f is a rename, also revert the source
2266 cwd = repo.getcwd()
2232 cwd = repo.getcwd()
2267 for f in added:
2233 for f in added:
2268 src = repo.dirstate.copied(f)
2234 src = repo.dirstate.copied(f)
2269 if src and src not in names and repo.dirstate[src] == 'r':
2235 if src and src not in names and repo.dirstate[src] == 'r':
2270 removed[src] = None
2236 removed[src] = None
2271 names[src] = (repo.pathto(src, cwd), True)
2237 names[src] = (repo.pathto(src, cwd), True)
2272
2238
2273 revert = ([], _('reverting %s\n'))
2239 revert = ([], _('reverting %s\n'))
2274 add = ([], _('adding %s\n'))
2240 add = ([], _('adding %s\n'))
2275 remove = ([], _('removing %s\n'))
2241 remove = ([], _('removing %s\n'))
2276 forget = ([], _('forgetting %s\n'))
2242 forget = ([], _('forgetting %s\n'))
2277 undelete = ([], _('undeleting %s\n'))
2243 undelete = ([], _('undeleting %s\n'))
2278 update = {}
2244 update = {}
2279
2245
2280 disptable = (
2246 disptable = (
2281 # dispatch table:
2247 # dispatch table:
2282 # file state
2248 # file state
2283 # action if in target manifest
2249 # action if in target manifest
2284 # action if not in target manifest
2250 # action if not in target manifest
2285 # make backup if in target manifest
2251 # make backup if in target manifest
2286 # make backup if not in target manifest
2252 # make backup if not in target manifest
2287 (modified, revert, remove, True, True),
2253 (modified, revert, remove, True, True),
2288 (added, revert, forget, True, False),
2254 (added, revert, forget, True, False),
2289 (removed, undelete, None, False, False),
2255 (removed, undelete, None, False, False),
2290 (deleted, revert, remove, False, False),
2256 (deleted, revert, remove, False, False),
2291 (unknown, add, None, True, False),
2257 (unknown, add, None, True, False),
2292 (target_only, add, None, False, False),
2258 (target_only, add, None, False, False),
2293 )
2259 )
2294
2260
2295 entries = names.items()
2261 entries = names.items()
2296 entries.sort()
2262 entries.sort()
2297
2263
2298 for abs, (rel, exact) in entries:
2264 for abs, (rel, exact) in entries:
2299 mfentry = mf.get(abs)
2265 mfentry = mf.get(abs)
2300 target = repo.wjoin(abs)
2266 target = repo.wjoin(abs)
2301 def handle(xlist, dobackup):
2267 def handle(xlist, dobackup):
2302 xlist[0].append(abs)
2268 xlist[0].append(abs)
2303 update[abs] = 1
2269 update[abs] = 1
2304 if dobackup and not opts['no_backup'] and util.lexists(target):
2270 if dobackup and not opts['no_backup'] and util.lexists(target):
2305 bakname = "%s.orig" % rel
2271 bakname = "%s.orig" % rel
2306 ui.note(_('saving current version of %s as %s\n') %
2272 ui.note(_('saving current version of %s as %s\n') %
2307 (rel, bakname))
2273 (rel, bakname))
2308 if not opts.get('dry_run'):
2274 if not opts.get('dry_run'):
2309 util.copyfile(target, bakname)
2275 util.copyfile(target, bakname)
2310 if ui.verbose or not exact:
2276 if ui.verbose or not exact:
2311 ui.status(xlist[1] % rel)
2277 ui.status(xlist[1] % rel)
2312 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2278 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2313 if abs not in table: continue
2279 if abs not in table: continue
2314 # file has changed in dirstate
2280 # file has changed in dirstate
2315 if mfentry:
2281 if mfentry:
2316 handle(hitlist, backuphit)
2282 handle(hitlist, backuphit)
2317 elif misslist is not None:
2283 elif misslist is not None:
2318 handle(misslist, backupmiss)
2284 handle(misslist, backupmiss)
2319 else:
2285 else:
2320 if exact: ui.warn(_('file not managed: %s\n') % rel)
2286 if exact: ui.warn(_('file not managed: %s\n') % rel)
2321 break
2287 break
2322 else:
2288 else:
2323 # file has not changed in dirstate
2289 # file has not changed in dirstate
2324 if node == parent:
2290 if node == parent:
2325 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2291 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2326 continue
2292 continue
2327 if pmf is None:
2293 if pmf is None:
2328 # only need parent manifest in this unlikely case,
2294 # only need parent manifest in this unlikely case,
2329 # so do not read by default
2295 # so do not read by default
2330 pmf = repo.changectx(parent).manifest()
2296 pmf = repo.changectx(parent).manifest()
2331 if abs in pmf:
2297 if abs in pmf:
2332 if mfentry:
2298 if mfentry:
2333 # if version of file is same in parent and target
2299 # if version of file is same in parent and target
2334 # manifests, do nothing
2300 # manifests, do nothing
2335 if pmf[abs] != mfentry:
2301 if pmf[abs] != mfentry:
2336 handle(revert, False)
2302 handle(revert, False)
2337 else:
2303 else:
2338 handle(remove, False)
2304 handle(remove, False)
2339
2305
2340 if not opts.get('dry_run'):
2306 if not opts.get('dry_run'):
2341 for f in forget[0]:
2307 for f in forget[0]:
2342 repo.dirstate.forget(f)
2308 repo.dirstate.forget(f)
2343 r = hg.revert(repo, node, update.has_key)
2309 r = hg.revert(repo, node, update.has_key)
2344 for f in add[0]:
2310 for f in add[0]:
2345 repo.dirstate.add(f)
2311 repo.dirstate.add(f)
2346 for f in undelete[0]:
2312 for f in undelete[0]:
2347 repo.dirstate.normal(f)
2313 repo.dirstate.normal(f)
2348 for f in remove[0]:
2314 for f in remove[0]:
2349 repo.dirstate.remove(f)
2315 repo.dirstate.remove(f)
2350 return r
2316 return r
2351 finally:
2317 finally:
2352 del wlock
2318 del wlock
2353
2319
2354 def rollback(ui, repo):
2320 def rollback(ui, repo):
2355 """roll back the last transaction
2321 """roll back the last transaction
2356
2322
2357 This command should be used with care. There is only one level of
2323 This command should be used with care. There is only one level of
2358 rollback, and there is no way to undo a rollback. It will also
2324 rollback, and there is no way to undo a rollback. It will also
2359 restore the dirstate at the time of the last transaction, losing
2325 restore the dirstate at the time of the last transaction, losing
2360 any dirstate changes since that time.
2326 any dirstate changes since that time.
2361
2327
2362 Transactions are used to encapsulate the effects of all commands
2328 Transactions are used to encapsulate the effects of all commands
2363 that create new changesets or propagate existing changesets into a
2329 that create new changesets or propagate existing changesets into a
2364 repository. For example, the following commands are transactional,
2330 repository. For example, the following commands are transactional,
2365 and their effects can be rolled back:
2331 and their effects can be rolled back:
2366
2332
2367 commit
2333 commit
2368 import
2334 import
2369 pull
2335 pull
2370 push (with this repository as destination)
2336 push (with this repository as destination)
2371 unbundle
2337 unbundle
2372
2338
2373 This command is not intended for use on public repositories. Once
2339 This command is not intended for use on public repositories. Once
2374 changes are visible for pull by other users, rolling a transaction
2340 changes are visible for pull by other users, rolling a transaction
2375 back locally is ineffective (someone else may already have pulled
2341 back locally is ineffective (someone else may already have pulled
2376 the changes). Furthermore, a race is possible with readers of the
2342 the changes). Furthermore, a race is possible with readers of the
2377 repository; for example an in-progress pull from the repository
2343 repository; for example an in-progress pull from the repository
2378 may fail if a rollback is performed.
2344 may fail if a rollback is performed.
2379 """
2345 """
2380 repo.rollback()
2346 repo.rollback()
2381
2347
2382 def root(ui, repo):
2348 def root(ui, repo):
2383 """print the root (top) of the current working dir
2349 """print the root (top) of the current working dir
2384
2350
2385 Print the root directory of the current repository.
2351 Print the root directory of the current repository.
2386 """
2352 """
2387 ui.write(repo.root + "\n")
2353 ui.write(repo.root + "\n")
2388
2354
2389 def serve(ui, repo, **opts):
2355 def serve(ui, repo, **opts):
2390 """export the repository via HTTP
2356 """export the repository via HTTP
2391
2357
2392 Start a local HTTP repository browser and pull server.
2358 Start a local HTTP repository browser and pull server.
2393
2359
2394 By default, the server logs accesses to stdout and errors to
2360 By default, the server logs accesses to stdout and errors to
2395 stderr. Use the "-A" and "-E" options to log to files.
2361 stderr. Use the "-A" and "-E" options to log to files.
2396 """
2362 """
2397
2363
2398 if opts["stdio"]:
2364 if opts["stdio"]:
2399 if repo is None:
2365 if repo is None:
2400 raise hg.RepoError(_("There is no Mercurial repository here"
2366 raise hg.RepoError(_("There is no Mercurial repository here"
2401 " (.hg not found)"))
2367 " (.hg not found)"))
2402 s = sshserver.sshserver(ui, repo)
2368 s = sshserver.sshserver(ui, repo)
2403 s.serve_forever()
2369 s.serve_forever()
2404
2370
2405 parentui = ui.parentui or ui
2371 parentui = ui.parentui or ui
2406 optlist = ("name templates style address port prefix ipv6"
2372 optlist = ("name templates style address port prefix ipv6"
2407 " accesslog errorlog webdir_conf certificate")
2373 " accesslog errorlog webdir_conf certificate")
2408 for o in optlist.split():
2374 for o in optlist.split():
2409 if opts[o]:
2375 if opts[o]:
2410 parentui.setconfig("web", o, str(opts[o]))
2376 parentui.setconfig("web", o, str(opts[o]))
2411 if (repo is not None) and (repo.ui != parentui):
2377 if (repo is not None) and (repo.ui != parentui):
2412 repo.ui.setconfig("web", o, str(opts[o]))
2378 repo.ui.setconfig("web", o, str(opts[o]))
2413
2379
2414 if repo is None and not ui.config("web", "webdir_conf"):
2380 if repo is None and not ui.config("web", "webdir_conf"):
2415 raise hg.RepoError(_("There is no Mercurial repository here"
2381 raise hg.RepoError(_("There is no Mercurial repository here"
2416 " (.hg not found)"))
2382 " (.hg not found)"))
2417
2383
2418 class service:
2384 class service:
2419 def init(self):
2385 def init(self):
2420 util.set_signal_handler()
2386 util.set_signal_handler()
2421 try:
2387 try:
2422 self.httpd = hgweb.server.create_server(parentui, repo)
2388 self.httpd = hgweb.server.create_server(parentui, repo)
2423 except socket.error, inst:
2389 except socket.error, inst:
2424 raise util.Abort(_('cannot start server: ') + inst.args[1])
2390 raise util.Abort(_('cannot start server: ') + inst.args[1])
2425
2391
2426 if not ui.verbose: return
2392 if not ui.verbose: return
2427
2393
2428 if self.httpd.prefix:
2394 if self.httpd.prefix:
2429 prefix = self.httpd.prefix.strip('/') + '/'
2395 prefix = self.httpd.prefix.strip('/') + '/'
2430 else:
2396 else:
2431 prefix = ''
2397 prefix = ''
2432
2398
2433 if self.httpd.port != 80:
2399 if self.httpd.port != 80:
2434 ui.status(_('listening at http://%s:%d/%s\n') %
2400 ui.status(_('listening at http://%s:%d/%s\n') %
2435 (self.httpd.addr, self.httpd.port, prefix))
2401 (self.httpd.addr, self.httpd.port, prefix))
2436 else:
2402 else:
2437 ui.status(_('listening at http://%s/%s\n') %
2403 ui.status(_('listening at http://%s/%s\n') %
2438 (self.httpd.addr, prefix))
2404 (self.httpd.addr, prefix))
2439
2405
2440 def run(self):
2406 def run(self):
2441 self.httpd.serve_forever()
2407 self.httpd.serve_forever()
2442
2408
2443 service = service()
2409 service = service()
2444
2410
2445 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2411 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2446
2412
2447 def status(ui, repo, *pats, **opts):
2413 def status(ui, repo, *pats, **opts):
2448 """show changed files in the working directory
2414 """show changed files in the working directory
2449
2415
2450 Show status of files in the repository. If names are given, only
2416 Show status of files in the repository. If names are given, only
2451 files that match are shown. Files that are clean or ignored or
2417 files that match are shown. Files that are clean or ignored or
2452 source of a copy/move operation, are not listed unless -c (clean),
2418 source of a copy/move operation, are not listed unless -c (clean),
2453 -i (ignored), -C (copies) or -A is given. Unless options described
2419 -i (ignored), -C (copies) or -A is given. Unless options described
2454 with "show only ..." are given, the options -mardu are used.
2420 with "show only ..." are given, the options -mardu are used.
2455
2421
2456 NOTE: status may appear to disagree with diff if permissions have
2422 NOTE: status may appear to disagree with diff if permissions have
2457 changed or a merge has occurred. The standard diff format does not
2423 changed or a merge has occurred. The standard diff format does not
2458 report permission changes and diff only reports changes relative
2424 report permission changes and diff only reports changes relative
2459 to one merge parent.
2425 to one merge parent.
2460
2426
2461 If one revision is given, it is used as the base revision.
2427 If one revision is given, it is used as the base revision.
2462 If two revisions are given, the difference between them is shown.
2428 If two revisions are given, the difference between them is shown.
2463
2429
2464 The codes used to show the status of files are:
2430 The codes used to show the status of files are:
2465 M = modified
2431 M = modified
2466 A = added
2432 A = added
2467 R = removed
2433 R = removed
2468 C = clean
2434 C = clean
2469 ! = deleted, but still tracked
2435 ! = deleted, but still tracked
2470 ? = not tracked
2436 ? = not tracked
2471 I = ignored
2437 I = ignored
2472 = the previous added file was copied from here
2438 = the previous added file was copied from here
2473 """
2439 """
2474
2440
2475 all = opts['all']
2441 all = opts['all']
2476 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2442 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2477
2443
2478 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2444 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2479 cwd = (pats and repo.getcwd()) or ''
2445 cwd = (pats and repo.getcwd()) or ''
2480 modified, added, removed, deleted, unknown, ignored, clean = [
2446 modified, added, removed, deleted, unknown, ignored, clean = [
2481 n for n in repo.status(node1=node1, node2=node2, files=files,
2447 n for n in repo.status(node1=node1, node2=node2, files=files,
2482 match=matchfn,
2448 match=matchfn,
2483 list_ignored=all or opts['ignored'],
2449 list_ignored=all or opts['ignored'],
2484 list_clean=all or opts['clean'])]
2450 list_clean=all or opts['clean'])]
2485
2451
2486 changetypes = (('modified', 'M', modified),
2452 changetypes = (('modified', 'M', modified),
2487 ('added', 'A', added),
2453 ('added', 'A', added),
2488 ('removed', 'R', removed),
2454 ('removed', 'R', removed),
2489 ('deleted', '!', deleted),
2455 ('deleted', '!', deleted),
2490 ('unknown', '?', unknown),
2456 ('unknown', '?', unknown),
2491 ('ignored', 'I', ignored))
2457 ('ignored', 'I', ignored))
2492
2458
2493 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2459 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2494
2460
2495 end = opts['print0'] and '\0' or '\n'
2461 end = opts['print0'] and '\0' or '\n'
2496
2462
2497 for opt, char, changes in ([ct for ct in explicit_changetypes
2463 for opt, char, changes in ([ct for ct in explicit_changetypes
2498 if all or opts[ct[0]]]
2464 if all or opts[ct[0]]]
2499 or changetypes):
2465 or changetypes):
2500 if opts['no_status']:
2466 if opts['no_status']:
2501 format = "%%s%s" % end
2467 format = "%%s%s" % end
2502 else:
2468 else:
2503 format = "%s %%s%s" % (char, end)
2469 format = "%s %%s%s" % (char, end)
2504
2470
2505 for f in changes:
2471 for f in changes:
2506 ui.write(format % repo.pathto(f, cwd))
2472 ui.write(format % repo.pathto(f, cwd))
2507 if ((all or opts.get('copies')) and not opts.get('no_status')):
2473 if ((all or opts.get('copies')) and not opts.get('no_status')):
2508 copied = repo.dirstate.copied(f)
2474 copied = repo.dirstate.copied(f)
2509 if copied:
2475 if copied:
2510 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2476 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2511
2477
2512 def tag(ui, repo, name, rev_=None, **opts):
2478 def tag(ui, repo, name, rev_=None, **opts):
2513 """add a tag for the current or given revision
2479 """add a tag for the current or given revision
2514
2480
2515 Name a particular revision using <name>.
2481 Name a particular revision using <name>.
2516
2482
2517 Tags are used to name particular revisions of the repository and are
2483 Tags are used to name particular revisions of the repository and are
2518 very useful to compare different revision, to go back to significant
2484 very useful to compare different revision, to go back to significant
2519 earlier versions or to mark branch points as releases, etc.
2485 earlier versions or to mark branch points as releases, etc.
2520
2486
2521 If no revision is given, the parent of the working directory is used,
2487 If no revision is given, the parent of the working directory is used,
2522 or tip if no revision is checked out.
2488 or tip if no revision is checked out.
2523
2489
2524 To facilitate version control, distribution, and merging of tags,
2490 To facilitate version control, distribution, and merging of tags,
2525 they are stored as a file named ".hgtags" which is managed
2491 they are stored as a file named ".hgtags" which is managed
2526 similarly to other project files and can be hand-edited if
2492 similarly to other project files and can be hand-edited if
2527 necessary. The file '.hg/localtags' is used for local tags (not
2493 necessary. The file '.hg/localtags' is used for local tags (not
2528 shared among repositories).
2494 shared among repositories).
2529 """
2495 """
2530 if name in ['tip', '.', 'null']:
2496 if name in ['tip', '.', 'null']:
2531 raise util.Abort(_("the name '%s' is reserved") % name)
2497 raise util.Abort(_("the name '%s' is reserved") % name)
2532 if rev_ is not None:
2498 if rev_ is not None:
2533 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2499 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2534 "please use 'hg tag [-r REV] NAME' instead\n"))
2500 "please use 'hg tag [-r REV] NAME' instead\n"))
2535 if opts['rev']:
2501 if opts['rev']:
2536 raise util.Abort(_("use only one form to specify the revision"))
2502 raise util.Abort(_("use only one form to specify the revision"))
2537 if opts['rev'] and opts['remove']:
2503 if opts['rev'] and opts['remove']:
2538 raise util.Abort(_("--rev and --remove are incompatible"))
2504 raise util.Abort(_("--rev and --remove are incompatible"))
2539 if opts['rev']:
2505 if opts['rev']:
2540 rev_ = opts['rev']
2506 rev_ = opts['rev']
2541 message = opts['message']
2507 message = opts['message']
2542 if opts['remove']:
2508 if opts['remove']:
2543 tagtype = repo.tagtype(name)
2509 tagtype = repo.tagtype(name)
2544
2510
2545 if not tagtype:
2511 if not tagtype:
2546 raise util.Abort(_('tag %s does not exist') % name)
2512 raise util.Abort(_('tag %s does not exist') % name)
2547 if opts['local'] and tagtype == 'global':
2513 if opts['local'] and tagtype == 'global':
2548 raise util.Abort(_('%s tag is global') % name)
2514 raise util.Abort(_('%s tag is global') % name)
2549 if not opts['local'] and tagtype == 'local':
2515 if not opts['local'] and tagtype == 'local':
2550 raise util.Abort(_('%s tag is local') % name)
2516 raise util.Abort(_('%s tag is local') % name)
2551
2517
2552 rev_ = nullid
2518 rev_ = nullid
2553 if not message:
2519 if not message:
2554 message = _('Removed tag %s') % name
2520 message = _('Removed tag %s') % name
2555 elif name in repo.tags() and not opts['force']:
2521 elif name in repo.tags() and not opts['force']:
2556 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2522 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2557 % name)
2523 % name)
2558 if not rev_ and repo.dirstate.parents()[1] != nullid:
2524 if not rev_ and repo.dirstate.parents()[1] != nullid:
2559 raise util.Abort(_('uncommitted merge - please provide a '
2525 raise util.Abort(_('uncommitted merge - please provide a '
2560 'specific revision'))
2526 'specific revision'))
2561 r = repo.changectx(rev_).node()
2527 r = repo.changectx(rev_).node()
2562
2528
2563 if not message:
2529 if not message:
2564 message = _('Added tag %s for changeset %s') % (name, short(r))
2530 message = _('Added tag %s for changeset %s') % (name, short(r))
2565
2531
2566 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2532 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2567
2533
2568 def tags(ui, repo):
2534 def tags(ui, repo):
2569 """list repository tags
2535 """list repository tags
2570
2536
2571 List the repository tags.
2537 List the repository tags.
2572
2538
2573 This lists both regular and local tags. When the -v/--verbose switch
2539 This lists both regular and local tags. When the -v/--verbose switch
2574 is used, a third column "local" is printed for local tags.
2540 is used, a third column "local" is printed for local tags.
2575 """
2541 """
2576
2542
2577 l = repo.tagslist()
2543 l = repo.tagslist()
2578 l.reverse()
2544 l.reverse()
2579 hexfunc = ui.debugflag and hex or short
2545 hexfunc = ui.debugflag and hex or short
2580 tagtype = ""
2546 tagtype = ""
2581
2547
2582 for t, n in l:
2548 for t, n in l:
2583 if ui.quiet:
2549 if ui.quiet:
2584 ui.write("%s\n" % t)
2550 ui.write("%s\n" % t)
2585 continue
2551 continue
2586
2552
2587 try:
2553 try:
2588 hn = hexfunc(n)
2554 hn = hexfunc(n)
2589 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2555 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2590 except revlog.LookupError:
2556 except revlog.LookupError:
2591 r = " ?:%s" % hn
2557 r = " ?:%s" % hn
2592 else:
2558 else:
2593 spaces = " " * (30 - util.locallen(t))
2559 spaces = " " * (30 - util.locallen(t))
2594 if ui.verbose:
2560 if ui.verbose:
2595 if repo.tagtype(t) == 'local':
2561 if repo.tagtype(t) == 'local':
2596 tagtype = " local"
2562 tagtype = " local"
2597 else:
2563 else:
2598 tagtype = ""
2564 tagtype = ""
2599 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2565 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2600
2566
2601 def tip(ui, repo, **opts):
2567 def tip(ui, repo, **opts):
2602 """show the tip revision
2568 """show the tip revision
2603
2569
2604 Show the tip revision.
2570 Show the tip revision.
2605 """
2571 """
2606 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2572 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2607
2573
2608 def unbundle(ui, repo, fname1, *fnames, **opts):
2574 def unbundle(ui, repo, fname1, *fnames, **opts):
2609 """apply one or more changegroup files
2575 """apply one or more changegroup files
2610
2576
2611 Apply one or more compressed changegroup files generated by the
2577 Apply one or more compressed changegroup files generated by the
2612 bundle command.
2578 bundle command.
2613 """
2579 """
2614 fnames = (fname1,) + fnames
2580 fnames = (fname1,) + fnames
2615 for fname in fnames:
2581 for fname in fnames:
2616 if os.path.exists(fname):
2582 if os.path.exists(fname):
2617 f = open(fname, "rb")
2583 f = open(fname, "rb")
2618 else:
2584 else:
2619 f = urllib.urlopen(fname)
2585 f = urllib.urlopen(fname)
2620 gen = changegroup.readbundle(f, fname)
2586 gen = changegroup.readbundle(f, fname)
2621 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2587 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2622
2588
2623 return postincoming(ui, repo, modheads, opts['update'], None)
2589 return postincoming(ui, repo, modheads, opts['update'], None)
2624
2590
2625 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2591 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2626 """update working directory
2592 """update working directory
2627
2593
2628 Update the working directory to the specified revision, or the
2594 Update the working directory to the specified revision, or the
2629 tip of the current branch if none is specified.
2595 tip of the current branch if none is specified.
2630
2596
2631 If there are no outstanding changes in the working directory and
2597 If there are no outstanding changes in the working directory and
2632 there is a linear relationship between the current version and the
2598 there is a linear relationship between the current version and the
2633 requested version, the result is the requested version.
2599 requested version, the result is the requested version.
2634
2600
2635 To merge the working directory with another revision, use the
2601 To merge the working directory with another revision, use the
2636 merge command.
2602 merge command.
2637
2603
2638 By default, update will refuse to run if doing so would require
2604 By default, update will refuse to run if doing so would require
2639 discarding local changes.
2605 discarding local changes.
2640 """
2606 """
2641 if rev and node:
2607 if rev and node:
2642 raise util.Abort(_("please specify just one revision"))
2608 raise util.Abort(_("please specify just one revision"))
2643
2609
2644 if not rev:
2610 if not rev:
2645 rev = node
2611 rev = node
2646
2612
2647 if date:
2613 if date:
2648 if rev:
2614 if rev:
2649 raise util.Abort(_("you can't specify a revision and a date"))
2615 raise util.Abort(_("you can't specify a revision and a date"))
2650 rev = cmdutil.finddate(ui, repo, date)
2616 rev = cmdutil.finddate(ui, repo, date)
2651
2617
2652 if clean:
2618 if clean:
2653 return hg.clean(repo, rev)
2619 return hg.clean(repo, rev)
2654 else:
2620 else:
2655 return hg.update(repo, rev)
2621 return hg.update(repo, rev)
2656
2622
2657 def verify(ui, repo):
2623 def verify(ui, repo):
2658 """verify the integrity of the repository
2624 """verify the integrity of the repository
2659
2625
2660 Verify the integrity of the current repository.
2626 Verify the integrity of the current repository.
2661
2627
2662 This will perform an extensive check of the repository's
2628 This will perform an extensive check of the repository's
2663 integrity, validating the hashes and checksums of each entry in
2629 integrity, validating the hashes and checksums of each entry in
2664 the changelog, manifest, and tracked files, as well as the
2630 the changelog, manifest, and tracked files, as well as the
2665 integrity of their crosslinks and indices.
2631 integrity of their crosslinks and indices.
2666 """
2632 """
2667 return hg.verify(repo)
2633 return hg.verify(repo)
2668
2634
2669 def version_(ui):
2635 def version_(ui):
2670 """output version and copyright information"""
2636 """output version and copyright information"""
2671 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2637 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2672 % version.get_version())
2638 % version.get_version())
2673 ui.status(_(
2639 ui.status(_(
2674 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2640 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2675 "This is free software; see the source for copying conditions. "
2641 "This is free software; see the source for copying conditions. "
2676 "There is NO\nwarranty; "
2642 "There is NO\nwarranty; "
2677 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2643 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2678 ))
2644 ))
2679
2645
2680 # Command options and aliases are listed here, alphabetically
2646 # Command options and aliases are listed here, alphabetically
2681
2647
2682 globalopts = [
2648 globalopts = [
2683 ('R', 'repository', '',
2649 ('R', 'repository', '',
2684 _('repository root directory or symbolic path name')),
2650 _('repository root directory or symbolic path name')),
2685 ('', 'cwd', '', _('change working directory')),
2651 ('', 'cwd', '', _('change working directory')),
2686 ('y', 'noninteractive', None,
2652 ('y', 'noninteractive', None,
2687 _('do not prompt, assume \'yes\' for any required answers')),
2653 _('do not prompt, assume \'yes\' for any required answers')),
2688 ('q', 'quiet', None, _('suppress output')),
2654 ('q', 'quiet', None, _('suppress output')),
2689 ('v', 'verbose', None, _('enable additional output')),
2655 ('v', 'verbose', None, _('enable additional output')),
2690 ('', 'config', [], _('set/override config option')),
2656 ('', 'config', [], _('set/override config option')),
2691 ('', 'debug', None, _('enable debugging output')),
2657 ('', 'debug', None, _('enable debugging output')),
2692 ('', 'debugger', None, _('start debugger')),
2658 ('', 'debugger', None, _('start debugger')),
2693 ('', 'encoding', util._encoding, _('set the charset encoding')),
2659 ('', 'encoding', util._encoding, _('set the charset encoding')),
2694 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2660 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2695 ('', 'lsprof', None, _('print improved command execution profile')),
2661 ('', 'lsprof', None, _('print improved command execution profile')),
2696 ('', 'traceback', None, _('print traceback on exception')),
2662 ('', 'traceback', None, _('print traceback on exception')),
2697 ('', 'time', None, _('time how long the command takes')),
2663 ('', 'time', None, _('time how long the command takes')),
2698 ('', 'profile', None, _('print command execution profile')),
2664 ('', 'profile', None, _('print command execution profile')),
2699 ('', 'version', None, _('output version information and exit')),
2665 ('', 'version', None, _('output version information and exit')),
2700 ('h', 'help', None, _('display help and exit')),
2666 ('h', 'help', None, _('display help and exit')),
2701 ]
2667 ]
2702
2668
2703 dryrunopts = [('n', 'dry-run', None,
2669 dryrunopts = [('n', 'dry-run', None,
2704 _('do not perform actions, just print output'))]
2670 _('do not perform actions, just print output'))]
2705
2671
2706 remoteopts = [
2672 remoteopts = [
2707 ('e', 'ssh', '', _('specify ssh command to use')),
2673 ('e', 'ssh', '', _('specify ssh command to use')),
2708 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2674 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2709 ]
2675 ]
2710
2676
2711 walkopts = [
2677 walkopts = [
2712 ('I', 'include', [], _('include names matching the given patterns')),
2678 ('I', 'include', [], _('include names matching the given patterns')),
2713 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2679 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2714 ]
2680 ]
2715
2681
2716 commitopts = [
2682 commitopts = [
2717 ('m', 'message', '', _('use <text> as commit message')),
2683 ('m', 'message', '', _('use <text> as commit message')),
2718 ('l', 'logfile', '', _('read commit message from <file>')),
2684 ('l', 'logfile', '', _('read commit message from <file>')),
2719 ]
2685 ]
2720
2686
2721 commitopts2 = [
2687 commitopts2 = [
2722 ('d', 'date', '', _('record datecode as commit date')),
2688 ('d', 'date', '', _('record datecode as commit date')),
2723 ('u', 'user', '', _('record user as committer')),
2689 ('u', 'user', '', _('record user as committer')),
2724 ]
2690 ]
2725
2691
2726 table = {
2692 table = {
2727 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2693 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2728 "addremove":
2694 "addremove":
2729 (addremove,
2695 (addremove,
2730 [('s', 'similarity', '',
2696 [('s', 'similarity', '',
2731 _('guess renamed files by similarity (0<=s<=100)')),
2697 _('guess renamed files by similarity (0<=s<=100)')),
2732 ] + walkopts + dryrunopts,
2698 ] + walkopts + dryrunopts,
2733 _('hg addremove [OPTION]... [FILE]...')),
2699 _('hg addremove [OPTION]... [FILE]...')),
2734 "^annotate":
2700 "^annotate":
2735 (annotate,
2701 (annotate,
2736 [('r', 'rev', '', _('annotate the specified revision')),
2702 [('r', 'rev', '', _('annotate the specified revision')),
2737 ('f', 'follow', None, _('follow file copies and renames')),
2703 ('f', 'follow', None, _('follow file copies and renames')),
2738 ('a', 'text', None, _('treat all files as text')),
2704 ('a', 'text', None, _('treat all files as text')),
2739 ('u', 'user', None, _('list the author')),
2705 ('u', 'user', None, _('list the author')),
2740 ('d', 'date', None, _('list the date')),
2706 ('d', 'date', None, _('list the date')),
2741 ('n', 'number', None, _('list the revision number (default)')),
2707 ('n', 'number', None, _('list the revision number (default)')),
2742 ('c', 'changeset', None, _('list the changeset')),
2708 ('c', 'changeset', None, _('list the changeset')),
2743 ('l', 'line-number', None,
2709 ('l', 'line-number', None,
2744 _('show line number at the first appearance'))
2710 _('show line number at the first appearance'))
2745 ] + walkopts,
2711 ] + walkopts,
2746 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2712 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2747 "archive":
2713 "archive":
2748 (archive,
2714 (archive,
2749 [('', 'no-decode', None, _('do not pass files through decoders')),
2715 [('', 'no-decode', None, _('do not pass files through decoders')),
2750 ('p', 'prefix', '', _('directory prefix for files in archive')),
2716 ('p', 'prefix', '', _('directory prefix for files in archive')),
2751 ('r', 'rev', '', _('revision to distribute')),
2717 ('r', 'rev', '', _('revision to distribute')),
2752 ('t', 'type', '', _('type of distribution to create')),
2718 ('t', 'type', '', _('type of distribution to create')),
2753 ] + walkopts,
2719 ] + walkopts,
2754 _('hg archive [OPTION]... DEST')),
2720 _('hg archive [OPTION]... DEST')),
2755 "backout":
2721 "backout":
2756 (backout,
2722 (backout,
2757 [('', 'merge', None,
2723 [('', 'merge', None,
2758 _('merge with old dirstate parent after backout')),
2724 _('merge with old dirstate parent after backout')),
2759 ('', 'parent', '', _('parent to choose when backing out merge')),
2725 ('', 'parent', '', _('parent to choose when backing out merge')),
2760 ('r', 'rev', '', _('revision to backout')),
2726 ('r', 'rev', '', _('revision to backout')),
2761 ] + walkopts + commitopts + commitopts2,
2727 ] + walkopts + commitopts + commitopts2,
2762 _('hg backout [OPTION]... [-r] REV')),
2728 _('hg backout [OPTION]... [-r] REV')),
2763 "bisect":
2729 "bisect":
2764 (bisect,
2730 (bisect,
2765 [('r', 'reset', False, _('reset bisect state')),
2731 [('r', 'reset', False, _('reset bisect state')),
2766 ('g', 'good', False, _('mark changeset good')),
2732 ('g', 'good', False, _('mark changeset good')),
2767 ('b', 'bad', False, _('mark changeset bad')),
2733 ('b', 'bad', False, _('mark changeset bad')),
2768 ('s', 'skip', False, _('skip testing changeset')),
2734 ('s', 'skip', False, _('skip testing changeset')),
2769 ('U', 'noupdate', False, _('do not update to target'))],
2735 ('U', 'noupdate', False, _('do not update to target'))],
2770 _("hg bisect [-gbsr] [REV]")),
2736 _("hg bisect [-gbsr] [REV]")),
2771 "branch":
2737 "branch":
2772 (branch,
2738 (branch,
2773 [('f', 'force', None,
2739 [('f', 'force', None,
2774 _('set branch name even if it shadows an existing branch'))],
2740 _('set branch name even if it shadows an existing branch'))],
2775 _('hg branch [-f] [NAME]')),
2741 _('hg branch [-f] [NAME]')),
2776 "branches":
2742 "branches":
2777 (branches,
2743 (branches,
2778 [('a', 'active', False,
2744 [('a', 'active', False,
2779 _('show only branches that have unmerged heads'))],
2745 _('show only branches that have unmerged heads'))],
2780 _('hg branches [-a]')),
2746 _('hg branches [-a]')),
2781 "bundle":
2747 "bundle":
2782 (bundle,
2748 (bundle,
2783 [('f', 'force', None,
2749 [('f', 'force', None,
2784 _('run even when remote repository is unrelated')),
2750 _('run even when remote repository is unrelated')),
2785 ('r', 'rev', [],
2751 ('r', 'rev', [],
2786 _('a changeset you would like to bundle')),
2752 _('a changeset you would like to bundle')),
2787 ('', 'base', [],
2753 ('', 'base', [],
2788 _('a base changeset to specify instead of a destination')),
2754 _('a base changeset to specify instead of a destination')),
2789 ] + remoteopts,
2755 ] + remoteopts,
2790 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2756 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2791 "cat":
2757 "cat":
2792 (cat,
2758 (cat,
2793 [('o', 'output', '', _('print output to file with formatted name')),
2759 [('o', 'output', '', _('print output to file with formatted name')),
2794 ('r', 'rev', '', _('print the given revision')),
2760 ('r', 'rev', '', _('print the given revision')),
2795 ] + walkopts,
2761 ] + walkopts,
2796 _('hg cat [OPTION]... FILE...')),
2762 _('hg cat [OPTION]... FILE...')),
2797 "^clone":
2763 "^clone":
2798 (clone,
2764 (clone,
2799 [('U', 'noupdate', None, _('do not update the new working directory')),
2765 [('U', 'noupdate', None, _('do not update the new working directory')),
2800 ('r', 'rev', [],
2766 ('r', 'rev', [],
2801 _('a changeset you would like to have after cloning')),
2767 _('a changeset you would like to have after cloning')),
2802 ('', 'pull', None, _('use pull protocol to copy metadata')),
2768 ('', 'pull', None, _('use pull protocol to copy metadata')),
2803 ('', 'uncompressed', None,
2769 ('', 'uncompressed', None,
2804 _('use uncompressed transfer (fast over LAN)')),
2770 _('use uncompressed transfer (fast over LAN)')),
2805 ] + remoteopts,
2771 ] + remoteopts,
2806 _('hg clone [OPTION]... SOURCE [DEST]')),
2772 _('hg clone [OPTION]... SOURCE [DEST]')),
2807 "^commit|ci":
2773 "^commit|ci":
2808 (commit,
2774 (commit,
2809 [('A', 'addremove', None,
2775 [('A', 'addremove', None,
2810 _('mark new/missing files as added/removed before committing')),
2776 _('mark new/missing files as added/removed before committing')),
2811 ] + walkopts + commitopts + commitopts2,
2777 ] + walkopts + commitopts + commitopts2,
2812 _('hg commit [OPTION]... [FILE]...')),
2778 _('hg commit [OPTION]... [FILE]...')),
2813 "copy|cp":
2779 "copy|cp":
2814 (copy,
2780 (copy,
2815 [('A', 'after', None, _('record a copy that has already occurred')),
2781 [('A', 'after', None, _('record a copy that has already occurred')),
2816 ('f', 'force', None,
2782 ('f', 'force', None,
2817 _('forcibly copy over an existing managed file')),
2783 _('forcibly copy over an existing managed file')),
2818 ] + walkopts + dryrunopts,
2784 ] + walkopts + dryrunopts,
2819 _('hg copy [OPTION]... [SOURCE]... DEST')),
2785 _('hg copy [OPTION]... [SOURCE]... DEST')),
2820 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2786 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2821 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2787 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2822 "debugcomplete":
2788 "debugcomplete":
2823 (debugcomplete,
2789 (debugcomplete,
2824 [('o', 'options', None, _('show the command options'))],
2790 [('o', 'options', None, _('show the command options'))],
2825 _('hg debugcomplete [-o] CMD')),
2791 _('hg debugcomplete [-o] CMD')),
2826 "debugdate":
2792 "debugdate":
2827 (debugdate,
2793 (debugdate,
2828 [('e', 'extended', None, _('try extended date formats'))],
2794 [('e', 'extended', None, _('try extended date formats'))],
2829 _('hg debugdate [-e] DATE [RANGE]')),
2795 _('hg debugdate [-e] DATE [RANGE]')),
2830 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2796 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2831 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2797 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2832 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2798 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2833 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2799 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2834 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2800 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2835 "debugrawcommit|rawcommit":
2801 "debugrawcommit|rawcommit":
2836 (rawcommit,
2802 (rawcommit,
2837 [('p', 'parent', [], _('parent')),
2803 [('p', 'parent', [], _('parent')),
2838 ('F', 'files', '', _('file list'))
2804 ('F', 'files', '', _('file list'))
2839 ] + commitopts + commitopts2,
2805 ] + commitopts + commitopts2,
2840 _('hg debugrawcommit [OPTION]... [FILE]...')),
2806 _('hg debugrawcommit [OPTION]... [FILE]...')),
2841 "debugrebuildstate":
2807 "debugrebuildstate":
2842 (debugrebuildstate,
2808 (debugrebuildstate,
2843 [('r', 'rev', '', _('revision to rebuild to'))],
2809 [('r', 'rev', '', _('revision to rebuild to'))],
2844 _('hg debugrebuildstate [-r REV] [REV]')),
2810 _('hg debugrebuildstate [-r REV] [REV]')),
2845 "debugrename":
2811 "debugrename":
2846 (debugrename,
2812 (debugrename,
2847 [('r', 'rev', '', _('revision to debug'))],
2813 [('r', 'rev', '', _('revision to debug'))],
2848 _('hg debugrename [-r REV] FILE')),
2814 _('hg debugrename [-r REV] FILE')),
2849 "debugsetparents":
2815 "debugsetparents":
2850 (debugsetparents,
2816 (debugsetparents,
2851 [],
2817 [],
2852 _('hg debugsetparents REV1 [REV2]')),
2818 _('hg debugsetparents REV1 [REV2]')),
2853 "debugstate": (debugstate, [], _('hg debugstate')),
2819 "debugstate": (debugstate, [], _('hg debugstate')),
2854 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2820 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2855 "^diff":
2821 "^diff":
2856 (diff,
2822 (diff,
2857 [('r', 'rev', [], _('revision')),
2823 [('r', 'rev', [], _('revision')),
2858 ('a', 'text', None, _('treat all files as text')),
2824 ('a', 'text', None, _('treat all files as text')),
2859 ('p', 'show-function', None,
2825 ('p', 'show-function', None,
2860 _('show which function each change is in')),
2826 _('show which function each change is in')),
2861 ('g', 'git', None, _('use git extended diff format')),
2827 ('g', 'git', None, _('use git extended diff format')),
2862 ('', 'nodates', None, _("don't include dates in diff headers")),
2828 ('', 'nodates', None, _("don't include dates in diff headers")),
2863 ('w', 'ignore-all-space', None,
2829 ('w', 'ignore-all-space', None,
2864 _('ignore white space when comparing lines')),
2830 _('ignore white space when comparing lines')),
2865 ('b', 'ignore-space-change', None,
2831 ('b', 'ignore-space-change', None,
2866 _('ignore changes in the amount of white space')),
2832 _('ignore changes in the amount of white space')),
2867 ('B', 'ignore-blank-lines', None,
2833 ('B', 'ignore-blank-lines', None,
2868 _('ignore changes whose lines are all blank')),
2834 _('ignore changes whose lines are all blank')),
2869 ] + walkopts,
2835 ] + walkopts,
2870 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2836 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2871 "^export":
2837 "^export":
2872 (export,
2838 (export,
2873 [('o', 'output', '', _('print output to file with formatted name')),
2839 [('o', 'output', '', _('print output to file with formatted name')),
2874 ('a', 'text', None, _('treat all files as text')),
2840 ('a', 'text', None, _('treat all files as text')),
2875 ('g', 'git', None, _('use git extended diff format')),
2841 ('g', 'git', None, _('use git extended diff format')),
2876 ('', 'nodates', None, _("don't include dates in diff headers")),
2842 ('', 'nodates', None, _("don't include dates in diff headers")),
2877 ('', 'switch-parent', None, _('diff against the second parent'))],
2843 ('', 'switch-parent', None, _('diff against the second parent'))],
2878 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2844 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2879 "grep":
2845 "grep":
2880 (grep,
2846 (grep,
2881 [('0', 'print0', None, _('end fields with NUL')),
2847 [('0', 'print0', None, _('end fields with NUL')),
2882 ('', 'all', None, _('print all revisions that match')),
2848 ('', 'all', None, _('print all revisions that match')),
2883 ('f', 'follow', None,
2849 ('f', 'follow', None,
2884 _('follow changeset history, or file history across copies and renames')),
2850 _('follow changeset history, or file history across copies and renames')),
2885 ('i', 'ignore-case', None, _('ignore case when matching')),
2851 ('i', 'ignore-case', None, _('ignore case when matching')),
2886 ('l', 'files-with-matches', None,
2852 ('l', 'files-with-matches', None,
2887 _('print only filenames and revs that match')),
2853 _('print only filenames and revs that match')),
2888 ('n', 'line-number', None, _('print matching line numbers')),
2854 ('n', 'line-number', None, _('print matching line numbers')),
2889 ('r', 'rev', [], _('search in given revision range')),
2855 ('r', 'rev', [], _('search in given revision range')),
2890 ('u', 'user', None, _('print user who committed change')),
2856 ('u', 'user', None, _('print user who committed change')),
2891 ] + walkopts,
2857 ] + walkopts,
2892 _('hg grep [OPTION]... PATTERN [FILE]...')),
2858 _('hg grep [OPTION]... PATTERN [FILE]...')),
2893 "heads":
2859 "heads":
2894 (heads,
2860 (heads,
2895 [('', 'style', '', _('display using template map file')),
2861 [('', 'style', '', _('display using template map file')),
2896 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2862 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2897 ('', 'template', '', _('display with template'))],
2863 ('', 'template', '', _('display with template'))],
2898 _('hg heads [-r REV] [REV]...')),
2864 _('hg heads [-r REV] [REV]...')),
2899 "help": (help_, [], _('hg help [COMMAND]')),
2865 "help": (help_, [], _('hg help [COMMAND]')),
2900 "identify|id":
2866 "identify|id":
2901 (identify,
2867 (identify,
2902 [('r', 'rev', '', _('identify the specified rev')),
2868 [('r', 'rev', '', _('identify the specified rev')),
2903 ('n', 'num', None, _('show local revision number')),
2869 ('n', 'num', None, _('show local revision number')),
2904 ('i', 'id', None, _('show global revision id')),
2870 ('i', 'id', None, _('show global revision id')),
2905 ('b', 'branch', None, _('show branch')),
2871 ('b', 'branch', None, _('show branch')),
2906 ('t', 'tags', None, _('show tags'))],
2872 ('t', 'tags', None, _('show tags'))],
2907 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2873 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2908 "import|patch":
2874 "import|patch":
2909 (import_,
2875 (import_,
2910 [('p', 'strip', 1,
2876 [('p', 'strip', 1,
2911 _('directory strip option for patch. This has the same\n'
2877 _('directory strip option for patch. This has the same\n'
2912 'meaning as the corresponding patch option')),
2878 'meaning as the corresponding patch option')),
2913 ('b', 'base', '', _('base path')),
2879 ('b', 'base', '', _('base path')),
2914 ('f', 'force', None,
2880 ('f', 'force', None,
2915 _('skip check for outstanding uncommitted changes')),
2881 _('skip check for outstanding uncommitted changes')),
2916 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2882 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2917 ('', 'exact', None,
2883 ('', 'exact', None,
2918 _('apply patch to the nodes from which it was generated')),
2884 _('apply patch to the nodes from which it was generated')),
2919 ('', 'import-branch', None,
2885 ('', 'import-branch', None,
2920 _('Use any branch information in patch (implied by --exact)'))] +
2886 _('Use any branch information in patch (implied by --exact)'))] +
2921 commitopts + commitopts2,
2887 commitopts + commitopts2,
2922 _('hg import [OPTION]... PATCH...')),
2888 _('hg import [OPTION]... PATCH...')),
2923 "incoming|in":
2889 "incoming|in":
2924 (incoming,
2890 (incoming,
2925 [('M', 'no-merges', None, _('do not show merges')),
2891 [('M', 'no-merges', None, _('do not show merges')),
2926 ('f', 'force', None,
2892 ('f', 'force', None,
2927 _('run even when remote repository is unrelated')),
2893 _('run even when remote repository is unrelated')),
2928 ('', 'style', '', _('display using template map file')),
2894 ('', 'style', '', _('display using template map file')),
2929 ('n', 'newest-first', None, _('show newest record first')),
2895 ('n', 'newest-first', None, _('show newest record first')),
2930 ('', 'bundle', '', _('file to store the bundles into')),
2896 ('', 'bundle', '', _('file to store the bundles into')),
2931 ('p', 'patch', None, _('show patch')),
2897 ('p', 'patch', None, _('show patch')),
2932 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2898 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2933 ('', 'template', '', _('display with template')),
2899 ('', 'template', '', _('display with template')),
2934 ] + remoteopts,
2900 ] + remoteopts,
2935 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2901 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2936 ' [--bundle FILENAME] [SOURCE]')),
2902 ' [--bundle FILENAME] [SOURCE]')),
2937 "^init":
2903 "^init":
2938 (init,
2904 (init,
2939 remoteopts,
2905 remoteopts,
2940 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2906 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2941 "locate":
2907 "locate":
2942 (locate,
2908 (locate,
2943 [('r', 'rev', '', _('search the repository as it stood at rev')),
2909 [('r', 'rev', '', _('search the repository as it stood at rev')),
2944 ('0', 'print0', None,
2910 ('0', 'print0', None,
2945 _('end filenames with NUL, for use with xargs')),
2911 _('end filenames with NUL, for use with xargs')),
2946 ('f', 'fullpath', None,
2912 ('f', 'fullpath', None,
2947 _('print complete paths from the filesystem root')),
2913 _('print complete paths from the filesystem root')),
2948 ] + walkopts,
2914 ] + walkopts,
2949 _('hg locate [OPTION]... [PATTERN]...')),
2915 _('hg locate [OPTION]... [PATTERN]...')),
2950 "^log|history":
2916 "^log|history":
2951 (log,
2917 (log,
2952 [('f', 'follow', None,
2918 [('f', 'follow', None,
2953 _('follow changeset history, or file history across copies and renames')),
2919 _('follow changeset history, or file history across copies and renames')),
2954 ('', 'follow-first', None,
2920 ('', 'follow-first', None,
2955 _('only follow the first parent of merge changesets')),
2921 _('only follow the first parent of merge changesets')),
2956 ('d', 'date', '', _('show revs matching date spec')),
2922 ('d', 'date', '', _('show revs matching date spec')),
2957 ('C', 'copies', None, _('show copied files')),
2923 ('C', 'copies', None, _('show copied files')),
2958 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2924 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2959 ('l', 'limit', '', _('limit number of changes displayed')),
2925 ('l', 'limit', '', _('limit number of changes displayed')),
2960 ('r', 'rev', [], _('show the specified revision or range')),
2926 ('r', 'rev', [], _('show the specified revision or range')),
2961 ('', 'removed', None, _('include revs where files were removed')),
2927 ('', 'removed', None, _('include revs where files were removed')),
2962 ('M', 'no-merges', None, _('do not show merges')),
2928 ('M', 'no-merges', None, _('do not show merges')),
2963 ('', 'style', '', _('display using template map file')),
2929 ('', 'style', '', _('display using template map file')),
2964 ('m', 'only-merges', None, _('show only merges')),
2930 ('m', 'only-merges', None, _('show only merges')),
2965 ('p', 'patch', None, _('show patch')),
2931 ('p', 'patch', None, _('show patch')),
2966 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2932 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2967 ('', 'template', '', _('display with template')),
2933 ('', 'template', '', _('display with template')),
2968 ] + walkopts,
2934 ] + walkopts,
2969 _('hg log [OPTION]... [FILE]')),
2935 _('hg log [OPTION]... [FILE]')),
2970 "manifest":
2936 "manifest":
2971 (manifest,
2937 (manifest,
2972 [('r', 'rev', '', _('revision to display'))],
2938 [('r', 'rev', '', _('revision to display'))],
2973 _('hg manifest [-r REV]')),
2939 _('hg manifest [-r REV]')),
2974 "^merge":
2940 "^merge":
2975 (merge,
2941 (merge,
2976 [('f', 'force', None, _('force a merge with outstanding changes')),
2942 [('f', 'force', None, _('force a merge with outstanding changes')),
2977 ('r', 'rev', '', _('revision to merge')),
2943 ('r', 'rev', '', _('revision to merge')),
2978 ],
2944 ],
2979 _('hg merge [-f] [[-r] REV]')),
2945 _('hg merge [-f] [[-r] REV]')),
2980 "outgoing|out":
2946 "outgoing|out":
2981 (outgoing,
2947 (outgoing,
2982 [('M', 'no-merges', None, _('do not show merges')),
2948 [('M', 'no-merges', None, _('do not show merges')),
2983 ('f', 'force', None,
2949 ('f', 'force', None,
2984 _('run even when remote repository is unrelated')),
2950 _('run even when remote repository is unrelated')),
2985 ('p', 'patch', None, _('show patch')),
2951 ('p', 'patch', None, _('show patch')),
2986 ('', 'style', '', _('display using template map file')),
2952 ('', 'style', '', _('display using template map file')),
2987 ('r', 'rev', [], _('a specific revision you would like to push')),
2953 ('r', 'rev', [], _('a specific revision you would like to push')),
2988 ('n', 'newest-first', None, _('show newest record first')),
2954 ('n', 'newest-first', None, _('show newest record first')),
2989 ('', 'template', '', _('display with template')),
2955 ('', 'template', '', _('display with template')),
2990 ] + remoteopts,
2956 ] + remoteopts,
2991 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2957 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2992 "^parents":
2958 "^parents":
2993 (parents,
2959 (parents,
2994 [('r', 'rev', '', _('show parents from the specified rev')),
2960 [('r', 'rev', '', _('show parents from the specified rev')),
2995 ('', 'style', '', _('display using template map file')),
2961 ('', 'style', '', _('display using template map file')),
2996 ('', 'template', '', _('display with template'))],
2962 ('', 'template', '', _('display with template'))],
2997 _('hg parents [-r REV] [FILE]')),
2963 _('hg parents [-r REV] [FILE]')),
2998 "paths": (paths, [], _('hg paths [NAME]')),
2964 "paths": (paths, [], _('hg paths [NAME]')),
2999 "^pull":
2965 "^pull":
3000 (pull,
2966 (pull,
3001 [('u', 'update', None,
2967 [('u', 'update', None,
3002 _('update to new tip if changesets were pulled')),
2968 _('update to new tip if changesets were pulled')),
3003 ('f', 'force', None,
2969 ('f', 'force', None,
3004 _('run even when remote repository is unrelated')),
2970 _('run even when remote repository is unrelated')),
3005 ('r', 'rev', [],
2971 ('r', 'rev', [],
3006 _('a specific revision up to which you would like to pull')),
2972 _('a specific revision up to which you would like to pull')),
3007 ] + remoteopts,
2973 ] + remoteopts,
3008 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
2974 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
3009 "^push":
2975 "^push":
3010 (push,
2976 (push,
3011 [('f', 'force', None, _('force push')),
2977 [('f', 'force', None, _('force push')),
3012 ('r', 'rev', [], _('a specific revision you would like to push')),
2978 ('r', 'rev', [], _('a specific revision you would like to push')),
3013 ] + remoteopts,
2979 ] + remoteopts,
3014 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
2980 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3015 "recover": (recover, [], _('hg recover')),
2981 "recover": (recover, [], _('hg recover')),
3016 "^remove|rm":
2982 "^remove|rm":
3017 (remove,
2983 (remove,
3018 [('A', 'after', None, _('record remove without deleting')),
2984 [('A', 'after', None, _('record remove without deleting')),
3019 ('f', 'force', None, _('remove file even if modified')),
2985 ('f', 'force', None, _('remove file even if modified')),
3020 ] + walkopts,
2986 ] + walkopts,
3021 _('hg remove [OPTION]... FILE...')),
2987 _('hg remove [OPTION]... FILE...')),
3022 "rename|mv":
2988 "rename|mv":
3023 (rename,
2989 (rename,
3024 [('A', 'after', None, _('record a rename that has already occurred')),
2990 [('A', 'after', None, _('record a rename that has already occurred')),
3025 ('f', 'force', None,
2991 ('f', 'force', None,
3026 _('forcibly copy over an existing managed file')),
2992 _('forcibly copy over an existing managed file')),
3027 ] + walkopts + dryrunopts,
2993 ] + walkopts + dryrunopts,
3028 _('hg rename [OPTION]... SOURCE... DEST')),
2994 _('hg rename [OPTION]... SOURCE... DEST')),
3029 "revert":
2995 "revert":
3030 (revert,
2996 (revert,
3031 [('a', 'all', None, _('revert all changes when no arguments given')),
2997 [('a', 'all', None, _('revert all changes when no arguments given')),
3032 ('d', 'date', '', _('tipmost revision matching date')),
2998 ('d', 'date', '', _('tipmost revision matching date')),
3033 ('r', 'rev', '', _('revision to revert to')),
2999 ('r', 'rev', '', _('revision to revert to')),
3034 ('', 'no-backup', None, _('do not save backup copies of files')),
3000 ('', 'no-backup', None, _('do not save backup copies of files')),
3035 ] + walkopts + dryrunopts,
3001 ] + walkopts + dryrunopts,
3036 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3002 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3037 "rollback": (rollback, [], _('hg rollback')),
3003 "rollback": (rollback, [], _('hg rollback')),
3038 "root": (root, [], _('hg root')),
3004 "root": (root, [], _('hg root')),
3039 "^serve":
3005 "^serve":
3040 (serve,
3006 (serve,
3041 [('A', 'accesslog', '', _('name of access log file to write to')),
3007 [('A', 'accesslog', '', _('name of access log file to write to')),
3042 ('d', 'daemon', None, _('run server in background')),
3008 ('d', 'daemon', None, _('run server in background')),
3043 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3009 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3044 ('E', 'errorlog', '', _('name of error log file to write to')),
3010 ('E', 'errorlog', '', _('name of error log file to write to')),
3045 ('p', 'port', 0, _('port to use (default: 8000)')),
3011 ('p', 'port', 0, _('port to use (default: 8000)')),
3046 ('a', 'address', '', _('address to use')),
3012 ('a', 'address', '', _('address to use')),
3047 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3013 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3048 ('n', 'name', '',
3014 ('n', 'name', '',
3049 _('name to show in web pages (default: working dir)')),
3015 _('name to show in web pages (default: working dir)')),
3050 ('', 'webdir-conf', '', _('name of the webdir config file'
3016 ('', 'webdir-conf', '', _('name of the webdir config file'
3051 ' (serve more than one repo)')),
3017 ' (serve more than one repo)')),
3052 ('', 'pid-file', '', _('name of file to write process ID to')),
3018 ('', 'pid-file', '', _('name of file to write process ID to')),
3053 ('', 'stdio', None, _('for remote clients')),
3019 ('', 'stdio', None, _('for remote clients')),
3054 ('t', 'templates', '', _('web templates to use')),
3020 ('t', 'templates', '', _('web templates to use')),
3055 ('', 'style', '', _('template style to use')),
3021 ('', 'style', '', _('template style to use')),
3056 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3022 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3057 ('', 'certificate', '', _('SSL certificate file'))],
3023 ('', 'certificate', '', _('SSL certificate file'))],
3058 _('hg serve [OPTION]...')),
3024 _('hg serve [OPTION]...')),
3059 "showconfig|debugconfig":
3025 "showconfig|debugconfig":
3060 (showconfig,
3026 (showconfig,
3061 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3027 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3062 _('hg showconfig [-u] [NAME]...')),
3028 _('hg showconfig [-u] [NAME]...')),
3063 "^status|st":
3029 "^status|st":
3064 (status,
3030 (status,
3065 [('A', 'all', None, _('show status of all files')),
3031 [('A', 'all', None, _('show status of all files')),
3066 ('m', 'modified', None, _('show only modified files')),
3032 ('m', 'modified', None, _('show only modified files')),
3067 ('a', 'added', None, _('show only added files')),
3033 ('a', 'added', None, _('show only added files')),
3068 ('r', 'removed', None, _('show only removed files')),
3034 ('r', 'removed', None, _('show only removed files')),
3069 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3035 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3070 ('c', 'clean', None, _('show only files without changes')),
3036 ('c', 'clean', None, _('show only files without changes')),
3071 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3037 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3072 ('i', 'ignored', None, _('show only ignored files')),
3038 ('i', 'ignored', None, _('show only ignored files')),
3073 ('n', 'no-status', None, _('hide status prefix')),
3039 ('n', 'no-status', None, _('hide status prefix')),
3074 ('C', 'copies', None, _('show source of copied files')),
3040 ('C', 'copies', None, _('show source of copied files')),
3075 ('0', 'print0', None,
3041 ('0', 'print0', None,
3076 _('end filenames with NUL, for use with xargs')),
3042 _('end filenames with NUL, for use with xargs')),
3077 ('', 'rev', [], _('show difference from revision')),
3043 ('', 'rev', [], _('show difference from revision')),
3078 ] + walkopts,
3044 ] + walkopts,
3079 _('hg status [OPTION]... [FILE]...')),
3045 _('hg status [OPTION]... [FILE]...')),
3080 "tag":
3046 "tag":
3081 (tag,
3047 (tag,
3082 [('f', 'force', None, _('replace existing tag')),
3048 [('f', 'force', None, _('replace existing tag')),
3083 ('l', 'local', None, _('make the tag local')),
3049 ('l', 'local', None, _('make the tag local')),
3084 ('r', 'rev', '', _('revision to tag')),
3050 ('r', 'rev', '', _('revision to tag')),
3085 ('', 'remove', None, _('remove a tag')),
3051 ('', 'remove', None, _('remove a tag')),
3086 # -l/--local is already there, commitopts cannot be used
3052 # -l/--local is already there, commitopts cannot be used
3087 ('m', 'message', '', _('use <text> as commit message')),
3053 ('m', 'message', '', _('use <text> as commit message')),
3088 ] + commitopts2,
3054 ] + commitopts2,
3089 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3055 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3090 "tags": (tags, [], _('hg tags')),
3056 "tags": (tags, [], _('hg tags')),
3091 "tip":
3057 "tip":
3092 (tip,
3058 (tip,
3093 [('', 'style', '', _('display using template map file')),
3059 [('', 'style', '', _('display using template map file')),
3094 ('p', 'patch', None, _('show patch')),
3060 ('p', 'patch', None, _('show patch')),
3095 ('', 'template', '', _('display with template'))],
3061 ('', 'template', '', _('display with template'))],
3096 _('hg tip [-p]')),
3062 _('hg tip [-p]')),
3097 "unbundle":
3063 "unbundle":
3098 (unbundle,
3064 (unbundle,
3099 [('u', 'update', None,
3065 [('u', 'update', None,
3100 _('update to new tip if changesets were unbundled'))],
3066 _('update to new tip if changesets were unbundled'))],
3101 _('hg unbundle [-u] FILE...')),
3067 _('hg unbundle [-u] FILE...')),
3102 "^update|up|checkout|co":
3068 "^update|up|checkout|co":
3103 (update,
3069 (update,
3104 [('C', 'clean', None, _('overwrite locally modified files')),
3070 [('C', 'clean', None, _('overwrite locally modified files')),
3105 ('d', 'date', '', _('tipmost revision matching date')),
3071 ('d', 'date', '', _('tipmost revision matching date')),
3106 ('r', 'rev', '', _('revision'))],
3072 ('r', 'rev', '', _('revision'))],
3107 _('hg update [-C] [-d DATE] [[-r] REV]')),
3073 _('hg update [-C] [-d DATE] [[-r] REV]')),
3108 "verify": (verify, [], _('hg verify')),
3074 "verify": (verify, [], _('hg verify')),
3109 "version": (version_, [], _('hg version')),
3075 "version": (version_, [], _('hg version')),
3110 }
3076 }
3111
3077
3112 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3078 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3113 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3079 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3114 optionalrepo = ("identify paths serve showconfig")
3080 optionalrepo = ("identify paths serve showconfig")
@@ -1,65 +1,168 b''
1 # filemerge.py - file-level merge handling for Mercurial
1 # filemerge.py - file-level merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from i18n import _
9 from i18n import _
10 import util, os, tempfile, context
10 import util, os, tempfile, context, simplemerge, re
11
12 def _toolstr(ui, tool, part, default=None):
13 return ui.config("merge-tools", tool + "." + part, default)
14
15 def _toolbool(ui, tool, part, default=False):
16 return ui.configbool("merge-tools", tool + "." + part, default)
17
18 def _findtool(ui, tool):
19 return util.find_exe(_toolstr(ui, tool, "executable", tool))
20
21 def _picktool(repo, ui, path, binary, symlink):
22 def check(tool, pat, symlink, binary):
23 tmsg = tool
24 if pat:
25 tmsg += " specified for " + pat
26 if pat and not _findtool(ui, tool): # skip search if not matching
27 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
28 elif symlink and not _toolbool(ui, tool, "symlink"):
29 ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
30 elif binary and not _toolbool(ui, tool, "binary"):
31 ui.warn(_("tool %s can't handle binary\n") % tmsg)
32 else:
33 return True
34 return False
35
36 # HGMERGE takes precedence
37 if os.environ.get("HGMERGE"):
38 return os.environ.get("HGMERGE")
39
40 # then patterns
41 for pattern, tool in ui.configitems("merge-patterns"):
42 mf = util.matcher(repo.root, "", [pat], [], [])[1]
43 if mf(path) and check(tool, pat, symlink, False):
44 return tool
45
46 # then merge tools
47 tools = {}
48 for k,v in ui.configitems("merge-tools"):
49 t = k.split('.')[0]
50 if t not in tools:
51 tools[t] = int(_toolstr(ui, t, "priority", "0"))
52 tools = [(-p,t) for t,p in tools.items()]
53 tools.sort()
54 if ui.config("ui", "merge"):
55 tools.insert(0, (None, ui.config("ui", "merge"))) # highest priority
56 tools.append((None, "hgmerge")) # the old default, if found
57 tools.append((None, "internal:merge")) # internal merge as last resort
58 for p,t in tools:
59 if _findtool(ui, t) and check(t, None, symlink, binary):
60 return t
11
61
12 def filemerge(repo, fw, fd, fo, wctx, mctx):
62 def filemerge(repo, fw, fd, fo, wctx, mctx):
13 """perform a 3-way merge in the working directory
63 """perform a 3-way merge in the working directory
14
64
15 fw = original filename in the working directory
65 fw = original filename in the working directory
16 fd = destination filename in the working directory
66 fd = destination filename in the working directory
17 fo = filename in other parent
67 fo = filename in other parent
18 wctx, mctx = working and merge changecontexts
68 wctx, mctx = working and merge changecontexts
19 """
69 """
20
70
21 def temp(prefix, ctx):
71 def temp(prefix, ctx):
22 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
72 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
23 (fd, name) = tempfile.mkstemp(prefix=pre)
73 (fd, name) = tempfile.mkstemp(prefix=pre)
24 data = repo.wwritedata(ctx.path(), ctx.data())
74 data = repo.wwritedata(ctx.path(), ctx.data())
25 f = os.fdopen(fd, "wb")
75 f = os.fdopen(fd, "wb")
26 f.write(data)
76 f.write(data)
27 f.close()
77 f.close()
28 return name
78 return name
29
79
30 fcm = wctx.filectx(fw)
80 def isbin(ctx):
31 fcmdata = wctx.filectx(fd).data()
81 try:
82 return util.binary(ctx.data())
83 except IOError:
84 return False
85
32 fco = mctx.filectx(fo)
86 fco = mctx.filectx(fo)
33
87 if not fco.cmp(wctx.filectx(fd).data()): # files identical?
34 if not fco.cmp(fcmdata): # files identical?
35 return None
88 return None
36
89
37 fca = fcm.ancestor(fco)
90 ui = repo.ui
38 if not fca:
91 fcm = wctx.filectx(fw)
39 fca = repo.filectx(fw, fileid=nullrev)
92 fca = fcm.ancestor(fco) or repo.filectx(fw, fileid=nullrev)
93 binary = isbin(fcm) or isbin(fco) or isbin(fca)
94 symlink = fcm.islink() or fco.islink()
95 tool = _picktool(repo, ui, fw, binary, symlink)
96 ui.debug(_("picked tool '%s' for %s (binary %s symlink %s)\n") %
97 (tool, fw, binary, symlink))
98
99 if not tool:
100 tool = "internal:local"
101 if ui.prompt(_(" no tool found to merge %s\n"
102 "keep (l)ocal or take (o)ther?") % fw,
103 _("[lo]"), _("l")) != _("l"):
104 tool = "internal:other"
105 if tool == "internal:local":
106 return 0
107 if tool == "internal:other":
108 repo.wwrite(fd, fco.data(), fco.fileflags())
109 return 0
110 if tool == "internal:fail":
111 return 1
112
113 # do the actual merge
40 a = repo.wjoin(fd)
114 a = repo.wjoin(fd)
41 b = temp("base", fca)
115 b = temp("base", fca)
42 c = temp("other", fco)
116 c = temp("other", fco)
117 out = ""
118 back = a + ".orig"
119 util.copyfile(a, back)
43
120
44 if fw != fo:
121 if fw != fo:
45 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
122 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
46 else:
123 else:
47 repo.ui.status(_("merging %s\n") % fw)
124 repo.ui.status(_("merging %s\n") % fw)
48
49 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
125 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
50
126
51 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
127 # do we attempt to simplemerge first?
52 or "hgmerge")
128 if _toolbool(ui, tool, "premerge", not (binary or symlink)):
53 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
129 r = simplemerge.simplemerge(a, b, c, quiet=True)
54 environ={'HG_FILE': fd,
130 if not r:
55 'HG_MY_NODE': str(wctx.parents()[0]),
131 ui.debug(_(" premerge successful\n"))
56 'HG_OTHER_NODE': str(mctx),
132 os.unlink(back)
57 'HG_MY_ISLINK': fcm.islink(),
133 os.unlink(b)
58 'HG_OTHER_ISLINK': fco.islink(),
134 os.unlink(c)
59 'HG_BASE_ISLINK': fca.islink(),})
135 return 0
136 util.copyfile(back, a) # restore from backup and try again
137
138 env = dict(HG_FILE=fd,
139 HG_MY_NODE=str(wctx.parents()[0]),
140 HG_OTHER_NODE=str(mctx),
141 HG_MY_ISLINK=fcm.islink(),
142 HG_OTHER_ISLINK=fco.islink(),
143 HG_BASE_ISLINK=fca.islink())
144
145 if tool == "internal:merge":
146 r = simplemerge.simplemerge(a, b, c, label=['local', 'other'])
147 else:
148 toolpath = _findtool(ui, tool)
149 args = _toolstr(ui, tool, "args", '$local $base $other')
150 if "$output" in args:
151 out, a = a, back # read input from backup, write to original
152 replace = dict(local=a, base=b, other=c, output=out)
153 args = re.sub("\$(local|base|other|output)",
154 lambda x: '"%s"' % replace[x.group()[1:]], args)
155 r = util.system(toolpath + ' ' + args, cwd=repo.root, environ=env)
156
157 if not r and _toolbool(ui, tool, "checkconflicts"):
158 if re.match("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcm.data()):
159 r = 1
160
60 if r:
161 if r:
61 repo.ui.warn(_("merging %s failed!\n") % fd)
162 repo.ui.warn(_("merging %s failed!\n") % fd)
163 else:
164 os.unlink(back)
62
165
63 os.unlink(b)
166 os.unlink(b)
64 os.unlink(c)
167 os.unlink(c)
65 return r
168 return r
@@ -1,590 +1,588 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # run-tests.py - Run a set of tests on Mercurial
3 # run-tests.py - Run a set of tests on Mercurial
4 #
4 #
5 # Copyright 2006 Matt Mackall <mpm@selenic.com>
5 # Copyright 2006 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms
7 # This software may be used and distributed according to the terms
8 # of the GNU General Public License, incorporated herein by reference.
8 # of the GNU General Public License, incorporated herein by reference.
9
9
10 import difflib
10 import difflib
11 import errno
11 import errno
12 import optparse
12 import optparse
13 import os
13 import os
14 import popen2
14 import popen2
15 import re
15 import re
16 import shutil
16 import shutil
17 import signal
17 import signal
18 import sys
18 import sys
19 import tempfile
19 import tempfile
20 import time
20 import time
21
21
22 # reserved exit code to skip test (used by hghave)
22 # reserved exit code to skip test (used by hghave)
23 SKIPPED_STATUS = 80
23 SKIPPED_STATUS = 80
24 SKIPPED_PREFIX = 'skipped: '
24 SKIPPED_PREFIX = 'skipped: '
25
25
26 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
26 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
27
27
28 parser = optparse.OptionParser("%prog [options] [tests]")
28 parser = optparse.OptionParser("%prog [options] [tests]")
29 parser.add_option("-C", "--annotate", action="store_true",
29 parser.add_option("-C", "--annotate", action="store_true",
30 help="output files annotated with coverage")
30 help="output files annotated with coverage")
31 parser.add_option("--child", type="int",
31 parser.add_option("--child", type="int",
32 help="run as child process, summary to given fd")
32 help="run as child process, summary to given fd")
33 parser.add_option("-c", "--cover", action="store_true",
33 parser.add_option("-c", "--cover", action="store_true",
34 help="print a test coverage report")
34 help="print a test coverage report")
35 parser.add_option("-f", "--first", action="store_true",
35 parser.add_option("-f", "--first", action="store_true",
36 help="exit on the first test failure")
36 help="exit on the first test failure")
37 parser.add_option("-i", "--interactive", action="store_true",
37 parser.add_option("-i", "--interactive", action="store_true",
38 help="prompt to accept changed output")
38 help="prompt to accept changed output")
39 parser.add_option("-j", "--jobs", type="int",
39 parser.add_option("-j", "--jobs", type="int",
40 help="number of jobs to run in parallel")
40 help="number of jobs to run in parallel")
41 parser.add_option("-R", "--restart", action="store_true",
41 parser.add_option("-R", "--restart", action="store_true",
42 help="restart at last error")
42 help="restart at last error")
43 parser.add_option("-p", "--port", type="int",
43 parser.add_option("-p", "--port", type="int",
44 help="port on which servers should listen")
44 help="port on which servers should listen")
45 parser.add_option("-r", "--retest", action="store_true",
45 parser.add_option("-r", "--retest", action="store_true",
46 help="retest failed tests")
46 help="retest failed tests")
47 parser.add_option("-s", "--cover_stdlib", action="store_true",
47 parser.add_option("-s", "--cover_stdlib", action="store_true",
48 help="print a test coverage report inc. standard libraries")
48 help="print a test coverage report inc. standard libraries")
49 parser.add_option("-t", "--timeout", type="int",
49 parser.add_option("-t", "--timeout", type="int",
50 help="kill errant tests after TIMEOUT seconds")
50 help="kill errant tests after TIMEOUT seconds")
51 parser.add_option("--tmpdir", type="string",
51 parser.add_option("--tmpdir", type="string",
52 help="run tests in the given temporary directory")
52 help="run tests in the given temporary directory")
53 parser.add_option("-v", "--verbose", action="store_true",
53 parser.add_option("-v", "--verbose", action="store_true",
54 help="output verbose messages")
54 help="output verbose messages")
55 parser.add_option("--with-hg", type="string",
55 parser.add_option("--with-hg", type="string",
56 help="test existing install at given location")
56 help="test existing install at given location")
57
57
58 parser.set_defaults(jobs=1, port=20059, timeout=180)
58 parser.set_defaults(jobs=1, port=20059, timeout=180)
59 (options, args) = parser.parse_args()
59 (options, args) = parser.parse_args()
60 verbose = options.verbose
60 verbose = options.verbose
61 coverage = options.cover or options.cover_stdlib or options.annotate
61 coverage = options.cover or options.cover_stdlib or options.annotate
62 python = sys.executable
62 python = sys.executable
63
63
64 if options.jobs < 1:
64 if options.jobs < 1:
65 print >> sys.stderr, 'ERROR: -j/--jobs must be positive'
65 print >> sys.stderr, 'ERROR: -j/--jobs must be positive'
66 sys.exit(1)
66 sys.exit(1)
67 if options.interactive and options.jobs > 1:
67 if options.interactive and options.jobs > 1:
68 print >> sys.stderr, 'ERROR: cannot mix -interactive and --jobs > 1'
68 print >> sys.stderr, 'ERROR: cannot mix -interactive and --jobs > 1'
69 sys.exit(1)
69 sys.exit(1)
70
70
71 def rename(src, dst):
71 def rename(src, dst):
72 """Like os.rename(), trade atomicity and opened files friendliness
72 """Like os.rename(), trade atomicity and opened files friendliness
73 for existing destination support.
73 for existing destination support.
74 """
74 """
75 shutil.copy(src, dst)
75 shutil.copy(src, dst)
76 os.remove(src)
76 os.remove(src)
77
77
78 def vlog(*msg):
78 def vlog(*msg):
79 if verbose:
79 if verbose:
80 for m in msg:
80 for m in msg:
81 print m,
81 print m,
82 print
82 print
83
83
84 def splitnewlines(text):
84 def splitnewlines(text):
85 '''like str.splitlines, but only split on newlines.
85 '''like str.splitlines, but only split on newlines.
86 keep line endings.'''
86 keep line endings.'''
87 i = 0
87 i = 0
88 lines = []
88 lines = []
89 while True:
89 while True:
90 n = text.find('\n', i)
90 n = text.find('\n', i)
91 if n == -1:
91 if n == -1:
92 last = text[i:]
92 last = text[i:]
93 if last:
93 if last:
94 lines.append(last)
94 lines.append(last)
95 return lines
95 return lines
96 lines.append(text[i:n+1])
96 lines.append(text[i:n+1])
97 i = n + 1
97 i = n + 1
98
98
99 def extract_missing_features(lines):
99 def extract_missing_features(lines):
100 '''Extract missing/unknown features log lines as a list'''
100 '''Extract missing/unknown features log lines as a list'''
101 missing = []
101 missing = []
102 for line in lines:
102 for line in lines:
103 if not line.startswith(SKIPPED_PREFIX):
103 if not line.startswith(SKIPPED_PREFIX):
104 continue
104 continue
105 line = line.splitlines()[0]
105 line = line.splitlines()[0]
106 missing.append(line[len(SKIPPED_PREFIX):])
106 missing.append(line[len(SKIPPED_PREFIX):])
107
107
108 return missing
108 return missing
109
109
110 def show_diff(expected, output):
110 def show_diff(expected, output):
111 for line in difflib.unified_diff(expected, output,
111 for line in difflib.unified_diff(expected, output,
112 "Expected output", "Test output"):
112 "Expected output", "Test output"):
113 sys.stdout.write(line)
113 sys.stdout.write(line)
114
114
115 def find_program(program):
115 def find_program(program):
116 """Search PATH for a executable program"""
116 """Search PATH for a executable program"""
117 for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
117 for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
118 name = os.path.join(p, program)
118 name = os.path.join(p, program)
119 if os.access(name, os.X_OK):
119 if os.access(name, os.X_OK):
120 return name
120 return name
121 return None
121 return None
122
122
123 def check_required_tools():
123 def check_required_tools():
124 # Before we go any further, check for pre-requisite tools
124 # Before we go any further, check for pre-requisite tools
125 # stuff from coreutils (cat, rm, etc) are not tested
125 # stuff from coreutils (cat, rm, etc) are not tested
126 for p in required_tools:
126 for p in required_tools:
127 if os.name == 'nt':
127 if os.name == 'nt':
128 p += '.exe'
128 p += '.exe'
129 found = find_program(p)
129 found = find_program(p)
130 if found:
130 if found:
131 vlog("# Found prerequisite", p, "at", found)
131 vlog("# Found prerequisite", p, "at", found)
132 else:
132 else:
133 print "WARNING: Did not find prerequisite tool: "+p
133 print "WARNING: Did not find prerequisite tool: "+p
134
134
135 def cleanup_exit():
135 def cleanup_exit():
136 if verbose:
136 if verbose:
137 print "# Cleaning up HGTMP", HGTMP
137 print "# Cleaning up HGTMP", HGTMP
138 shutil.rmtree(HGTMP, True)
138 shutil.rmtree(HGTMP, True)
139
139
140 def use_correct_python():
140 def use_correct_python():
141 # some tests run python interpreter. they must use same
141 # some tests run python interpreter. they must use same
142 # interpreter we use or bad things will happen.
142 # interpreter we use or bad things will happen.
143 exedir, exename = os.path.split(sys.executable)
143 exedir, exename = os.path.split(sys.executable)
144 if exename == 'python':
144 if exename == 'python':
145 path = find_program('python')
145 path = find_program('python')
146 if os.path.dirname(path) == exedir:
146 if os.path.dirname(path) == exedir:
147 return
147 return
148 vlog('# Making python executable in test path use correct Python')
148 vlog('# Making python executable in test path use correct Python')
149 my_python = os.path.join(BINDIR, 'python')
149 my_python = os.path.join(BINDIR, 'python')
150 try:
150 try:
151 os.symlink(sys.executable, my_python)
151 os.symlink(sys.executable, my_python)
152 except AttributeError:
152 except AttributeError:
153 # windows fallback
153 # windows fallback
154 shutil.copyfile(sys.executable, my_python)
154 shutil.copyfile(sys.executable, my_python)
155 shutil.copymode(sys.executable, my_python)
155 shutil.copymode(sys.executable, my_python)
156
156
157 def install_hg():
157 def install_hg():
158 global python
158 global python
159 vlog("# Performing temporary installation of HG")
159 vlog("# Performing temporary installation of HG")
160 installerrs = os.path.join("tests", "install.err")
160 installerrs = os.path.join("tests", "install.err")
161
161
162 # Run installer in hg root
162 # Run installer in hg root
163 os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..'))
163 os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..'))
164 cmd = ('%s setup.py clean --all'
164 cmd = ('%s setup.py clean --all'
165 ' install --force --home="%s" --install-lib="%s"'
165 ' install --force --home="%s" --install-lib="%s"'
166 ' --install-scripts="%s" >%s 2>&1'
166 ' --install-scripts="%s" >%s 2>&1'
167 % (sys.executable, INST, PYTHONDIR, BINDIR, installerrs))
167 % (sys.executable, INST, PYTHONDIR, BINDIR, installerrs))
168 vlog("# Running", cmd)
168 vlog("# Running", cmd)
169 if os.system(cmd) == 0:
169 if os.system(cmd) == 0:
170 if not verbose:
170 if not verbose:
171 os.remove(installerrs)
171 os.remove(installerrs)
172 else:
172 else:
173 f = open(installerrs)
173 f = open(installerrs)
174 for line in f:
174 for line in f:
175 print line,
175 print line,
176 f.close()
176 f.close()
177 sys.exit(1)
177 sys.exit(1)
178 os.chdir(TESTDIR)
178 os.chdir(TESTDIR)
179
179
180 os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
180 os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
181
181
182 pydir = os.pathsep.join([PYTHONDIR, TESTDIR])
182 pydir = os.pathsep.join([PYTHONDIR, TESTDIR])
183 pythonpath = os.environ.get("PYTHONPATH")
183 pythonpath = os.environ.get("PYTHONPATH")
184 if pythonpath:
184 if pythonpath:
185 pythonpath = pydir + os.pathsep + pythonpath
185 pythonpath = pydir + os.pathsep + pythonpath
186 else:
186 else:
187 pythonpath = pydir
187 pythonpath = pydir
188 os.environ["PYTHONPATH"] = pythonpath
188 os.environ["PYTHONPATH"] = pythonpath
189
189
190 use_correct_python()
190 use_correct_python()
191
191
192 if coverage:
192 if coverage:
193 vlog("# Installing coverage wrapper")
193 vlog("# Installing coverage wrapper")
194 os.environ['COVERAGE_FILE'] = COVERAGE_FILE
194 os.environ['COVERAGE_FILE'] = COVERAGE_FILE
195 if os.path.exists(COVERAGE_FILE):
195 if os.path.exists(COVERAGE_FILE):
196 os.unlink(COVERAGE_FILE)
196 os.unlink(COVERAGE_FILE)
197 # Create a wrapper script to invoke hg via coverage.py
197 # Create a wrapper script to invoke hg via coverage.py
198 os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
198 os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
199 f = open(os.path.join(BINDIR, 'hg'), 'w')
199 f = open(os.path.join(BINDIR, 'hg'), 'w')
200 f.write('#!' + sys.executable + '\n')
200 f.write('#!' + sys.executable + '\n')
201 f.write('import sys, os; os.execv(sys.executable, [sys.executable, '
201 f.write('import sys, os; os.execv(sys.executable, [sys.executable, '
202 '"%s", "-x", "%s"] + sys.argv[1:])\n' %
202 '"%s", "-x", "%s"] + sys.argv[1:])\n' %
203 (os.path.join(TESTDIR, 'coverage.py'),
203 (os.path.join(TESTDIR, 'coverage.py'),
204 os.path.join(BINDIR, '_hg.py')))
204 os.path.join(BINDIR, '_hg.py')))
205 f.close()
205 f.close()
206 os.chmod(os.path.join(BINDIR, 'hg'), 0700)
206 os.chmod(os.path.join(BINDIR, 'hg'), 0700)
207 python = '"%s" "%s" -x' % (sys.executable,
207 python = '"%s" "%s" -x' % (sys.executable,
208 os.path.join(TESTDIR,'coverage.py'))
208 os.path.join(TESTDIR,'coverage.py'))
209
209
210 def output_coverage():
210 def output_coverage():
211 vlog("# Producing coverage report")
211 vlog("# Producing coverage report")
212 omit = [BINDIR, TESTDIR, PYTHONDIR]
212 omit = [BINDIR, TESTDIR, PYTHONDIR]
213 if not options.cover_stdlib:
213 if not options.cover_stdlib:
214 # Exclude as system paths (ignoring empty strings seen on win)
214 # Exclude as system paths (ignoring empty strings seen on win)
215 omit += [x for x in sys.path if x != '']
215 omit += [x for x in sys.path if x != '']
216 omit = ','.join(omit)
216 omit = ','.join(omit)
217 os.chdir(PYTHONDIR)
217 os.chdir(PYTHONDIR)
218 cmd = '"%s" "%s" -i -r "--omit=%s"' % (
218 cmd = '"%s" "%s" -i -r "--omit=%s"' % (
219 sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
219 sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
220 vlog("# Running: "+cmd)
220 vlog("# Running: "+cmd)
221 os.system(cmd)
221 os.system(cmd)
222 if options.annotate:
222 if options.annotate:
223 adir = os.path.join(TESTDIR, 'annotated')
223 adir = os.path.join(TESTDIR, 'annotated')
224 if not os.path.isdir(adir):
224 if not os.path.isdir(adir):
225 os.mkdir(adir)
225 os.mkdir(adir)
226 cmd = '"%s" "%s" -i -a "--directory=%s" "--omit=%s"' % (
226 cmd = '"%s" "%s" -i -a "--directory=%s" "--omit=%s"' % (
227 sys.executable, os.path.join(TESTDIR, 'coverage.py'),
227 sys.executable, os.path.join(TESTDIR, 'coverage.py'),
228 adir, omit)
228 adir, omit)
229 vlog("# Running: "+cmd)
229 vlog("# Running: "+cmd)
230 os.system(cmd)
230 os.system(cmd)
231
231
232 class Timeout(Exception):
232 class Timeout(Exception):
233 pass
233 pass
234
234
235 def alarmed(signum, frame):
235 def alarmed(signum, frame):
236 raise Timeout
236 raise Timeout
237
237
238 def run(cmd):
238 def run(cmd):
239 """Run command in a sub-process, capturing the output (stdout and stderr).
239 """Run command in a sub-process, capturing the output (stdout and stderr).
240 Return the exist code, and output."""
240 Return the exist code, and output."""
241 # TODO: Use subprocess.Popen if we're running on Python 2.4
241 # TODO: Use subprocess.Popen if we're running on Python 2.4
242 if os.name == 'nt':
242 if os.name == 'nt':
243 tochild, fromchild = os.popen4(cmd)
243 tochild, fromchild = os.popen4(cmd)
244 tochild.close()
244 tochild.close()
245 output = fromchild.read()
245 output = fromchild.read()
246 ret = fromchild.close()
246 ret = fromchild.close()
247 if ret == None:
247 if ret == None:
248 ret = 0
248 ret = 0
249 else:
249 else:
250 proc = popen2.Popen4(cmd)
250 proc = popen2.Popen4(cmd)
251 try:
251 try:
252 output = ''
252 output = ''
253 proc.tochild.close()
253 proc.tochild.close()
254 output = proc.fromchild.read()
254 output = proc.fromchild.read()
255 ret = proc.wait()
255 ret = proc.wait()
256 if os.WIFEXITED(ret):
256 if os.WIFEXITED(ret):
257 ret = os.WEXITSTATUS(ret)
257 ret = os.WEXITSTATUS(ret)
258 except Timeout:
258 except Timeout:
259 vlog('# Process %d timed out - killing it' % proc.pid)
259 vlog('# Process %d timed out - killing it' % proc.pid)
260 os.kill(proc.pid, signal.SIGTERM)
260 os.kill(proc.pid, signal.SIGTERM)
261 ret = proc.wait()
261 ret = proc.wait()
262 if ret == 0:
262 if ret == 0:
263 ret = signal.SIGTERM << 8
263 ret = signal.SIGTERM << 8
264 output += ("\n### Abort: timeout after %d seconds.\n"
264 output += ("\n### Abort: timeout after %d seconds.\n"
265 % options.timeout)
265 % options.timeout)
266 return ret, splitnewlines(output)
266 return ret, splitnewlines(output)
267
267
268 def run_one(test, skips):
268 def run_one(test, skips):
269 '''tristate output:
269 '''tristate output:
270 None -> skipped
270 None -> skipped
271 True -> passed
271 True -> passed
272 False -> failed'''
272 False -> failed'''
273
273
274 def skip(msg):
274 def skip(msg):
275 if not verbose:
275 if not verbose:
276 skips.append((test, msg))
276 skips.append((test, msg))
277 else:
277 else:
278 print "\nSkipping %s: %s" % (test, msg)
278 print "\nSkipping %s: %s" % (test, msg)
279 return None
279 return None
280
280
281 vlog("# Test", test)
281 vlog("# Test", test)
282
282
283 # create a fresh hgrc
283 # create a fresh hgrc
284 hgrc = file(HGRCPATH, 'w+')
284 hgrc = file(HGRCPATH, 'w+')
285 hgrc.write('[ui]\n')
285 hgrc.write('[ui]\n')
286 hgrc.write('slash = True\n')
286 hgrc.write('slash = True\n')
287 hgrc.write('[defaults]\n')
287 hgrc.write('[defaults]\n')
288 hgrc.write('backout = -d "0 0"\n')
288 hgrc.write('backout = -d "0 0"\n')
289 hgrc.write('commit = -d "0 0"\n')
289 hgrc.write('commit = -d "0 0"\n')
290 hgrc.write('debugrawcommit = -d "0 0"\n')
290 hgrc.write('debugrawcommit = -d "0 0"\n')
291 hgrc.write('tag = -d "0 0"\n')
291 hgrc.write('tag = -d "0 0"\n')
292 hgrc.close()
292 hgrc.close()
293
293
294 err = os.path.join(TESTDIR, test+".err")
294 err = os.path.join(TESTDIR, test+".err")
295 ref = os.path.join(TESTDIR, test+".out")
295 ref = os.path.join(TESTDIR, test+".out")
296 testpath = os.path.join(TESTDIR, test)
296 testpath = os.path.join(TESTDIR, test)
297
297
298 if os.path.exists(err):
298 if os.path.exists(err):
299 os.remove(err) # Remove any previous output files
299 os.remove(err) # Remove any previous output files
300
300
301 # Make a tmp subdirectory to work in
301 # Make a tmp subdirectory to work in
302 tmpd = os.path.join(HGTMP, test)
302 tmpd = os.path.join(HGTMP, test)
303 os.mkdir(tmpd)
303 os.mkdir(tmpd)
304 os.chdir(tmpd)
304 os.chdir(tmpd)
305
305
306 try:
306 try:
307 tf = open(testpath)
307 tf = open(testpath)
308 firstline = tf.readline().rstrip()
308 firstline = tf.readline().rstrip()
309 tf.close()
309 tf.close()
310 except:
310 except:
311 firstline = ''
311 firstline = ''
312 lctest = test.lower()
312 lctest = test.lower()
313
313
314 if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
314 if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
315 cmd = '%s "%s"' % (python, testpath)
315 cmd = '%s "%s"' % (python, testpath)
316 elif lctest.endswith('.bat'):
316 elif lctest.endswith('.bat'):
317 # do not run batch scripts on non-windows
317 # do not run batch scripts on non-windows
318 if os.name != 'nt':
318 if os.name != 'nt':
319 return skip("batch script")
319 return skip("batch script")
320 # To reliably get the error code from batch files on WinXP,
320 # To reliably get the error code from batch files on WinXP,
321 # the "cmd /c call" prefix is needed. Grrr
321 # the "cmd /c call" prefix is needed. Grrr
322 cmd = 'cmd /c call "%s"' % testpath
322 cmd = 'cmd /c call "%s"' % testpath
323 else:
323 else:
324 # do not run shell scripts on windows
324 # do not run shell scripts on windows
325 if os.name == 'nt':
325 if os.name == 'nt':
326 return skip("shell script")
326 return skip("shell script")
327 # do not try to run non-executable programs
327 # do not try to run non-executable programs
328 if not os.access(testpath, os.X_OK):
328 if not os.access(testpath, os.X_OK):
329 return skip("not executable")
329 return skip("not executable")
330 cmd = '"%s"' % testpath
330 cmd = '"%s"' % testpath
331
331
332 if options.timeout > 0:
332 if options.timeout > 0:
333 signal.alarm(options.timeout)
333 signal.alarm(options.timeout)
334
334
335 vlog("# Running", cmd)
335 vlog("# Running", cmd)
336 ret, out = run(cmd)
336 ret, out = run(cmd)
337 vlog("# Ret was:", ret)
337 vlog("# Ret was:", ret)
338
338
339 if options.timeout > 0:
339 if options.timeout > 0:
340 signal.alarm(0)
340 signal.alarm(0)
341
341
342 skipped = (ret == SKIPPED_STATUS)
342 skipped = (ret == SKIPPED_STATUS)
343 diffret = 0
343 diffret = 0
344 # If reference output file exists, check test output against it
344 # If reference output file exists, check test output against it
345 if os.path.exists(ref):
345 if os.path.exists(ref):
346 f = open(ref, "r")
346 f = open(ref, "r")
347 ref_out = splitnewlines(f.read())
347 ref_out = splitnewlines(f.read())
348 f.close()
348 f.close()
349 else:
349 else:
350 ref_out = []
350 ref_out = []
351 if not skipped and out != ref_out:
351 if not skipped and out != ref_out:
352 diffret = 1
352 diffret = 1
353 print "\nERROR: %s output changed" % (test)
353 print "\nERROR: %s output changed" % (test)
354 show_diff(ref_out, out)
354 show_diff(ref_out, out)
355 if skipped:
355 if skipped:
356 missing = extract_missing_features(out)
356 missing = extract_missing_features(out)
357 if not missing:
357 if not missing:
358 missing = ['irrelevant']
358 missing = ['irrelevant']
359 skip(missing[-1])
359 skip(missing[-1])
360 elif ret:
360 elif ret:
361 print "\nERROR: %s failed with error code %d" % (test, ret)
361 print "\nERROR: %s failed with error code %d" % (test, ret)
362 elif diffret:
362 elif diffret:
363 ret = diffret
363 ret = diffret
364
364
365 if not verbose:
365 if not verbose:
366 sys.stdout.write(skipped and 's' or '.')
366 sys.stdout.write(skipped and 's' or '.')
367 sys.stdout.flush()
367 sys.stdout.flush()
368
368
369 if ret != 0 and not skipped:
369 if ret != 0 and not skipped:
370 # Save errors to a file for diagnosis
370 # Save errors to a file for diagnosis
371 f = open(err, "wb")
371 f = open(err, "wb")
372 for line in out:
372 for line in out:
373 f.write(line)
373 f.write(line)
374 f.close()
374 f.close()
375
375
376 # Kill off any leftover daemon processes
376 # Kill off any leftover daemon processes
377 try:
377 try:
378 fp = file(DAEMON_PIDS)
378 fp = file(DAEMON_PIDS)
379 for line in fp:
379 for line in fp:
380 try:
380 try:
381 pid = int(line)
381 pid = int(line)
382 except ValueError:
382 except ValueError:
383 continue
383 continue
384 try:
384 try:
385 os.kill(pid, 0)
385 os.kill(pid, 0)
386 vlog('# Killing daemon process %d' % pid)
386 vlog('# Killing daemon process %d' % pid)
387 os.kill(pid, signal.SIGTERM)
387 os.kill(pid, signal.SIGTERM)
388 time.sleep(0.25)
388 time.sleep(0.25)
389 os.kill(pid, 0)
389 os.kill(pid, 0)
390 vlog('# Daemon process %d is stuck - really killing it' % pid)
390 vlog('# Daemon process %d is stuck - really killing it' % pid)
391 os.kill(pid, signal.SIGKILL)
391 os.kill(pid, signal.SIGKILL)
392 except OSError, err:
392 except OSError, err:
393 if err.errno != errno.ESRCH:
393 if err.errno != errno.ESRCH:
394 raise
394 raise
395 fp.close()
395 fp.close()
396 os.unlink(DAEMON_PIDS)
396 os.unlink(DAEMON_PIDS)
397 except IOError:
397 except IOError:
398 pass
398 pass
399
399
400 os.chdir(TESTDIR)
400 os.chdir(TESTDIR)
401 shutil.rmtree(tmpd, True)
401 shutil.rmtree(tmpd, True)
402 if skipped:
402 if skipped:
403 return None
403 return None
404 return ret == 0
404 return ret == 0
405
405
406 if not options.child:
406 if not options.child:
407 os.umask(022)
407 os.umask(022)
408
408
409 check_required_tools()
409 check_required_tools()
410
410
411 # Reset some environment variables to well-known values so that
411 # Reset some environment variables to well-known values so that
412 # the tests produce repeatable output.
412 # the tests produce repeatable output.
413 os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
413 os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
414 os.environ['TZ'] = 'GMT'
414 os.environ['TZ'] = 'GMT'
415 os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
415 os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
416
416
417 TESTDIR = os.environ["TESTDIR"] = os.getcwd()
417 TESTDIR = os.environ["TESTDIR"] = os.getcwd()
418 HGTMP = os.environ['HGTMP'] = tempfile.mkdtemp('', 'hgtests.', options.tmpdir)
418 HGTMP = os.environ['HGTMP'] = tempfile.mkdtemp('', 'hgtests.', options.tmpdir)
419 DAEMON_PIDS = None
419 DAEMON_PIDS = None
420 HGRCPATH = None
420 HGRCPATH = None
421
421
422 os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
422 os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
423 os.environ["HGMERGE"] = ('python "%s" -L my -L other'
423 os.environ["HGMERGE"] = "internal:merge"
424 % os.path.join(TESTDIR, os.path.pardir,
425 'contrib', 'simplemerge'))
426 os.environ["HGUSER"] = "test"
424 os.environ["HGUSER"] = "test"
427 os.environ["HGENCODING"] = "ascii"
425 os.environ["HGENCODING"] = "ascii"
428 os.environ["HGENCODINGMODE"] = "strict"
426 os.environ["HGENCODINGMODE"] = "strict"
429 os.environ["HGPORT"] = str(options.port)
427 os.environ["HGPORT"] = str(options.port)
430 os.environ["HGPORT1"] = str(options.port + 1)
428 os.environ["HGPORT1"] = str(options.port + 1)
431 os.environ["HGPORT2"] = str(options.port + 2)
429 os.environ["HGPORT2"] = str(options.port + 2)
432
430
433 if options.with_hg:
431 if options.with_hg:
434 INST = options.with_hg
432 INST = options.with_hg
435 else:
433 else:
436 INST = os.path.join(HGTMP, "install")
434 INST = os.path.join(HGTMP, "install")
437 BINDIR = os.path.join(INST, "bin")
435 BINDIR = os.path.join(INST, "bin")
438 PYTHONDIR = os.path.join(INST, "lib", "python")
436 PYTHONDIR = os.path.join(INST, "lib", "python")
439 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
437 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
440
438
441 def run_children(tests):
439 def run_children(tests):
442 if not options.with_hg:
440 if not options.with_hg:
443 install_hg()
441 install_hg()
444
442
445 optcopy = dict(options.__dict__)
443 optcopy = dict(options.__dict__)
446 optcopy['jobs'] = 1
444 optcopy['jobs'] = 1
447 optcopy['with_hg'] = INST
445 optcopy['with_hg'] = INST
448 opts = []
446 opts = []
449 for opt, value in optcopy.iteritems():
447 for opt, value in optcopy.iteritems():
450 name = '--' + opt.replace('_', '-')
448 name = '--' + opt.replace('_', '-')
451 if value is True:
449 if value is True:
452 opts.append(name)
450 opts.append(name)
453 elif value is not None:
451 elif value is not None:
454 opts.append(name + '=' + str(value))
452 opts.append(name + '=' + str(value))
455
453
456 tests.reverse()
454 tests.reverse()
457 jobs = [[] for j in xrange(options.jobs)]
455 jobs = [[] for j in xrange(options.jobs)]
458 while tests:
456 while tests:
459 for j in xrange(options.jobs):
457 for j in xrange(options.jobs):
460 if not tests: break
458 if not tests: break
461 jobs[j].append(tests.pop())
459 jobs[j].append(tests.pop())
462 fps = {}
460 fps = {}
463 for j in xrange(len(jobs)):
461 for j in xrange(len(jobs)):
464 job = jobs[j]
462 job = jobs[j]
465 if not job:
463 if not job:
466 continue
464 continue
467 rfd, wfd = os.pipe()
465 rfd, wfd = os.pipe()
468 childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
466 childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
469 cmdline = [python, sys.argv[0]] + opts + childopts + job
467 cmdline = [python, sys.argv[0]] + opts + childopts + job
470 vlog(' '.join(cmdline))
468 vlog(' '.join(cmdline))
471 fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
469 fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
472 os.close(wfd)
470 os.close(wfd)
473 failures = 0
471 failures = 0
474 tested, skipped, failed = 0, 0, 0
472 tested, skipped, failed = 0, 0, 0
475 skips = []
473 skips = []
476 while fps:
474 while fps:
477 pid, status = os.wait()
475 pid, status = os.wait()
478 fp = fps.pop(pid)
476 fp = fps.pop(pid)
479 l = fp.read().splitlines()
477 l = fp.read().splitlines()
480 test, skip, fail = map(int, l[:3])
478 test, skip, fail = map(int, l[:3])
481 for s in l[3:]:
479 for s in l[3:]:
482 skips.append(s.split(" ", 1))
480 skips.append(s.split(" ", 1))
483 tested += test
481 tested += test
484 skipped += skip
482 skipped += skip
485 failed += fail
483 failed += fail
486 vlog('pid %d exited, status %d' % (pid, status))
484 vlog('pid %d exited, status %d' % (pid, status))
487 failures |= status
485 failures |= status
488 print
486 print
489 for s in skips:
487 for s in skips:
490 print "Skipped %s: %s" % (s[0], s[1])
488 print "Skipped %s: %s" % (s[0], s[1])
491 print "# Ran %d tests, %d skipped, %d failed." % (
489 print "# Ran %d tests, %d skipped, %d failed." % (
492 tested, skipped, failed)
490 tested, skipped, failed)
493 sys.exit(failures != 0)
491 sys.exit(failures != 0)
494
492
495 def run_tests(tests):
493 def run_tests(tests):
496 global DAEMON_PIDS, HGRCPATH
494 global DAEMON_PIDS, HGRCPATH
497 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
495 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
498 HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
496 HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
499
497
500 try:
498 try:
501 if not options.with_hg:
499 if not options.with_hg:
502 install_hg()
500 install_hg()
503
501
504 if options.timeout > 0:
502 if options.timeout > 0:
505 try:
503 try:
506 signal.signal(signal.SIGALRM, alarmed)
504 signal.signal(signal.SIGALRM, alarmed)
507 vlog('# Running tests with %d-second timeout' %
505 vlog('# Running tests with %d-second timeout' %
508 options.timeout)
506 options.timeout)
509 except AttributeError:
507 except AttributeError:
510 print 'WARNING: cannot run tests with timeouts'
508 print 'WARNING: cannot run tests with timeouts'
511 options.timeout = 0
509 options.timeout = 0
512
510
513 tested = 0
511 tested = 0
514 failed = 0
512 failed = 0
515 skipped = 0
513 skipped = 0
516
514
517 if options.restart:
515 if options.restart:
518 orig = list(tests)
516 orig = list(tests)
519 while tests:
517 while tests:
520 if os.path.exists(tests[0] + ".err"):
518 if os.path.exists(tests[0] + ".err"):
521 break
519 break
522 tests.pop(0)
520 tests.pop(0)
523 if not tests:
521 if not tests:
524 print "running all tests"
522 print "running all tests"
525 tests = orig
523 tests = orig
526
524
527 skips = []
525 skips = []
528 for test in tests:
526 for test in tests:
529 if options.retest and not os.path.exists(test + ".err"):
527 if options.retest and not os.path.exists(test + ".err"):
530 skipped += 1
528 skipped += 1
531 continue
529 continue
532 ret = run_one(test, skips)
530 ret = run_one(test, skips)
533 if ret is None:
531 if ret is None:
534 skipped += 1
532 skipped += 1
535 elif not ret:
533 elif not ret:
536 if options.interactive:
534 if options.interactive:
537 print "Accept this change? [n] ",
535 print "Accept this change? [n] ",
538 answer = sys.stdin.readline().strip()
536 answer = sys.stdin.readline().strip()
539 if answer.lower() in "y yes".split():
537 if answer.lower() in "y yes".split():
540 rename(test + ".err", test + ".out")
538 rename(test + ".err", test + ".out")
541 tested += 1
539 tested += 1
542 continue
540 continue
543 failed += 1
541 failed += 1
544 if options.first:
542 if options.first:
545 break
543 break
546 tested += 1
544 tested += 1
547
545
548 if options.child:
546 if options.child:
549 fp = os.fdopen(options.child, 'w')
547 fp = os.fdopen(options.child, 'w')
550 fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
548 fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
551 for s in skips:
549 for s in skips:
552 fp.write("%s %s\n" % s)
550 fp.write("%s %s\n" % s)
553 fp.close()
551 fp.close()
554 else:
552 else:
555 print
553 print
556 for s in skips:
554 for s in skips:
557 print "Skipped %s: %s" % s
555 print "Skipped %s: %s" % s
558 print "# Ran %d tests, %d skipped, %d failed." % (
556 print "# Ran %d tests, %d skipped, %d failed." % (
559 tested, skipped, failed)
557 tested, skipped, failed)
560
558
561 if coverage:
559 if coverage:
562 output_coverage()
560 output_coverage()
563 except KeyboardInterrupt:
561 except KeyboardInterrupt:
564 failed = True
562 failed = True
565 print "\ninterrupted!"
563 print "\ninterrupted!"
566
564
567 if failed:
565 if failed:
568 sys.exit(1)
566 sys.exit(1)
569
567
570 if len(args) == 0:
568 if len(args) == 0:
571 args = os.listdir(".")
569 args = os.listdir(".")
572 args.sort()
570 args.sort()
573
571
574 tests = []
572 tests = []
575 for test in args:
573 for test in args:
576 if (test.startswith("test-") and '~' not in test and
574 if (test.startswith("test-") and '~' not in test and
577 ('.' not in test or test.endswith('.py') or
575 ('.' not in test or test.endswith('.py') or
578 test.endswith('.bat'))):
576 test.endswith('.bat'))):
579 tests.append(test)
577 tests.append(test)
580
578
581 vlog("# Using TESTDIR", TESTDIR)
579 vlog("# Using TESTDIR", TESTDIR)
582 vlog("# Using HGTMP", HGTMP)
580 vlog("# Using HGTMP", HGTMP)
583
581
584 try:
582 try:
585 if len(tests) > 1 and options.jobs > 1:
583 if len(tests) > 1 and options.jobs > 1:
586 run_children(tests)
584 run_children(tests)
587 else:
585 else:
588 run_tests(tests)
586 run_tests(tests)
589 finally:
587 finally:
590 cleanup_exit()
588 cleanup_exit()
@@ -1,33 +1,38 b''
1 adding a
1 adding a
2 ? a
2 ? a
3 adding a
3 adding a
4 A a
4 A a
5 A a
5 A a
6 ? b
6 ? b
7 A a
7 A a
8 A b
8 A b
9 % should fail
9 % should fail
10 b already tracked!
10 b already tracked!
11 A a
11 A a
12 A b
12 A b
13 % should fail
13 % should fail
14 a already tracked!
14 a already tracked!
15 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
16 merging a
16 warning: conflicts during merge.
17 warning: conflicts during merge.
17 merging a
18 merging a failed!
18 merging a failed!
19 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
19 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
20 There are unresolved merges, you can redo the full merge using:
20 There are unresolved merges, you can redo the full merge using:
21 hg update -C 2
21 hg update -C 2
22 hg merge 1
22 hg merge 1
23 M a
23 M a
24 ? a.orig
24 % should fail
25 % should fail
25 a already tracked!
26 a already tracked!
26 M a
27 M a
28 ? a.orig
27 % issue683
29 % issue683
28 R a
30 R a
31 ? a.orig
29 M a
32 M a
33 ? a.orig
30 c does not exist!
34 c does not exist!
31 d does not exist!
35 d does not exist!
32 M a
36 M a
33 A c
37 A c
38 ? a.orig
@@ -1,15 +1,16 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 merging a
2 warning: conflicts during merge.
3 warning: conflicts during merge.
3 merging a
4 merging a failed!
4 merging a failed!
5 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
5 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
6 There are unresolved merges, you can redo the full merge using:
6 There are unresolved merges, you can redo the full merge using:
7 hg update -C 2
7 hg update -C 2
8 hg merge 1
8 hg merge 1
9 e7fe8eb3e180+0d24b7662d3e+ tip
9 e7fe8eb3e180+0d24b7662d3e+ tip
10 <<<<<<< my
10 <<<<<<< local
11 something else
11 something else
12 =======
12 =======
13 something
13 something
14 >>>>>>> other
14 >>>>>>> other
15 M a
15 M a
16 ? a.orig
@@ -1,338 +1,338 b''
1 % add
1 % add
2 adding a
2 adding a
3 adding d1/d2/b
3 adding d1/d2/b
4 % modify
4 % modify
5 1:e0e2b8a9156b
5 1:e0e2b8a9156b
6 assuming destination a-hg
6 assuming destination a-hg
7 initializing svn repo 'a-hg'
7 initializing svn repo 'a-hg'
8 initializing svn wc 'a-hg-wc'
8 initializing svn wc 'a-hg-wc'
9 scanning source...
9 scanning source...
10 sorting...
10 sorting...
11 converting...
11 converting...
12 1 add a file
12 1 add a file
13 0 modify a file
13 0 modify a file
14 At revision 2.
14 At revision 2.
15 2 2 test .
15 2 2 test .
16 2 2 test a
16 2 2 test a
17 2 1 test d1
17 2 1 test d1
18 2 1 test d1/d2
18 2 1 test d1/d2
19 2 1 test d1/d2/b
19 2 1 test d1/d2/b
20 <?xml version="1.0"?>
20 <?xml version="1.0"?>
21 <log>
21 <log>
22 <logentry
22 <logentry
23 revision="2">
23 revision="2">
24 <author>test</author>
24 <author>test</author>
25 <date/>
25 <date/>
26 <paths>
26 <paths>
27 <path
27 <path
28 action="M">/a</path>
28 action="M">/a</path>
29 </paths>
29 </paths>
30 <msg>modify a file</msg>
30 <msg>modify a file</msg>
31 </logentry>
31 </logentry>
32 <logentry
32 <logentry
33 revision="1">
33 revision="1">
34 <author>test</author>
34 <author>test</author>
35 <date/>
35 <date/>
36 <paths>
36 <paths>
37 <path
37 <path
38 action="A">/a</path>
38 action="A">/a</path>
39 <path
39 <path
40 action="A">/d1</path>
40 action="A">/d1</path>
41 <path
41 <path
42 action="A">/d1/d2</path>
42 action="A">/d1/d2</path>
43 <path
43 <path
44 action="A">/d1/d2/b</path>
44 action="A">/d1/d2/b</path>
45 </paths>
45 </paths>
46 <msg>add a file</msg>
46 <msg>add a file</msg>
47 </logentry>
47 </logentry>
48 </log>
48 </log>
49 a:
49 a:
50 a
50 a
51 d1
51 d1
52
52
53 a-hg-wc:
53 a-hg-wc:
54 a
54 a
55 d1
55 d1
56 same
56 same
57 % rename
57 % rename
58 2:7009fc4efb34
58 2:7009fc4efb34
59 assuming destination a-hg
59 assuming destination a-hg
60 initializing svn wc 'a-hg-wc'
60 initializing svn wc 'a-hg-wc'
61 scanning source...
61 scanning source...
62 sorting...
62 sorting...
63 converting...
63 converting...
64 0 rename a file
64 0 rename a file
65 At revision 3.
65 At revision 3.
66 3 3 test .
66 3 3 test .
67 3 3 test b
67 3 3 test b
68 3 1 test d1
68 3 1 test d1
69 3 1 test d1/d2
69 3 1 test d1/d2
70 3 1 test d1/d2/b
70 3 1 test d1/d2/b
71 <?xml version="1.0"?>
71 <?xml version="1.0"?>
72 <log>
72 <log>
73 <logentry
73 <logentry
74 revision="3">
74 revision="3">
75 <author>test</author>
75 <author>test</author>
76 <date/>
76 <date/>
77 <paths>
77 <paths>
78 <path
78 <path
79 action="D">/a</path>
79 action="D">/a</path>
80 <path
80 <path
81 copyfrom-path="/a"
81 copyfrom-path="/a"
82 copyfrom-rev="2"
82 copyfrom-rev="2"
83 action="A">/b</path>
83 action="A">/b</path>
84 </paths>
84 </paths>
85 <msg>rename a file</msg>
85 <msg>rename a file</msg>
86 </logentry>
86 </logentry>
87 </log>
87 </log>
88 a:
88 a:
89 b
89 b
90 d1
90 d1
91
91
92 a-hg-wc:
92 a-hg-wc:
93 b
93 b
94 d1
94 d1
95 % copy
95 % copy
96 3:56c519973ce6
96 3:56c519973ce6
97 assuming destination a-hg
97 assuming destination a-hg
98 initializing svn wc 'a-hg-wc'
98 initializing svn wc 'a-hg-wc'
99 scanning source...
99 scanning source...
100 sorting...
100 sorting...
101 converting...
101 converting...
102 0 copy a file
102 0 copy a file
103 At revision 4.
103 At revision 4.
104 4 4 test .
104 4 4 test .
105 4 3 test b
105 4 3 test b
106 4 4 test c
106 4 4 test c
107 4 1 test d1
107 4 1 test d1
108 4 1 test d1/d2
108 4 1 test d1/d2
109 4 1 test d1/d2/b
109 4 1 test d1/d2/b
110 <?xml version="1.0"?>
110 <?xml version="1.0"?>
111 <log>
111 <log>
112 <logentry
112 <logentry
113 revision="4">
113 revision="4">
114 <author>test</author>
114 <author>test</author>
115 <date/>
115 <date/>
116 <paths>
116 <paths>
117 <path
117 <path
118 copyfrom-path="/b"
118 copyfrom-path="/b"
119 copyfrom-rev="3"
119 copyfrom-rev="3"
120 action="A">/c</path>
120 action="A">/c</path>
121 </paths>
121 </paths>
122 <msg>copy a file</msg>
122 <msg>copy a file</msg>
123 </logentry>
123 </logentry>
124 </log>
124 </log>
125 a:
125 a:
126 b
126 b
127 c
127 c
128 d1
128 d1
129
129
130 a-hg-wc:
130 a-hg-wc:
131 b
131 b
132 c
132 c
133 d1
133 d1
134 % remove
134 % remove
135 4:ed4dc9a6f585
135 4:ed4dc9a6f585
136 assuming destination a-hg
136 assuming destination a-hg
137 initializing svn wc 'a-hg-wc'
137 initializing svn wc 'a-hg-wc'
138 scanning source...
138 scanning source...
139 sorting...
139 sorting...
140 converting...
140 converting...
141 0 remove a file
141 0 remove a file
142 At revision 5.
142 At revision 5.
143 5 5 test .
143 5 5 test .
144 5 4 test c
144 5 4 test c
145 5 1 test d1
145 5 1 test d1
146 5 1 test d1/d2
146 5 1 test d1/d2
147 5 1 test d1/d2/b
147 5 1 test d1/d2/b
148 <?xml version="1.0"?>
148 <?xml version="1.0"?>
149 <log>
149 <log>
150 <logentry
150 <logentry
151 revision="5">
151 revision="5">
152 <author>test</author>
152 <author>test</author>
153 <date/>
153 <date/>
154 <paths>
154 <paths>
155 <path
155 <path
156 action="D">/b</path>
156 action="D">/b</path>
157 </paths>
157 </paths>
158 <msg>remove a file</msg>
158 <msg>remove a file</msg>
159 </logentry>
159 </logentry>
160 </log>
160 </log>
161 a:
161 a:
162 c
162 c
163 d1
163 d1
164
164
165 a-hg-wc:
165 a-hg-wc:
166 c
166 c
167 d1
167 d1
168 % executable
168 % executable
169 5:f205b3636d77
169 5:f205b3636d77
170 assuming destination a-hg
170 assuming destination a-hg
171 initializing svn wc 'a-hg-wc'
171 initializing svn wc 'a-hg-wc'
172 scanning source...
172 scanning source...
173 sorting...
173 sorting...
174 converting...
174 converting...
175 0 make a file executable
175 0 make a file executable
176 At revision 6.
176 At revision 6.
177 6 6 test .
177 6 6 test .
178 6 6 test c
178 6 6 test c
179 6 1 test d1
179 6 1 test d1
180 6 1 test d1/d2
180 6 1 test d1/d2
181 6 1 test d1/d2/b
181 6 1 test d1/d2/b
182 <?xml version="1.0"?>
182 <?xml version="1.0"?>
183 <log>
183 <log>
184 <logentry
184 <logentry
185 revision="6">
185 revision="6">
186 <author>test</author>
186 <author>test</author>
187 <date/>
187 <date/>
188 <paths>
188 <paths>
189 <path
189 <path
190 action="M">/c</path>
190 action="M">/c</path>
191 </paths>
191 </paths>
192 <msg>make a file executable</msg>
192 <msg>make a file executable</msg>
193 </logentry>
193 </logentry>
194 </log>
194 </log>
195 executable
195 executable
196 % executable in new directory
196 % executable in new directory
197 adding d1/a
197 adding d1/a
198 assuming destination a-hg
198 assuming destination a-hg
199 initializing svn repo 'a-hg'
199 initializing svn repo 'a-hg'
200 initializing svn wc 'a-hg-wc'
200 initializing svn wc 'a-hg-wc'
201 scanning source...
201 scanning source...
202 sorting...
202 sorting...
203 converting...
203 converting...
204 0 add executable file in new directory
204 0 add executable file in new directory
205 At revision 1.
205 At revision 1.
206 1 1 test .
206 1 1 test .
207 1 1 test d1
207 1 1 test d1
208 1 1 test d1/a
208 1 1 test d1/a
209 <?xml version="1.0"?>
209 <?xml version="1.0"?>
210 <log>
210 <log>
211 <logentry
211 <logentry
212 revision="1">
212 revision="1">
213 <author>test</author>
213 <author>test</author>
214 <date/>
214 <date/>
215 <paths>
215 <paths>
216 <path
216 <path
217 action="A">/d1</path>
217 action="A">/d1</path>
218 <path
218 <path
219 action="A">/d1/a</path>
219 action="A">/d1/a</path>
220 </paths>
220 </paths>
221 <msg>add executable file in new directory</msg>
221 <msg>add executable file in new directory</msg>
222 </logentry>
222 </logentry>
223 </log>
223 </log>
224 executable
224 executable
225 % copy to new directory
225 % copy to new directory
226 assuming destination a-hg
226 assuming destination a-hg
227 initializing svn wc 'a-hg-wc'
227 initializing svn wc 'a-hg-wc'
228 scanning source...
228 scanning source...
229 sorting...
229 sorting...
230 converting...
230 converting...
231 0 copy file to new directory
231 0 copy file to new directory
232 At revision 2.
232 At revision 2.
233 2 2 test .
233 2 2 test .
234 2 1 test d1
234 2 1 test d1
235 2 1 test d1/a
235 2 1 test d1/a
236 2 2 test d2
236 2 2 test d2
237 2 2 test d2/a
237 2 2 test d2/a
238 <?xml version="1.0"?>
238 <?xml version="1.0"?>
239 <log>
239 <log>
240 <logentry
240 <logentry
241 revision="2">
241 revision="2">
242 <author>test</author>
242 <author>test</author>
243 <date/>
243 <date/>
244 <paths>
244 <paths>
245 <path
245 <path
246 action="A">/d2</path>
246 action="A">/d2</path>
247 <path
247 <path
248 copyfrom-path="/d1/a"
248 copyfrom-path="/d1/a"
249 copyfrom-rev="1"
249 copyfrom-rev="1"
250 action="A">/d2/a</path>
250 action="A">/d2/a</path>
251 </paths>
251 </paths>
252 <msg>copy file to new directory</msg>
252 <msg>copy file to new directory</msg>
253 </logentry>
253 </logentry>
254 </log>
254 </log>
255 % branchy history
255 % branchy history
256 adding b
256 adding b
257 adding left-1
257 adding left-1
258 adding left-2
258 adding left-2
259 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
259 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
260 adding right-1
260 adding right-1
261 adding right-2
261 adding right-2
262 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
262 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
263 merging b
263 warning: conflicts during merge.
264 warning: conflicts during merge.
264 merging b
265 merging b failed!
265 merging b failed!
266 2 files updated, 0 files merged, 0 files removed, 1 files unresolved
266 2 files updated, 0 files merged, 0 files removed, 1 files unresolved
267 There are unresolved merges, you can redo the full merge using:
267 There are unresolved merges, you can redo the full merge using:
268 hg update -C 2
268 hg update -C 2
269 hg merge 4
269 hg merge 4
270 assuming destination b-hg
270 assuming destination b-hg
271 initializing svn repo 'b-hg'
271 initializing svn repo 'b-hg'
272 initializing svn wc 'b-hg-wc'
272 initializing svn wc 'b-hg-wc'
273 scanning source...
273 scanning source...
274 sorting...
274 sorting...
275 converting...
275 converting...
276 5 base
276 5 base
277 4 left-1
277 4 left-1
278 3 left-2
278 3 left-2
279 2 right-1
279 2 right-1
280 1 right-2
280 1 right-2
281 0 merge
281 0 merge
282 % expect 4 changes
282 % expect 4 changes
283 At revision 4.
283 At revision 4.
284 4 4 test .
284 4 4 test .
285 4 3 test b
285 4 3 test b
286 4 2 test left-1
286 4 2 test left-1
287 4 3 test left-2
287 4 3 test left-2
288 4 4 test right-1
288 4 4 test right-1
289 4 4 test right-2
289 4 4 test right-2
290 <?xml version="1.0"?>
290 <?xml version="1.0"?>
291 <log>
291 <log>
292 <logentry
292 <logentry
293 revision="4">
293 revision="4">
294 <author>test</author>
294 <author>test</author>
295 <date/>
295 <date/>
296 <paths>
296 <paths>
297 <path
297 <path
298 action="A">/right-1</path>
298 action="A">/right-1</path>
299 <path
299 <path
300 action="A">/right-2</path>
300 action="A">/right-2</path>
301 </paths>
301 </paths>
302 <msg>merge</msg>
302 <msg>merge</msg>
303 </logentry>
303 </logentry>
304 <logentry
304 <logentry
305 revision="3">
305 revision="3">
306 <author>test</author>
306 <author>test</author>
307 <date/>
307 <date/>
308 <paths>
308 <paths>
309 <path
309 <path
310 action="M">/b</path>
310 action="M">/b</path>
311 <path
311 <path
312 action="A">/left-2</path>
312 action="A">/left-2</path>
313 </paths>
313 </paths>
314 <msg>left-2</msg>
314 <msg>left-2</msg>
315 </logentry>
315 </logentry>
316 <logentry
316 <logentry
317 revision="2">
317 revision="2">
318 <author>test</author>
318 <author>test</author>
319 <date/>
319 <date/>
320 <paths>
320 <paths>
321 <path
321 <path
322 action="M">/b</path>
322 action="M">/b</path>
323 <path
323 <path
324 action="A">/left-1</path>
324 action="A">/left-1</path>
325 </paths>
325 </paths>
326 <msg>left-1</msg>
326 <msg>left-1</msg>
327 </logentry>
327 </logentry>
328 <logentry
328 <logentry
329 revision="1">
329 revision="1">
330 <author>test</author>
330 <author>test</author>
331 <date/>
331 <date/>
332 <paths>
332 <paths>
333 <path
333 <path
334 action="A">/b</path>
334 action="A">/b</path>
335 </paths>
335 </paths>
336 <msg>base</msg>
336 <msg>base</msg>
337 </logentry>
337 </logentry>
338 </log>
338 </log>
@@ -1,31 +1,35 b''
1 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
2 resolving manifests
2 resolving manifests
3 overwrite None partial False
3 overwrite None partial False
4 ancestor 583c7b748052 local fb3948d97f07+ remote 40da226db0f0
4 ancestor 583c7b748052 local fb3948d97f07+ remote 40da226db0f0
5 searching for copies back to rev 1
5 searching for copies back to rev 1
6 unmatched files in other:
6 unmatched files in other:
7 b
7 b
8 c
8 c
9 all copies found (* = to merge, ! = divergent):
9 all copies found (* = to merge, ! = divergent):
10 c -> a *
10 c -> a *
11 b -> a *
11 b -> a *
12 checking for directory renames
12 checking for directory renames
13 a: remote moved to c -> m
13 a: remote moved to c -> m
14 a: remote moved to b -> m
14 a: remote moved to b -> m
15 copying a to b
15 copying a to b
16 copying a to c
16 copying a to c
17 picked tool 'internal:merge' for a (binary False symlink False)
17 merging a and b
18 merging a and b
18 my a@fb3948d97f07+ other b@40da226db0f0 ancestor a@583c7b748052
19 my a@fb3948d97f07+ other b@40da226db0f0 ancestor a@583c7b748052
20 premerge successful
19 removing a
21 removing a
22 picked tool 'internal:merge' for a (binary False symlink False)
20 merging a and c
23 merging a and c
21 my a@fb3948d97f07+ other c@40da226db0f0 ancestor a@583c7b748052
24 my a@fb3948d97f07+ other c@40da226db0f0 ancestor a@583c7b748052
25 premerge successful
22 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
26 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
23 (branch merge, don't forget to commit)
27 (branch merge, don't forget to commit)
24 -- b --
28 -- b --
25 0
29 0
26 1
30 1
27 2
31 2
28 -- c --
32 -- c --
29 0
33 0
30 1
34 1
31 2
35 2
@@ -1,26 +1,30 b''
1 resolving manifests
1 resolving manifests
2 overwrite None partial False
2 overwrite None partial False
3 ancestor 310fd17130da local 2092631ce82b+ remote 7731dad1c2b9
3 ancestor 310fd17130da local 2092631ce82b+ remote 7731dad1c2b9
4 searching for copies back to rev 1
4 searching for copies back to rev 1
5 unmatched files in other:
5 unmatched files in other:
6 bar
6 bar
7 all copies found (* = to merge, ! = divergent):
7 all copies found (* = to merge, ! = divergent):
8 bar -> foo *
8 bar -> foo *
9 checking for directory renames
9 checking for directory renames
10 foo: versions differ -> m
10 foo: versions differ -> m
11 foo: remote copied to bar -> m
11 foo: remote copied to bar -> m
12 copying foo to bar
12 copying foo to bar
13 picked tool 'internal:merge' for foo (binary False symlink False)
13 merging foo and bar
14 merging foo and bar
14 my foo@2092631ce82b+ other bar@7731dad1c2b9 ancestor foo@310fd17130da
15 my foo@2092631ce82b+ other bar@7731dad1c2b9 ancestor foo@310fd17130da
16 premerge successful
17 picked tool 'internal:merge' for foo (binary False symlink False)
15 merging foo
18 merging foo
16 my foo@2092631ce82b+ other foo@7731dad1c2b9 ancestor foo@310fd17130da
19 my foo@2092631ce82b+ other foo@7731dad1c2b9 ancestor foo@310fd17130da
20 premerge successful
17 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
21 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
18 (branch merge, don't forget to commit)
22 (branch merge, don't forget to commit)
19 -- foo --
23 -- foo --
20 line 0
24 line 0
21 line 1
25 line 1
22 line 2-1
26 line 2-1
23 -- bar --
27 -- bar --
24 line 0
28 line 0
25 line 1
29 line 1
26 line 2-2
30 line 2-2
@@ -1,8 +1,7 b''
1 Checking encoding (ascii)...
1 Checking encoding (ascii)...
2 Checking extensions...
2 Checking extensions...
3 Checking templates...
3 Checking templates...
4 Checking patch...
4 Checking patch...
5 Checking merge helper...
6 Checking commit editor...
5 Checking commit editor...
7 Checking username...
6 Checking username...
8 No problems detected
7 No problems detected
@@ -1,51 +1,55 b''
1 adding 1
1 adding 1
2 adding 2
2 adding 2
3 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor 81f4b099af3d local c64f439569a9+ remote 2f8037f47a5c
6 ancestor 81f4b099af3d local c64f439569a9+ remote 2f8037f47a5c
7 searching for copies back to rev 1
7 searching for copies back to rev 1
8 unmatched files in other:
8 unmatched files in other:
9 1a
9 1a
10 all copies found (* = to merge, ! = divergent):
10 all copies found (* = to merge, ! = divergent):
11 1a -> 1
11 1a -> 1
12 checking for directory renames
12 checking for directory renames
13 1: other deleted -> r
13 1: other deleted -> r
14 1a: remote created -> g
14 1a: remote created -> g
15 removing 1
15 removing 1
16 getting 1a
16 getting 1a
17 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
17 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
18 (branch merge, don't forget to commit)
18 (branch merge, don't forget to commit)
19 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
19 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
20 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
20 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
21 resolving manifests
21 resolving manifests
22 overwrite None partial False
22 overwrite None partial False
23 ancestor c64f439569a9 local ac7575e3c052+ remote 746e9549ea96
23 ancestor c64f439569a9 local ac7575e3c052+ remote 746e9549ea96
24 searching for copies back to rev 1
24 searching for copies back to rev 1
25 unmatched files in local:
25 unmatched files in local:
26 1a
26 1a
27 all copies found (* = to merge, ! = divergent):
27 all copies found (* = to merge, ! = divergent):
28 1a -> 1 *
28 1a -> 1 *
29 checking for directory renames
29 checking for directory renames
30 1a: local moved to 1 -> m
30 1a: local moved to 1 -> m
31 picked tool 'internal:merge' for 1a (binary False symlink False)
31 merging 1a and 1
32 merging 1a and 1
32 my 1a@ac7575e3c052+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
33 my 1a@ac7575e3c052+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
34 premerge successful
33 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
35 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
34 (branch merge, don't forget to commit)
36 (branch merge, don't forget to commit)
35 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
37 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
36 resolving manifests
38 resolving manifests
37 overwrite None partial False
39 overwrite None partial False
38 ancestor c64f439569a9 local 746e9549ea96+ remote ac7575e3c052
40 ancestor c64f439569a9 local 746e9549ea96+ remote ac7575e3c052
39 searching for copies back to rev 1
41 searching for copies back to rev 1
40 unmatched files in other:
42 unmatched files in other:
41 1a
43 1a
42 all copies found (* = to merge, ! = divergent):
44 all copies found (* = to merge, ! = divergent):
43 1a -> 1 *
45 1a -> 1 *
44 checking for directory renames
46 checking for directory renames
45 1: remote moved to 1a -> m
47 1: remote moved to 1a -> m
46 copying 1 to 1a
48 copying 1 to 1a
49 picked tool 'internal:merge' for 1 (binary False symlink False)
47 merging 1 and 1a
50 merging 1 and 1a
48 my 1@746e9549ea96+ other 1a@ac7575e3c052 ancestor 1@81f4b099af3d
51 my 1@746e9549ea96+ other 1a@ac7575e3c052 ancestor 1@81f4b099af3d
52 premerge successful
49 removing 1
53 removing 1
50 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
54 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
51 (branch merge, don't forget to commit)
55 (branch merge, don't forget to commit)
@@ -1,85 +1,89 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 merging bar and foo
2 merging bar and foo
3 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4 (branch merge, don't forget to commit)
4 (branch merge, don't forget to commit)
5 % contents of bar should be line0 line1 line2
5 % contents of bar should be line0 line1 line2
6 line0
6 line0
7 line1
7 line1
8 line2
8 line2
9 rev offset length base linkrev nodeid p1 p2
9 rev offset length base linkrev nodeid p1 p2
10 0 0 77 0 2 da78c0659611 000000000000 000000000000
10 0 0 77 0 2 da78c0659611 000000000000 000000000000
11 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
11 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
12 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
12 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
13 rev offset length base linkrev nodeid p1 p2
13 rev offset length base linkrev nodeid p1 p2
14 0 0 7 0 0 690b295714ae 000000000000 000000000000
14 0 0 7 0 0 690b295714ae 000000000000 000000000000
15 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
15 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 4:2d2f9a22c82b 2:0a3ab4856510
17 4:2d2f9a22c82b 2:0a3ab4856510
18 3:7d3b554bfdf1 2:0a3ab4856510 1:5cd961e4045d
18 3:7d3b554bfdf1 2:0a3ab4856510 1:5cd961e4045d
19 2:0a3ab4856510 0:2665aaee66e9
19 2:0a3ab4856510 0:2665aaee66e9
20 1:5cd961e4045d
20 1:5cd961e4045d
21 0:2665aaee66e9
21 0:2665aaee66e9
22 % this should use bar@rev2 as the ancestor
22 % this should use bar@rev2 as the ancestor
23 resolving manifests
23 resolving manifests
24 overwrite None partial False
24 overwrite None partial False
25 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 7d3b554bfdf1
25 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 7d3b554bfdf1
26 searching for copies back to rev 1
26 searching for copies back to rev 1
27 bar: versions differ -> m
27 bar: versions differ -> m
28 picked tool 'internal:merge' for bar (binary False symlink False)
28 merging bar
29 merging bar
29 my bar@2d2f9a22c82b+ other bar@7d3b554bfdf1 ancestor bar@0a3ab4856510
30 my bar@2d2f9a22c82b+ other bar@7d3b554bfdf1 ancestor bar@0a3ab4856510
31 premerge successful
30 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
32 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
31 (branch merge, don't forget to commit)
33 (branch merge, don't forget to commit)
32 % contents of bar should be line1 line2
34 % contents of bar should be line1 line2
33 line1
35 line1
34 line2
36 line2
35 rev offset length base linkrev nodeid p1 p2
37 rev offset length base linkrev nodeid p1 p2
36 0 0 77 0 2 da78c0659611 000000000000 000000000000
38 0 0 77 0 2 da78c0659611 000000000000 000000000000
37 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
39 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
38 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
40 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
39 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
41 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
40
42
41
43
42 requesting all changes
44 requesting all changes
43 adding changesets
45 adding changesets
44 adding manifests
46 adding manifests
45 adding file changes
47 adding file changes
46 added 3 changesets with 3 changes to 2 files (+1 heads)
48 added 3 changesets with 3 changes to 2 files (+1 heads)
47 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 merging foo and bar
50 merging foo and bar
49 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
51 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
50 (branch merge, don't forget to commit)
52 (branch merge, don't forget to commit)
51 % contents of bar should be line0 line1 line2
53 % contents of bar should be line0 line1 line2
52 line0
54 line0
53 line1
55 line1
54 line2
56 line2
55 rev offset length base linkrev nodeid p1 p2
57 rev offset length base linkrev nodeid p1 p2
56 0 0 77 0 2 da78c0659611 000000000000 000000000000
58 0 0 77 0 2 da78c0659611 000000000000 000000000000
57 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
59 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
58 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
60 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
59 rev offset length base linkrev nodeid p1 p2
61 rev offset length base linkrev nodeid p1 p2
60 0 0 7 0 0 690b295714ae 000000000000 000000000000
62 0 0 7 0 0 690b295714ae 000000000000 000000000000
61 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
63 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
62 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 4:2d2f9a22c82b 2:0a3ab4856510
65 4:2d2f9a22c82b 2:0a3ab4856510
64 3:96ab80c60897 1:5cd961e4045d 2:0a3ab4856510
66 3:96ab80c60897 1:5cd961e4045d 2:0a3ab4856510
65 2:0a3ab4856510 0:2665aaee66e9
67 2:0a3ab4856510 0:2665aaee66e9
66 1:5cd961e4045d
68 1:5cd961e4045d
67 0:2665aaee66e9
69 0:2665aaee66e9
68 % this should use bar@rev2 as the ancestor
70 % this should use bar@rev2 as the ancestor
69 resolving manifests
71 resolving manifests
70 overwrite None partial False
72 overwrite None partial False
71 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 96ab80c60897
73 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 96ab80c60897
72 searching for copies back to rev 1
74 searching for copies back to rev 1
73 bar: versions differ -> m
75 bar: versions differ -> m
76 picked tool 'internal:merge' for bar (binary False symlink False)
74 merging bar
77 merging bar
75 my bar@2d2f9a22c82b+ other bar@96ab80c60897 ancestor bar@0a3ab4856510
78 my bar@2d2f9a22c82b+ other bar@96ab80c60897 ancestor bar@0a3ab4856510
79 premerge successful
76 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
80 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
77 (branch merge, don't forget to commit)
81 (branch merge, don't forget to commit)
78 % contents of bar should be line1 line2
82 % contents of bar should be line1 line2
79 line1
83 line1
80 line2
84 line2
81 rev offset length base linkrev nodeid p1 p2
85 rev offset length base linkrev nodeid p1 p2
82 0 0 77 0 2 da78c0659611 000000000000 000000000000
86 0 0 77 0 2 da78c0659611 000000000000 000000000000
83 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
87 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
84 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
88 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
85 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
89 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
@@ -1,67 +1,69 b''
1 # revision 0
1 # revision 0
2 adding copy
2 adding copy
3 adding move
3 adding move
4 adding remove
4 adding remove
5 adding unchanged
5 adding unchanged
6 adding zzz1_merge_ok
6 adding zzz1_merge_ok
7 adding zzz2_merge_bad
7 adding zzz2_merge_bad
8 # revision 1
8 # revision 1
9 # local changes to revision 0
9 # local changes to revision 0
10 4 files updated, 0 files merged, 3 files removed, 0 files unresolved
10 4 files updated, 0 files merged, 3 files removed, 0 files unresolved
11 --- a/zzz1_merge_ok
11 --- a/zzz1_merge_ok
12 +++ b/zzz1_merge_ok
12 +++ b/zzz1_merge_ok
13 +new last line
13 +new last line
14 --- a/zzz2_merge_bad
14 --- a/zzz2_merge_bad
15 +++ b/zzz2_merge_bad
15 +++ b/zzz2_merge_bad
16 +another last line
16 +another last line
17 M zzz1_merge_ok
17 M zzz1_merge_ok
18 M zzz2_merge_bad
18 M zzz2_merge_bad
19 # local merge with bad merge tool
19 # local merge with bad merge tool
20 merging zzz1_merge_ok
20 merging zzz1_merge_ok
21 merging zzz1_merge_ok failed!
22 merging zzz2_merge_bad
21 merging zzz2_merge_bad
23 merging zzz2_merge_bad failed!
22 merging zzz2_merge_bad failed!
24 3 files updated, 0 files merged, 2 files removed, 2 files unresolved
23 3 files updated, 1 files merged, 2 files removed, 1 files unresolved
25 There are unresolved merges with locally modified files.
24 There are unresolved merges with locally modified files.
26 You can redo the full merge using:
25 You can finish the partial merge using:
27 hg update 0
26 hg update 0
28 hg update 1
27 hg update 1
29 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
28 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
30 --- a/zzz1_merge_ok
29 --- a/zzz1_merge_ok
31 +++ b/zzz1_merge_ok
30 +++ b/zzz1_merge_ok
31 +new first line
32 +new last line
32 +new last line
33 --- a/zzz2_merge_bad
33 --- a/zzz2_merge_bad
34 +++ b/zzz2_merge_bad
34 +++ b/zzz2_merge_bad
35 +another last line
35 +another last line
36 M zzz1_merge_ok
36 M zzz1_merge_ok
37 M zzz2_merge_bad
37 M zzz2_merge_bad
38 ? zzz2_merge_bad.orig
38 # local merge with conflicts
39 # local merge with conflicts
39 warning: conflicts during merge.
40 merging zzz1_merge_ok
40 merging zzz1_merge_ok
41 merging zzz2_merge_bad
41 merging zzz2_merge_bad
42 warning: conflicts during merge.
42 merging zzz2_merge_bad failed!
43 merging zzz2_merge_bad failed!
43 3 files updated, 1 files merged, 2 files removed, 1 files unresolved
44 3 files updated, 1 files merged, 2 files removed, 1 files unresolved
44 There are unresolved merges with locally modified files.
45 There are unresolved merges with locally modified files.
45 You can finish the partial merge using:
46 You can finish the partial merge using:
46 hg update 0
47 hg update 0
47 hg update 1
48 hg update 1
48 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
49 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
49 --- a/zzz1_merge_ok
50 --- a/zzz1_merge_ok
50 +++ b/zzz1_merge_ok
51 +++ b/zzz1_merge_ok
51 +new first line
52 +new first line
52 +new last line
53 +new last line
53 --- a/zzz2_merge_bad
54 --- a/zzz2_merge_bad
54 +++ b/zzz2_merge_bad
55 +++ b/zzz2_merge_bad
55 +another last line
56 +another last line
56 +=======
57 +=======
57 +new last line
58 +new last line
58 M zzz1_merge_ok
59 M zzz1_merge_ok
59 M zzz2_merge_bad
60 M zzz2_merge_bad
61 ? zzz2_merge_bad.orig
60 # local merge without conflicts
62 # local merge without conflicts
61 merging zzz1_merge_ok
63 merging zzz1_merge_ok
62 4 files updated, 1 files merged, 2 files removed, 0 files unresolved
64 4 files updated, 1 files merged, 2 files removed, 0 files unresolved
63 --- a/zzz1_merge_ok
65 --- a/zzz1_merge_ok
64 +++ b/zzz1_merge_ok
66 +++ b/zzz1_merge_ok
65 +new last line
67 +new last line
66 M zzz1_merge_ok
68 M zzz1_merge_ok
67 ? zzz2_merge_bad.orig
69 ? zzz2_merge_bad.orig
@@ -1,37 +1,41 b''
1 1:f248da0d4c3e
1 1:f248da0d4c3e
2 0:9eca13a34789
2 0:9eca13a34789
3 f248da0d4c3e tip
3 f248da0d4c3e tip
4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 9eca13a34789
5 9eca13a34789
6 9eca13a34789+
6 9eca13a34789+
7 reverting file1
7 reverting file1
8 9eca13a34789
8 9eca13a34789
9 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
9 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 f248da0d4c3e tip
10 f248da0d4c3e tip
11 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
11 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 merging file1
12 warning: conflicts during merge.
13 warning: conflicts during merge.
13 merging file1
14 merging file1 failed!
14 merging file1 failed!
15 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
15 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
16 There are unresolved merges with locally modified files.
16 There are unresolved merges with locally modified files.
17 You can redo the full merge using:
17 You can redo the full merge using:
18 hg update 0
18 hg update 0
19 hg update 1
19 hg update 1
20 diff -r f248da0d4c3e file1
20 diff -r f248da0d4c3e file1
21 --- a/file1
21 --- a/file1
22 +++ b/file1
22 +++ b/file1
23 @@ -1,3 +1,7 @@
23 @@ -1,3 +1,7 @@
24 added file1
24 added file1
25 another line of text
25 another line of text
26 +<<<<<<< my
26 +<<<<<<< local
27 +changed file1 different
27 +changed file1 different
28 +=======
28 +=======
29 changed file1
29 changed file1
30 +>>>>>>> other
30 +>>>>>>> other
31 M file1
31 M file1
32 ? file1.orig
32 f248da0d4c3e+ tip
33 f248da0d4c3e+ tip
33 reverting file1
34 reverting file1
35 ? file1.orig
34 f248da0d4c3e tip
36 f248da0d4c3e tip
37 ? file1.orig
35 f248da0d4c3e tip
38 f248da0d4c3e tip
36 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
39 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
40 ? file1.orig
37 f248da0d4c3e tip
41 f248da0d4c3e tip
@@ -1,78 +1,79 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 pulling from ../test-a
2 pulling from ../test-a
3 searching for changes
3 searching for changes
4 adding changesets
4 adding changesets
5 adding manifests
5 adding manifests
6 adding file changes
6 adding file changes
7 added 1 changesets with 1 changes to 1 files (+1 heads)
7 added 1 changesets with 1 changes to 1 files (+1 heads)
8 (run 'hg heads' to see heads, 'hg merge' to merge)
8 (run 'hg heads' to see heads, 'hg merge' to merge)
9 merging test.txt
9 warning: conflicts during merge.
10 warning: conflicts during merge.
10 merging test.txt
11 merging test.txt failed!
11 merging test.txt failed!
12 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
12 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
13 There are unresolved merges, you can redo the full merge using:
13 There are unresolved merges, you can redo the full merge using:
14 hg update -C 1
14 hg update -C 1
15 hg merge 2
15 hg merge 2
16 pulling from ../test-a
16 pulling from ../test-a
17 searching for changes
17 searching for changes
18 adding changesets
18 adding changesets
19 adding manifests
19 adding manifests
20 adding file changes
20 adding file changes
21 added 1 changesets with 1 changes to 1 files (+1 heads)
21 added 1 changesets with 1 changes to 1 files (+1 heads)
22 (run 'hg heads' to see heads, 'hg merge' to merge)
22 (run 'hg heads' to see heads, 'hg merge' to merge)
23 warning: conflicts during merge.
24 resolving manifests
23 resolving manifests
25 overwrite None partial False
24 overwrite None partial False
26 ancestor faaea63e63a9 local 451c744aabcc+ remote a070d41e8360
25 ancestor faaea63e63a9 local 451c744aabcc+ remote a070d41e8360
27 searching for copies back to rev 1
26 searching for copies back to rev 1
28 test.txt: versions differ -> m
27 test.txt: versions differ -> m
28 picked tool 'internal:merge' for test.txt (binary False symlink False)
29 merging test.txt
29 merging test.txt
30 my test.txt@451c744aabcc+ other test.txt@a070d41e8360 ancestor test.txt@faaea63e63a9
30 my test.txt@451c744aabcc+ other test.txt@a070d41e8360 ancestor test.txt@faaea63e63a9
31 warning: conflicts during merge.
31 merging test.txt failed!
32 merging test.txt failed!
32 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
33 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
33 There are unresolved merges, you can redo the full merge using:
34 There are unresolved merges, you can redo the full merge using:
34 hg update -C 3
35 hg update -C 3
35 hg merge 4
36 hg merge 4
36 one
37 one
37 <<<<<<< my
38 <<<<<<< local
38 two-point-five
39 two-point-five
39 =======
40 =======
40 two-point-one
41 two-point-one
41 >>>>>>> other
42 >>>>>>> other
42 three
43 three
43 rev offset length base linkrev nodeid p1 p2
44 rev offset length base linkrev nodeid p1 p2
44 0 0 7 0 0 01365c4cca56 000000000000 000000000000
45 0 0 7 0 0 01365c4cca56 000000000000 000000000000
45 1 7 9 1 1 7b013192566a 01365c4cca56 000000000000
46 1 7 9 1 1 7b013192566a 01365c4cca56 000000000000
46 2 16 15 2 2 8fe46a3eb557 01365c4cca56 000000000000
47 2 16 15 2 2 8fe46a3eb557 01365c4cca56 000000000000
47 3 31 27 2 3 fc3148072371 7b013192566a 8fe46a3eb557
48 3 31 27 2 3 fc3148072371 7b013192566a 8fe46a3eb557
48 4 58 25 4 4 d40249267ae3 8fe46a3eb557 000000000000
49 4 58 25 4 4 d40249267ae3 8fe46a3eb557 000000000000
49 changeset: 4:a070d41e8360
50 changeset: 4:a070d41e8360
50 tag: tip
51 tag: tip
51 parent: 2:faaea63e63a9
52 parent: 2:faaea63e63a9
52 user: test
53 user: test
53 date: Mon Jan 12 13:46:40 1970 +0000
54 date: Mon Jan 12 13:46:40 1970 +0000
54 summary: two -> two-point-one
55 summary: two -> two-point-one
55
56
56 changeset: 3:451c744aabcc
57 changeset: 3:451c744aabcc
57 parent: 1:e409be6afcc0
58 parent: 1:e409be6afcc0
58 parent: 2:faaea63e63a9
59 parent: 2:faaea63e63a9
59 user: test
60 user: test
60 date: Mon Jan 12 13:46:40 1970 +0000
61 date: Mon Jan 12 13:46:40 1970 +0000
61 summary: Merge 1
62 summary: Merge 1
62
63
63 changeset: 2:faaea63e63a9
64 changeset: 2:faaea63e63a9
64 parent: 0:095c92b91f1a
65 parent: 0:095c92b91f1a
65 user: test
66 user: test
66 date: Mon Jan 12 13:46:40 1970 +0000
67 date: Mon Jan 12 13:46:40 1970 +0000
67 summary: Numbers as words
68 summary: Numbers as words
68
69
69 changeset: 1:e409be6afcc0
70 changeset: 1:e409be6afcc0
70 user: test
71 user: test
71 date: Mon Jan 12 13:46:40 1970 +0000
72 date: Mon Jan 12 13:46:40 1970 +0000
72 summary: 2 -> 2.5
73 summary: 2 -> 2.5
73
74
74 changeset: 0:095c92b91f1a
75 changeset: 0:095c92b91f1a
75 user: test
76 user: test
76 date: Mon Jan 12 13:46:40 1970 +0000
77 date: Mon Jan 12 13:46:40 1970 +0000
77 summary: Initial
78 summary: Initial
78
79
@@ -1,21 +1,19 b''
1 adding bar
1 adding bar
2 adding foo
2 adding foo
3 adding quux1
3 adding quux1
4 adding quux2
4 adding quux2
5 merging bar
5 merging bar
6 merging bar failed!
6 merging bar failed!
7 merging foo and baz
7 merging foo and baz
8 merging baz failed!
8 1 files updated, 1 files merged, 0 files removed, 1 files unresolved
9 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
10 There are unresolved merges, you can redo the full merge using:
9 There are unresolved merges, you can redo the full merge using:
11 hg update -C 2
10 hg update -C 2
12 hg merge 1
11 hg merge 1
13 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
12 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
14 merging bar
13 merging bar
15 merging bar failed!
14 merging bar failed!
16 merging baz and foo
15 merging baz and foo
17 merging baz failed!
16 1 files updated, 1 files merged, 0 files removed, 1 files unresolved
18 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
19 There are unresolved merges, you can redo the full merge using:
17 There are unresolved merges, you can redo the full merge using:
20 hg update -C 1
18 hg update -C 1
21 hg merge 2
19 hg merge 2
@@ -1,40 +1,42 b''
1 checkout
1 checkout
2 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
2 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 merge
3 merge
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor af1939970a1c local f26ec4fc3fa3+ remote 8e765a822af2
6 ancestor af1939970a1c local f26ec4fc3fa3+ remote 8e765a822af2
7 searching for copies back to rev 1
7 searching for copies back to rev 1
8 unmatched files in local:
8 unmatched files in local:
9 c2
9 c2
10 unmatched files in other:
10 unmatched files in other:
11 b
11 b
12 b2
12 b2
13 all copies found (* = to merge, ! = divergent):
13 all copies found (* = to merge, ! = divergent):
14 c2 -> a2 !
14 c2 -> a2 !
15 b -> a *
15 b -> a *
16 b2 -> a2 !
16 b2 -> a2 !
17 checking for directory renames
17 checking for directory renames
18 a2: divergent renames -> dr
18 a2: divergent renames -> dr
19 a: remote moved to b -> m
19 a: remote moved to b -> m
20 b2: remote created -> g
20 b2: remote created -> g
21 copying a to b
21 copying a to b
22 picked tool 'internal:merge' for a (binary False symlink False)
22 merging a and b
23 merging a and b
23 my a@f26ec4fc3fa3+ other b@8e765a822af2 ancestor a@af1939970a1c
24 my a@f26ec4fc3fa3+ other b@8e765a822af2 ancestor a@af1939970a1c
25 premerge successful
24 removing a
26 removing a
25 warning: detected divergent renames of a2 to:
27 warning: detected divergent renames of a2 to:
26 c2
28 c2
27 b2
29 b2
28 getting b2
30 getting b2
29 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
31 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
30 (branch merge, don't forget to commit)
32 (branch merge, don't forget to commit)
31 M b
33 M b
32 a
34 a
33 M b2
35 M b2
34 R a
36 R a
35 C c2
37 C c2
36 blahblah
38 blahblah
37 rev offset length base linkrev nodeid p1 p2
39 rev offset length base linkrev nodeid p1 p2
38 0 0 67 0 1 dc51707dfc98 000000000000 000000000000
40 0 0 67 0 1 dc51707dfc98 000000000000 000000000000
39 1 67 72 1 3 b2494a44f0a9 000000000000 dc51707dfc98
41 1 67 72 1 3 b2494a44f0a9 000000000000 dc51707dfc98
40 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
42 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
@@ -1,499 +1,541 b''
1 --------------
1 --------------
2 test L:up a R:nc a b W: - 1 get local a to b
2 test L:up a R:nc a b W: - 1 get local a to b
3 --------------
3 --------------
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
6 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
7 searching for copies back to rev 1
7 searching for copies back to rev 1
8 unmatched files in other:
8 unmatched files in other:
9 b
9 b
10 all copies found (* = to merge, ! = divergent):
10 all copies found (* = to merge, ! = divergent):
11 b -> a *
11 b -> a *
12 checking for directory renames
12 checking for directory renames
13 rev: versions differ -> m
13 rev: versions differ -> m
14 a: remote copied to b -> m
14 a: remote copied to b -> m
15 copying a to b
15 copying a to b
16 picked tool 'python ../merge' for a (binary False symlink False)
16 merging a and b
17 merging a and b
17 my a@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
18 my a@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
19 premerge successful
20 picked tool 'python ../merge' for rev (binary False symlink False)
18 merging rev
21 merging rev
19 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
22 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
20 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
23 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
21 (branch merge, don't forget to commit)
24 (branch merge, don't forget to commit)
22 --------------
25 --------------
23 M b
26 M b
24 a
27 a
25 C a
28 C a
26 --------------
29 --------------
27
30
28 --------------
31 --------------
29 test L:nc a b R:up a W: - 2 get rem change to a and b
32 test L:nc a b R:up a W: - 2 get rem change to a and b
30 --------------
33 --------------
31 resolving manifests
34 resolving manifests
32 overwrite None partial False
35 overwrite None partial False
33 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
36 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
34 searching for copies back to rev 1
37 searching for copies back to rev 1
35 unmatched files in local:
38 unmatched files in local:
36 b
39 b
37 all copies found (* = to merge, ! = divergent):
40 all copies found (* = to merge, ! = divergent):
38 b -> a *
41 b -> a *
39 checking for directory renames
42 checking for directory renames
40 a: remote is newer -> g
43 a: remote is newer -> g
41 b: local copied to a -> m
44 b: local copied to a -> m
42 rev: versions differ -> m
45 rev: versions differ -> m
43 getting a
46 getting a
47 picked tool 'python ../merge' for b (binary False symlink False)
44 merging b and a
48 merging b and a
45 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
49 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
50 premerge successful
51 picked tool 'python ../merge' for rev (binary False symlink False)
46 merging rev
52 merging rev
47 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
53 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
48 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
54 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
49 (branch merge, don't forget to commit)
55 (branch merge, don't forget to commit)
50 --------------
56 --------------
51 M a
57 M a
52 M b
58 M b
53 a
59 a
54 --------------
60 --------------
55
61
56 --------------
62 --------------
57 test L:up a R:nm a b W: - 3 get local a change to b, remove a
63 test L:up a R:nm a b W: - 3 get local a change to b, remove a
58 --------------
64 --------------
59 resolving manifests
65 resolving manifests
60 overwrite None partial False
66 overwrite None partial False
61 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
67 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
62 searching for copies back to rev 1
68 searching for copies back to rev 1
63 unmatched files in other:
69 unmatched files in other:
64 b
70 b
65 all copies found (* = to merge, ! = divergent):
71 all copies found (* = to merge, ! = divergent):
66 b -> a *
72 b -> a *
67 checking for directory renames
73 checking for directory renames
68 rev: versions differ -> m
74 rev: versions differ -> m
69 a: remote moved to b -> m
75 a: remote moved to b -> m
70 copying a to b
76 copying a to b
77 picked tool 'python ../merge' for a (binary False symlink False)
71 merging a and b
78 merging a and b
72 my a@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
79 my a@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
80 premerge successful
73 removing a
81 removing a
82 picked tool 'python ../merge' for rev (binary False symlink False)
74 merging rev
83 merging rev
75 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
84 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
76 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
85 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
77 (branch merge, don't forget to commit)
86 (branch merge, don't forget to commit)
78 --------------
87 --------------
79 M b
88 M b
80 a
89 a
81 --------------
90 --------------
82
91
83 --------------
92 --------------
84 test L:nm a b R:up a W: - 4 get remote change to b
93 test L:nm a b R:up a W: - 4 get remote change to b
85 --------------
94 --------------
86 resolving manifests
95 resolving manifests
87 overwrite None partial False
96 overwrite None partial False
88 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
97 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
89 searching for copies back to rev 1
98 searching for copies back to rev 1
90 unmatched files in local:
99 unmatched files in local:
91 b
100 b
92 all copies found (* = to merge, ! = divergent):
101 all copies found (* = to merge, ! = divergent):
93 b -> a *
102 b -> a *
94 checking for directory renames
103 checking for directory renames
95 b: local moved to a -> m
104 b: local moved to a -> m
96 rev: versions differ -> m
105 rev: versions differ -> m
106 picked tool 'python ../merge' for b (binary False symlink False)
97 merging b and a
107 merging b and a
98 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
108 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
109 premerge successful
110 picked tool 'python ../merge' for rev (binary False symlink False)
99 merging rev
111 merging rev
100 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
112 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
101 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
113 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
102 (branch merge, don't forget to commit)
114 (branch merge, don't forget to commit)
103 --------------
115 --------------
104 M b
116 M b
105 a
117 a
106 --------------
118 --------------
107
119
108 --------------
120 --------------
109 test L: R:nc a b W: - 5 get b
121 test L: R:nc a b W: - 5 get b
110 --------------
122 --------------
111 resolving manifests
123 resolving manifests
112 overwrite None partial False
124 overwrite None partial False
113 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
125 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
114 searching for copies back to rev 1
126 searching for copies back to rev 1
115 unmatched files in other:
127 unmatched files in other:
116 b
128 b
117 all copies found (* = to merge, ! = divergent):
129 all copies found (* = to merge, ! = divergent):
118 b -> a
130 b -> a
119 checking for directory renames
131 checking for directory renames
120 rev: versions differ -> m
132 rev: versions differ -> m
121 b: remote created -> g
133 b: remote created -> g
122 getting b
134 getting b
135 picked tool 'python ../merge' for rev (binary False symlink False)
123 merging rev
136 merging rev
124 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
137 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
125 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
138 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
126 (branch merge, don't forget to commit)
139 (branch merge, don't forget to commit)
127 --------------
140 --------------
128 M b
141 M b
129 C a
142 C a
130 --------------
143 --------------
131
144
132 --------------
145 --------------
133 test L:nc a b R: W: - 6 nothing
146 test L:nc a b R: W: - 6 nothing
134 --------------
147 --------------
135 resolving manifests
148 resolving manifests
136 overwrite None partial False
149 overwrite None partial False
137 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
150 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
138 searching for copies back to rev 1
151 searching for copies back to rev 1
139 unmatched files in local:
152 unmatched files in local:
140 b
153 b
141 all copies found (* = to merge, ! = divergent):
154 all copies found (* = to merge, ! = divergent):
142 b -> a
155 b -> a
143 checking for directory renames
156 checking for directory renames
144 rev: versions differ -> m
157 rev: versions differ -> m
158 picked tool 'python ../merge' for rev (binary False symlink False)
145 merging rev
159 merging rev
146 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
160 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
147 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
161 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
148 (branch merge, don't forget to commit)
162 (branch merge, don't forget to commit)
149 --------------
163 --------------
150 C a
164 C a
151 C b
165 C b
152 --------------
166 --------------
153
167
154 --------------
168 --------------
155 test L: R:nm a b W: - 7 get b
169 test L: R:nm a b W: - 7 get b
156 --------------
170 --------------
157 resolving manifests
171 resolving manifests
158 overwrite None partial False
172 overwrite None partial False
159 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
173 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
160 searching for copies back to rev 1
174 searching for copies back to rev 1
161 unmatched files in other:
175 unmatched files in other:
162 b
176 b
163 all copies found (* = to merge, ! = divergent):
177 all copies found (* = to merge, ! = divergent):
164 b -> a
178 b -> a
165 checking for directory renames
179 checking for directory renames
166 a: other deleted -> r
180 a: other deleted -> r
167 rev: versions differ -> m
181 rev: versions differ -> m
168 b: remote created -> g
182 b: remote created -> g
169 removing a
183 removing a
170 getting b
184 getting b
185 picked tool 'python ../merge' for rev (binary False symlink False)
171 merging rev
186 merging rev
172 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
187 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
173 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
188 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
174 (branch merge, don't forget to commit)
189 (branch merge, don't forget to commit)
175 --------------
190 --------------
176 M b
191 M b
177 --------------
192 --------------
178
193
179 --------------
194 --------------
180 test L:nm a b R: W: - 8 nothing
195 test L:nm a b R: W: - 8 nothing
181 --------------
196 --------------
182 resolving manifests
197 resolving manifests
183 overwrite None partial False
198 overwrite None partial False
184 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
199 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
185 searching for copies back to rev 1
200 searching for copies back to rev 1
186 unmatched files in local:
201 unmatched files in local:
187 b
202 b
188 all copies found (* = to merge, ! = divergent):
203 all copies found (* = to merge, ! = divergent):
189 b -> a
204 b -> a
190 checking for directory renames
205 checking for directory renames
191 rev: versions differ -> m
206 rev: versions differ -> m
207 picked tool 'python ../merge' for rev (binary False symlink False)
192 merging rev
208 merging rev
193 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
209 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
194 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
210 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
195 (branch merge, don't forget to commit)
211 (branch merge, don't forget to commit)
196 --------------
212 --------------
197 C b
213 C b
198 --------------
214 --------------
199
215
200 --------------
216 --------------
201 test L:um a b R:um a b W: - 9 do merge with ancestor in a
217 test L:um a b R:um a b W: - 9 do merge with ancestor in a
202 --------------
218 --------------
203 resolving manifests
219 resolving manifests
204 overwrite None partial False
220 overwrite None partial False
205 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
221 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
206 searching for copies back to rev 1
222 searching for copies back to rev 1
207 b: versions differ -> m
223 b: versions differ -> m
208 rev: versions differ -> m
224 rev: versions differ -> m
225 picked tool 'python ../merge' for b (binary False symlink False)
209 merging b
226 merging b
210 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
227 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
228 picked tool 'python ../merge' for rev (binary False symlink False)
211 merging rev
229 merging rev
212 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
230 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
213 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
231 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
214 (branch merge, don't forget to commit)
232 (branch merge, don't forget to commit)
215 --------------
233 --------------
216 M b
234 M b
217 --------------
235 --------------
218
236
219 --------------
237 --------------
220 test L:nm a b R:nm a c W: - 11 get c, keep b
238 test L:nm a b R:nm a c W: - 11 get c, keep b
221 --------------
239 --------------
222 resolving manifests
240 resolving manifests
223 overwrite None partial False
241 overwrite None partial False
224 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
242 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
225 searching for copies back to rev 1
243 searching for copies back to rev 1
226 unmatched files in local:
244 unmatched files in local:
227 b
245 b
228 unmatched files in other:
246 unmatched files in other:
229 c
247 c
230 all copies found (* = to merge, ! = divergent):
248 all copies found (* = to merge, ! = divergent):
231 c -> a !
249 c -> a !
232 b -> a !
250 b -> a !
233 checking for directory renames
251 checking for directory renames
234 a: divergent renames -> dr
252 a: divergent renames -> dr
235 rev: versions differ -> m
253 rev: versions differ -> m
236 c: remote created -> g
254 c: remote created -> g
237 warning: detected divergent renames of a to:
255 warning: detected divergent renames of a to:
238 b
256 b
239 c
257 c
240 getting c
258 getting c
259 picked tool 'python ../merge' for rev (binary False symlink False)
241 merging rev
260 merging rev
242 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
261 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
243 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
262 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
244 (branch merge, don't forget to commit)
263 (branch merge, don't forget to commit)
245 --------------
264 --------------
246 M c
265 M c
247 C b
266 C b
248 --------------
267 --------------
249
268
250 --------------
269 --------------
251 test L:nc a b R:up b W: - 12 merge b no ancestor
270 test L:nc a b R:up b W: - 12 merge b no ancestor
252 --------------
271 --------------
253 resolving manifests
272 resolving manifests
254 overwrite None partial False
273 overwrite None partial False
255 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
274 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
256 searching for copies back to rev 1
275 searching for copies back to rev 1
257 b: versions differ -> m
276 b: versions differ -> m
258 rev: versions differ -> m
277 rev: versions differ -> m
278 picked tool 'python ../merge' for b (binary False symlink False)
259 merging b
279 merging b
260 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
280 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
281 picked tool 'python ../merge' for rev (binary False symlink False)
261 merging rev
282 merging rev
262 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
283 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
263 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
284 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
264 (branch merge, don't forget to commit)
285 (branch merge, don't forget to commit)
265 --------------
286 --------------
266 M b
287 M b
267 C a
288 C a
268 --------------
289 --------------
269
290
270 --------------
291 --------------
271 test L:up b R:nm a b W: - 13 merge b no ancestor
292 test L:up b R:nm a b W: - 13 merge b no ancestor
272 --------------
293 --------------
273 resolving manifests
294 resolving manifests
274 overwrite None partial False
295 overwrite None partial False
275 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
296 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
276 searching for copies back to rev 1
297 searching for copies back to rev 1
277 a: other deleted -> r
298 a: other deleted -> r
278 b: versions differ -> m
299 b: versions differ -> m
279 rev: versions differ -> m
300 rev: versions differ -> m
280 removing a
301 removing a
302 picked tool 'python ../merge' for b (binary False symlink False)
281 merging b
303 merging b
282 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
304 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
305 picked tool 'python ../merge' for rev (binary False symlink False)
283 merging rev
306 merging rev
284 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
307 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
285 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
308 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
286 (branch merge, don't forget to commit)
309 (branch merge, don't forget to commit)
287 --------------
310 --------------
288 M b
311 M b
289 --------------
312 --------------
290
313
291 --------------
314 --------------
292 test L:nc a b R:up a b W: - 14 merge b no ancestor
315 test L:nc a b R:up a b W: - 14 merge b no ancestor
293 --------------
316 --------------
294 resolving manifests
317 resolving manifests
295 overwrite None partial False
318 overwrite None partial False
296 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
319 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
297 searching for copies back to rev 1
320 searching for copies back to rev 1
298 a: remote is newer -> g
321 a: remote is newer -> g
299 b: versions differ -> m
322 b: versions differ -> m
300 rev: versions differ -> m
323 rev: versions differ -> m
301 getting a
324 getting a
325 picked tool 'python ../merge' for b (binary False symlink False)
302 merging b
326 merging b
303 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
327 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
328 picked tool 'python ../merge' for rev (binary False symlink False)
304 merging rev
329 merging rev
305 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
330 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
306 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
331 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
307 (branch merge, don't forget to commit)
332 (branch merge, don't forget to commit)
308 --------------
333 --------------
309 M a
334 M a
310 M b
335 M b
311 --------------
336 --------------
312
337
313 --------------
338 --------------
314 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
339 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
315 --------------
340 --------------
316 resolving manifests
341 resolving manifests
317 overwrite None partial False
342 overwrite None partial False
318 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
343 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
319 searching for copies back to rev 1
344 searching for copies back to rev 1
320 a: other deleted -> r
345 a: other deleted -> r
321 b: versions differ -> m
346 b: versions differ -> m
322 rev: versions differ -> m
347 rev: versions differ -> m
323 removing a
348 removing a
349 picked tool 'python ../merge' for b (binary False symlink False)
324 merging b
350 merging b
325 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
351 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
352 picked tool 'python ../merge' for rev (binary False symlink False)
326 merging rev
353 merging rev
327 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
354 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
328 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
355 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
329 (branch merge, don't forget to commit)
356 (branch merge, don't forget to commit)
330 --------------
357 --------------
331 M b
358 M b
332 --------------
359 --------------
333
360
334 --------------
361 --------------
335 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
362 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
336 --------------
363 --------------
337 resolving manifests
364 resolving manifests
338 overwrite None partial False
365 overwrite None partial False
339 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
366 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
340 searching for copies back to rev 1
367 searching for copies back to rev 1
341 a: remote is newer -> g
368 a: remote is newer -> g
342 b: versions differ -> m
369 b: versions differ -> m
343 rev: versions differ -> m
370 rev: versions differ -> m
344 getting a
371 getting a
372 picked tool 'python ../merge' for b (binary False symlink False)
345 merging b
373 merging b
346 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
374 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
375 picked tool 'python ../merge' for rev (binary False symlink False)
347 merging rev
376 merging rev
348 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
377 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
349 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
378 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
350 (branch merge, don't forget to commit)
379 (branch merge, don't forget to commit)
351 --------------
380 --------------
352 M a
381 M a
353 M b
382 M b
354 --------------
383 --------------
355
384
356 --------------
385 --------------
357 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
386 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
358 --------------
387 --------------
359 resolving manifests
388 resolving manifests
360 overwrite None partial False
389 overwrite None partial False
361 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
390 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
362 searching for copies back to rev 1
391 searching for copies back to rev 1
363 b: versions differ -> m
392 b: versions differ -> m
364 rev: versions differ -> m
393 rev: versions differ -> m
394 picked tool 'python ../merge' for b (binary False symlink False)
365 merging b
395 merging b
366 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
396 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
397 picked tool 'python ../merge' for rev (binary False symlink False)
367 merging rev
398 merging rev
368 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
399 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
369 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
400 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
370 (branch merge, don't forget to commit)
401 (branch merge, don't forget to commit)
371 --------------
402 --------------
372 M b
403 M b
373 C a
404 C a
374 --------------
405 --------------
375
406
376 --------------
407 --------------
377 test L:nm a b R:up a b W: - 18 merge b no ancestor
408 test L:nm a b R:up a b W: - 18 merge b no ancestor
378 --------------
409 --------------
379 resolving manifests
410 resolving manifests
380 overwrite None partial False
411 overwrite None partial False
381 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
412 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
382 searching for copies back to rev 1
413 searching for copies back to rev 1
383 b: versions differ -> m
414 b: versions differ -> m
384 rev: versions differ -> m
415 rev: versions differ -> m
385 a: prompt recreating -> g
416 a: prompt recreating -> g
386 getting a
417 getting a
418 picked tool 'python ../merge' for b (binary False symlink False)
387 merging b
419 merging b
388 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
420 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
421 picked tool 'python ../merge' for rev (binary False symlink False)
389 merging rev
422 merging rev
390 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
423 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
391 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
424 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
392 (branch merge, don't forget to commit)
425 (branch merge, don't forget to commit)
393 --------------
426 --------------
394 M a
427 M a
395 M b
428 M b
396 --------------
429 --------------
397
430
398 --------------
431 --------------
399 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
432 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
400 --------------
433 --------------
401 resolving manifests
434 resolving manifests
402 overwrite None partial False
435 overwrite None partial False
403 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
436 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
404 searching for copies back to rev 1
437 searching for copies back to rev 1
405 b: versions differ -> m
438 b: versions differ -> m
406 rev: versions differ -> m
439 rev: versions differ -> m
440 picked tool 'python ../merge' for b (binary False symlink False)
407 merging b
441 merging b
408 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
442 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
443 picked tool 'python ../merge' for rev (binary False symlink False)
409 merging rev
444 merging rev
410 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
445 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
411 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
446 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
412 (branch merge, don't forget to commit)
447 (branch merge, don't forget to commit)
413 --------------
448 --------------
414 M b
449 M b
415 C a
450 C a
416 --------------
451 --------------
417
452
418 --------------
453 --------------
419 test L:up a R:um a b W: - 20 merge a and b to b, remove a
454 test L:up a R:um a b W: - 20 merge a and b to b, remove a
420 --------------
455 --------------
421 resolving manifests
456 resolving manifests
422 overwrite None partial False
457 overwrite None partial False
423 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
458 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
424 searching for copies back to rev 1
459 searching for copies back to rev 1
425 unmatched files in other:
460 unmatched files in other:
426 b
461 b
427 all copies found (* = to merge, ! = divergent):
462 all copies found (* = to merge, ! = divergent):
428 b -> a *
463 b -> a *
429 checking for directory renames
464 checking for directory renames
430 rev: versions differ -> m
465 rev: versions differ -> m
431 a: remote moved to b -> m
466 a: remote moved to b -> m
432 copying a to b
467 copying a to b
468 picked tool 'python ../merge' for a (binary False symlink False)
433 merging a and b
469 merging a and b
434 my a@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
470 my a@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
435 removing a
471 removing a
472 picked tool 'python ../merge' for rev (binary False symlink False)
436 merging rev
473 merging rev
437 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
474 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
438 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
475 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
439 (branch merge, don't forget to commit)
476 (branch merge, don't forget to commit)
440 --------------
477 --------------
441 M b
478 M b
442 a
479 a
443 --------------
480 --------------
444
481
445 --------------
482 --------------
446 test L:um a b R:up a W: - 21 merge a and b to b
483 test L:um a b R:up a W: - 21 merge a and b to b
447 --------------
484 --------------
448 resolving manifests
485 resolving manifests
449 overwrite None partial False
486 overwrite None partial False
450 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
487 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
451 searching for copies back to rev 1
488 searching for copies back to rev 1
452 unmatched files in local:
489 unmatched files in local:
453 b
490 b
454 all copies found (* = to merge, ! = divergent):
491 all copies found (* = to merge, ! = divergent):
455 b -> a *
492 b -> a *
456 checking for directory renames
493 checking for directory renames
457 b: local moved to a -> m
494 b: local moved to a -> m
458 rev: versions differ -> m
495 rev: versions differ -> m
496 picked tool 'python ../merge' for b (binary False symlink False)
459 merging b and a
497 merging b and a
460 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
498 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
499 picked tool 'python ../merge' for rev (binary False symlink False)
461 merging rev
500 merging rev
462 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
501 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
463 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
502 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
464 (branch merge, don't forget to commit)
503 (branch merge, don't forget to commit)
465 --------------
504 --------------
466 M b
505 M b
467 a
506 a
468 --------------
507 --------------
469
508
470 --------------
509 --------------
471 test L:nm a b R:up a c W: - 23 get c, keep b
510 test L:nm a b R:up a c W: - 23 get c, keep b
472 --------------
511 --------------
473 resolving manifests
512 resolving manifests
474 overwrite None partial False
513 overwrite None partial False
475 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
514 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
476 searching for copies back to rev 1
515 searching for copies back to rev 1
477 unmatched files in local:
516 unmatched files in local:
478 b
517 b
479 unmatched files in other:
518 unmatched files in other:
480 c
519 c
481 all copies found (* = to merge, ! = divergent):
520 all copies found (* = to merge, ! = divergent):
482 b -> a *
521 b -> a *
483 checking for directory renames
522 checking for directory renames
484 b: local moved to a -> m
523 b: local moved to a -> m
485 rev: versions differ -> m
524 rev: versions differ -> m
486 c: remote created -> g
525 c: remote created -> g
526 picked tool 'python ../merge' for b (binary False symlink False)
487 merging b and a
527 merging b and a
488 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
528 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
529 premerge successful
489 getting c
530 getting c
531 picked tool 'python ../merge' for rev (binary False symlink False)
490 merging rev
532 merging rev
491 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
533 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
492 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
534 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
493 (branch merge, don't forget to commit)
535 (branch merge, don't forget to commit)
494 --------------
536 --------------
495 M b
537 M b
496 a
538 a
497 M c
539 M c
498 --------------
540 --------------
499
541
@@ -1,143 +1,147 b''
1 adding a
1 adding a
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 diff -r 33aaa84a386b a
4 diff -r 33aaa84a386b a
5 --- a/a
5 --- a/a
6 +++ b/a
6 +++ b/a
7 @@ -1,1 +1,1 @@
7 @@ -1,1 +1,1 @@
8 -a
8 -a
9 +abc
9 +abc
10 adding b
10 adding b
11 M a
11 M a
12 changeset: 0:33aaa84a386b
12 changeset: 0:33aaa84a386b
13 user: test
13 user: test
14 date: Mon Jan 12 13:46:40 1970 +0000
14 date: Mon Jan 12 13:46:40 1970 +0000
15 summary: 1
15 summary: 1
16
16
17 resolving manifests
17 resolving manifests
18 overwrite False partial False
18 overwrite False partial False
19 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
19 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
20 searching for copies back to rev 1
20 searching for copies back to rev 1
21 unmatched files in other:
21 unmatched files in other:
22 b
22 b
23 a: versions differ -> m
23 a: versions differ -> m
24 b: remote created -> g
24 b: remote created -> g
25 picked tool 'true' for a (binary False symlink False)
25 merging a
26 merging a
26 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
27 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
27 getting b
28 getting b
28 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
29 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
29 changeset: 1:802f095af299
30 changeset: 1:802f095af299
30 tag: tip
31 tag: tip
31 user: test
32 user: test
32 date: Mon Jan 12 13:46:40 1970 +0000
33 date: Mon Jan 12 13:46:40 1970 +0000
33 summary: 2
34 summary: 2
34
35
35 resolving manifests
36 resolving manifests
36 overwrite False partial False
37 overwrite False partial False
37 ancestor 33aaa84a386b local 802f095af299+ remote 33aaa84a386b
38 ancestor 33aaa84a386b local 802f095af299+ remote 33aaa84a386b
38 b: remote deleted -> r
39 b: remote deleted -> r
39 removing b
40 removing b
40 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
41 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
41 changeset: 0:33aaa84a386b
42 changeset: 0:33aaa84a386b
42 user: test
43 user: test
43 date: Mon Jan 12 13:46:40 1970 +0000
44 date: Mon Jan 12 13:46:40 1970 +0000
44 summary: 1
45 summary: 1
45
46
46 abort: there is nothing to merge - use "hg update" instead
47 abort: there is nothing to merge - use "hg update" instead
47 failed
48 failed
48 changeset: 0:33aaa84a386b
49 changeset: 0:33aaa84a386b
49 user: test
50 user: test
50 date: Mon Jan 12 13:46:40 1970 +0000
51 date: Mon Jan 12 13:46:40 1970 +0000
51 summary: 1
52 summary: 1
52
53
53 resolving manifests
54 resolving manifests
54 overwrite False partial False
55 overwrite False partial False
55 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
56 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
56 searching for copies back to rev 1
57 searching for copies back to rev 1
57 unmatched files in other:
58 unmatched files in other:
58 b
59 b
59 a: versions differ -> m
60 a: versions differ -> m
60 b: remote created -> g
61 b: remote created -> g
62 picked tool 'true' for a (binary False symlink False)
61 merging a
63 merging a
62 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
64 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
63 getting b
65 getting b
64 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
66 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
65 changeset: 1:802f095af299
67 changeset: 1:802f095af299
66 tag: tip
68 tag: tip
67 user: test
69 user: test
68 date: Mon Jan 12 13:46:40 1970 +0000
70 date: Mon Jan 12 13:46:40 1970 +0000
69 summary: 2
71 summary: 2
70
72
71 changeset: 1:802f095af299
73 changeset: 1:802f095af299
72 tag: tip
74 tag: tip
73 user: test
75 user: test
74 date: Mon Jan 12 13:46:40 1970 +0000
76 date: Mon Jan 12 13:46:40 1970 +0000
75 files: a b
77 files: a b
76 description:
78 description:
77 2
79 2
78
80
79
81
80 changeset: 0:33aaa84a386b
82 changeset: 0:33aaa84a386b
81 user: test
83 user: test
82 date: Mon Jan 12 13:46:40 1970 +0000
84 date: Mon Jan 12 13:46:40 1970 +0000
83 files: a
85 files: a
84 description:
86 description:
85 1
87 1
86
88
87
89
88 diff -r 802f095af299 a
90 diff -r 802f095af299 a
89 --- a/a
91 --- a/a
90 +++ b/a
92 +++ b/a
91 @@ -1,1 +1,1 @@
93 @@ -1,1 +1,1 @@
92 -a2
94 -a2
93 +abc
95 +abc
94 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
96 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
95 adding b
97 adding b
96 M a
98 M a
97 changeset: 1:802f095af299
99 changeset: 1:802f095af299
98 user: test
100 user: test
99 date: Mon Jan 12 13:46:40 1970 +0000
101 date: Mon Jan 12 13:46:40 1970 +0000
100 summary: 2
102 summary: 2
101
103
102 abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
104 abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
103 failed
105 failed
104 abort: outstanding uncommitted changes
106 abort: outstanding uncommitted changes
105 failed
107 failed
106 resolving manifests
108 resolving manifests
107 overwrite False partial False
109 overwrite False partial False
108 ancestor 33aaa84a386b local 802f095af299+ remote 030602aee63d
110 ancestor 33aaa84a386b local 802f095af299+ remote 030602aee63d
109 searching for copies back to rev 1
111 searching for copies back to rev 1
110 a: versions differ -> m
112 a: versions differ -> m
111 b: versions differ -> m
113 b: versions differ -> m
114 picked tool 'true' for a (binary False symlink False)
112 merging a
115 merging a
113 my a@802f095af299+ other a@030602aee63d ancestor a@33aaa84a386b
116 my a@802f095af299+ other a@030602aee63d ancestor a@33aaa84a386b
117 picked tool 'true' for b (binary False symlink False)
114 merging b
118 merging b
115 my b@802f095af299+ other b@030602aee63d ancestor b@000000000000
119 my b@802f095af299+ other b@030602aee63d ancestor b@000000000000
116 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
120 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
117 (branch merge, don't forget to commit)
121 (branch merge, don't forget to commit)
118 changeset: 1:802f095af299
122 changeset: 1:802f095af299
119 user: test
123 user: test
120 date: Mon Jan 12 13:46:40 1970 +0000
124 date: Mon Jan 12 13:46:40 1970 +0000
121 summary: 2
125 summary: 2
122
126
123 changeset: 2:030602aee63d
127 changeset: 2:030602aee63d
124 tag: tip
128 tag: tip
125 parent: 0:33aaa84a386b
129 parent: 0:33aaa84a386b
126 user: test
130 user: test
127 date: Mon Jan 12 13:46:40 1970 +0000
131 date: Mon Jan 12 13:46:40 1970 +0000
128 summary: 3
132 summary: 3
129
133
130 diff -r 802f095af299 a
134 diff -r 802f095af299 a
131 --- a/a
135 --- a/a
132 +++ b/a
136 +++ b/a
133 @@ -1,1 +1,1 @@
137 @@ -1,1 +1,1 @@
134 -a2
138 -a2
135 +abc
139 +abc
136 adding a
140 adding a
137 pulling from ../a
141 pulling from ../a
138 requesting all changes
142 requesting all changes
139 adding changesets
143 adding changesets
140 adding manifests
144 adding manifests
141 adding file changes
145 adding file changes
142 added 1 changesets with 1 changes to 1 files
146 added 1 changesets with 1 changes to 1 files
143 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
General Comments 0
You need to be logged in to leave comments. Login now