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