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