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