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