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