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