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