##// END OF EJS Templates
migrate remaining commands...
mpm@selenic.com -
r248:b7645b3c default
parent child Browse files
Show More
@@ -1,121 +1,23 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # mercurial - a minimal scalable distributed SCM
3 # mercurial - a minimal scalable distributed SCM
4 # v0.5b "katje"
4 # v0.5b "katje"
5 #
5 #
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
7 #
7 #
8 # This software may be used and distributed according to the terms
8 # This software may be used and distributed according to the terms
9 # of the GNU General Public License, incorporated herein by reference.
9 # of the GNU General Public License, incorporated herein by reference.
10
10
11 # the psyco compiler makes commits a bit faster
11 # the psyco compiler makes commits a bit faster
12 # and makes changegroup merge about 20 times slower!
12 # and makes changegroup merge about 20 times slower!
13 # try:
13 # try:
14 # import psyco
14 # import psyco
15 # psyco.full()
15 # psyco.full()
16 # except:
16 # except:
17 # pass
17 # pass
18
18
19 import sys
19 import sys
20 from mercurial import hg, fancyopts, ui, commands
20 from mercurial import commands
21
22 try:
23 sys.exit(commands.dispatch(sys.argv[1:]))
24 except commands.UnknownCommand:
25 # fall through
26 pass
27
28 options = {}
29 opts = [('v', 'verbose', None, 'verbose'),
30 ('d', 'debug', None, 'debug'),
31 ('q', 'quiet', None, 'quiet'),
32 ('y', 'noninteractive', None, 'run non-interactively'),
33 ]
34
35 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
36 'hg [options] <command> [command options] [files]')
37
38 try:
39 cmd = args[0]
40 args = args[1:]
41 except:
42 cmd = "help"
43
44 ui = ui.ui(options["verbose"], options["debug"], options["quiet"],
45 not options["noninteractive"])
46
47 try:
48 repo = hg.repository(ui=ui)
49 except IOError:
50 ui.warn("Unable to open repository\n")
51 sys.exit(0)
52
53 if cmd == "debugchangegroup":
54 newer = repo.newer(map(repo.lookup, args))
55 for chunk in repo.changegroup(newer):
56 sys.stdout.write(chunk)
57
58 elif cmd == "debugaddchangegroup":
59 data = sys.stdin.read()
60 repo.addchangegroup(data)
61
62 elif cmd == "dump":
63 if args:
64 r = repo.file(args[0])
65 n = r.tip()
66 if len(args) > 1: n = r.lookup(args[1])
67 sys.stdout.write(r.read(n))
68 else:
69 print "missing filename"
70
21
71 elif cmd == "dumpmanifest":
22 sys.exit(commands.dispatch(sys.argv[1:]))
72 n = repo.manifest.tip()
73 if len(args) > 0:
74 n = repo.manifest.lookup(args[0])
75 m = repo.manifest.read(n)
76 files = m.keys()
77 files.sort()
78
79 for f in files:
80 print hg.hex(m[f]), f
81
82 elif cmd == "debugindex":
83 if ".hg" not in args[0]:
84 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
85
86 r = hg.revlog(open, args[0], "")
87 print " rev offset length base linkrev"+\
88 " p1 p2 nodeid"
89 for i in range(r.count()):
90 e = r.index[i]
91 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
92 i, e[0], e[1], e[2], e[3],
93 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
94
23
95 elif cmd == "debugindexdot":
96 if ".hg" not in args[0]:
97 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
98
99 r = hg.revlog(open, args[0], "")
100 print "digraph G {"
101 for i in range(r.count()):
102 e = r.index[i]
103 print "\t%d -> %d" % (r.rev(e[4]), i)
104 if e[5] != hg.nullid:
105 print "\t%d -> %d" % (r.rev(e[5]), i)
106 print "}"
107
108 elif cmd == "tags":
109 repo.lookup(0) # prime the cache
110 i = repo.tags.items()
111 i.sort()
112 for k, n in i:
113 try:
114 r = repo.changelog.rev(n)
115 except KeyError:
116 r = "?"
117 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
118
119 else:
120 if cmd: ui.warn("unknown command\n\n")
121 sys.exit(1)
@@ -1,507 +1,571 b''
1 import os, re, traceback, sys, signal, time, mdiff
1 import os, re, traceback, sys, signal, time, mdiff
2 from mercurial import fancyopts, ui, hg
2 from mercurial import fancyopts, ui, hg
3
3
4 class UnknownCommand(Exception): pass
4 class UnknownCommand(Exception): pass
5
5
6 def filterfiles(filters, files):
6 def filterfiles(filters, files):
7 l = [ x for x in files if x in filters ]
7 l = [ x for x in files if x in filters ]
8
8
9 for t in filters:
9 for t in filters:
10 if t and t[-1] != os.sep: t += os.sep
10 if t and t[-1] != os.sep: t += os.sep
11 l += [ x for x in files if x.startswith(t) ]
11 l += [ x for x in files if x.startswith(t) ]
12 return l
12 return l
13
13
14 def relfilter(repo, files):
14 def relfilter(repo, files):
15 if os.getcwd() != repo.root:
15 if os.getcwd() != repo.root:
16 p = os.getcwd()[len(repo.root) + 1: ]
16 p = os.getcwd()[len(repo.root) + 1: ]
17 return filterfiles(p, files)
17 return filterfiles(p, files)
18 return files
18 return files
19
19
20 def relpath(repo, args):
20 def relpath(repo, args):
21 if os.getcwd() != repo.root:
21 if os.getcwd() != repo.root:
22 p = os.getcwd()[len(repo.root) + 1: ]
22 p = os.getcwd()[len(repo.root) + 1: ]
23 return [ os.path.normpath(os.path.join(p, x)) for x in args ]
23 return [ os.path.normpath(os.path.join(p, x)) for x in args ]
24 return args
24 return args
25
25
26 def dodiff(repo, files = None, node1 = None, node2 = None):
26 def dodiff(repo, files = None, node1 = None, node2 = None):
27 def date(c):
27 def date(c):
28 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
28 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
29
29
30 if node2:
30 if node2:
31 change = repo.changelog.read(node2)
31 change = repo.changelog.read(node2)
32 mmap2 = repo.manifest.read(change[0])
32 mmap2 = repo.manifest.read(change[0])
33 (c, a, d) = repo.diffrevs(node1, node2)
33 (c, a, d) = repo.diffrevs(node1, node2)
34 def read(f): return repo.file(f).read(mmap2[f])
34 def read(f): return repo.file(f).read(mmap2[f])
35 date2 = date(change)
35 date2 = date(change)
36 else:
36 else:
37 date2 = time.asctime()
37 date2 = time.asctime()
38 (c, a, d, u) = repo.diffdir(repo.root, node1)
38 (c, a, d, u) = repo.diffdir(repo.root, node1)
39 if not node1:
39 if not node1:
40 node1 = repo.dirstate.parents()[0]
40 node1 = repo.dirstate.parents()[0]
41 def read(f): return file(os.path.join(repo.root, f)).read()
41 def read(f): return file(os.path.join(repo.root, f)).read()
42
42
43 change = repo.changelog.read(node1)
43 change = repo.changelog.read(node1)
44 mmap = repo.manifest.read(change[0])
44 mmap = repo.manifest.read(change[0])
45 date1 = date(change)
45 date1 = date(change)
46
46
47 if files:
47 if files:
48 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
48 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
49
49
50 for f in c:
50 for f in c:
51 to = repo.file(f).read(mmap[f])
51 to = repo.file(f).read(mmap[f])
52 tn = read(f)
52 tn = read(f)
53 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
53 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
54 for f in a:
54 for f in a:
55 to = ""
55 to = ""
56 tn = read(f)
56 tn = read(f)
57 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
57 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
58 for f in d:
58 for f in d:
59 to = repo.file(f).read(mmap[f])
59 to = repo.file(f).read(mmap[f])
60 tn = ""
60 tn = ""
61 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
61 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
62
62
63 def help(ui, cmd=None):
63 def help(ui, cmd=None):
64 '''show help'''
64 '''show help'''
65 if cmd:
65 if cmd:
66 try:
66 try:
67 i = find(cmd)
67 i = find(cmd)
68 ui.write("%s\n\n" % i[2])
68 ui.write("%s\n\n" % i[2])
69 ui.write(i[0].__doc__, "\n")
69 ui.write(i[0].__doc__, "\n")
70 except UnknownCommand:
70 except UnknownCommand:
71 ui.warn("unknown command %s", cmd)
71 ui.warn("unknown command %s", cmd)
72 sys.exit(0)
72 sys.exit(0)
73
73
74 ui.status("""\
74 ui.status("""\
75 hg commands:
75 hg commands:
76
76
77 add [files...] add the given files in the next commit
77 add [files...] add the given files in the next commit
78 addremove add all new files, delete all missing files
78 addremove add all new files, delete all missing files
79 annotate [files...] show changeset number per file line
79 annotate [files...] show changeset number per file line
80 branch <path> create a branch of <path> in this directory
80 branch <path> create a branch of <path> in this directory
81 checkout [changeset] checkout the latest or given changeset
81 checkout [changeset] checkout the latest or given changeset
82 commit commit all changes to the repository
82 commit commit all changes to the repository
83 diff [files...] diff working directory (or selected files)
83 diff [files...] diff working directory (or selected files)
84 dump <file> [rev] dump the latest or given revision of a file
84 dump <file> [rev] dump the latest or given revision of a file
85 dumpmanifest [rev] dump the latest or given revision of the manifest
85 dumpmanifest [rev] dump the latest or given revision of the manifest
86 export <rev> dump the changeset header and diffs for a revision
86 export <rev> dump the changeset header and diffs for a revision
87 history show changeset history
87 history show changeset history
88 init create a new repository in this directory
88 init create a new repository in this directory
89 log <file> show revision history of a single file
89 log <file> show revision history of a single file
90 merge <path> merge changes from <path> into local repository
90 merge <path> merge changes from <path> into local repository
91 recover rollback an interrupted transaction
91 recover rollback an interrupted transaction
92 remove [files...] remove the given files in the next commit
92 remove [files...] remove the given files in the next commit
93 serve export the repository via HTTP
93 serve export the repository via HTTP
94 status show new, missing, and changed files in working dir
94 status show new, missing, and changed files in working dir
95 tags show current changeset tags
95 tags show current changeset tags
96 undo undo the last transaction
96 undo undo the last transaction
97 """)
97 """)
98
98
99 def add(ui, repo, file, *files):
99 def add(ui, repo, file, *files):
100 '''add the specified files on the next commit'''
100 '''add the specified files on the next commit'''
101 repo.add(relpath(repo, (file,) + files))
101 repo.add(relpath(repo, (file,) + files))
102
102
103 def addremove(ui, repo):
103 def addremove(ui, repo):
104 (c, a, d, u) = repo.diffdir(repo.root)
104 (c, a, d, u) = repo.diffdir(repo.root)
105 repo.add(a)
105 repo.add(a)
106 repo.remove(d)
106 repo.remove(d)
107
107
108 def annotate(u, repo, file, *files, **ops):
108 def annotate(u, repo, file, *files, **ops):
109 def getnode(rev):
109 def getnode(rev):
110 return hg.short(repo.changelog.node(rev))
110 return hg.short(repo.changelog.node(rev))
111
111
112 def getname(rev):
112 def getname(rev):
113 try:
113 try:
114 return bcache[rev]
114 return bcache[rev]
115 except KeyError:
115 except KeyError:
116 cl = repo.changelog.read(repo.changelog.node(rev))
116 cl = repo.changelog.read(repo.changelog.node(rev))
117 name = cl[1]
117 name = cl[1]
118 f = name.find('@')
118 f = name.find('@')
119 if f >= 0:
119 if f >= 0:
120 name = name[:f]
120 name = name[:f]
121 bcache[rev] = name
121 bcache[rev] = name
122 return name
122 return name
123
123
124 bcache = {}
124 bcache = {}
125 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
125 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
126 if not ops['user'] and not ops['changeset']:
126 if not ops['user'] and not ops['changeset']:
127 ops['number'] = 1
127 ops['number'] = 1
128
128
129 node = repo.dirstate.parents()[0]
129 node = repo.dirstate.parents()[0]
130 if ops['revision']:
130 if ops['revision']:
131 node = repo.changelog.lookup(ops['revision'])
131 node = repo.changelog.lookup(ops['revision'])
132 change = repo.changelog.read(node)
132 change = repo.changelog.read(node)
133 mmap = repo.manifest.read(change[0])
133 mmap = repo.manifest.read(change[0])
134 maxuserlen = 0
134 maxuserlen = 0
135 maxchangelen = 0
135 maxchangelen = 0
136 for f in relpath(repo, (file,) + files):
136 for f in relpath(repo, (file,) + files):
137 lines = repo.file(f).annotate(mmap[f])
137 lines = repo.file(f).annotate(mmap[f])
138 pieces = []
138 pieces = []
139
139
140 for o, f in opmap:
140 for o, f in opmap:
141 if ops[o]:
141 if ops[o]:
142 l = [ f(n) for n,t in lines ]
142 l = [ f(n) for n,t in lines ]
143 m = max(map(len, l))
143 m = max(map(len, l))
144 pieces.append([ "%*s" % (m, x) for x in l])
144 pieces.append([ "%*s" % (m, x) for x in l])
145
145
146 for p,l in zip(zip(*pieces), lines):
146 for p,l in zip(zip(*pieces), lines):
147 u.write(" ".join(p) + ": " + l[1])
147 u.write(" ".join(p) + ": " + l[1])
148
148
149 def branch(ui, path):
149 def branch(ui, path):
150 '''branch from a local repository'''
150 '''branch from a local repository'''
151 # this should eventually support remote repos
151 # this should eventually support remote repos
152 os.system("cp -al %s/.hg .hg" % path)
152 os.system("cp -al %s/.hg .hg" % path)
153
153
154 def cat(ui, repo, file, rev = []):
155 r = repo.file(file)
156 n = r.tip()
157 if rev: n = r.lookup(rev)
158 sys.stdout.write(r.read(n))
159
154 def checkout(ui, repo, changeset=None):
160 def checkout(ui, repo, changeset=None):
155 '''checkout a given changeset or the current tip'''
161 '''checkout a given changeset or the current tip'''
156 (c, a, d, u) = repo.diffdir(repo.root)
162 (c, a, d, u) = repo.diffdir(repo.root)
157 if c or a or d:
163 if c or a or d:
158 ui.warn("aborting (outstanding changes in working directory)\n")
164 ui.warn("aborting (outstanding changes in working directory)\n")
159 sys.exit(1)
165 sys.exit(1)
160
166
161 node = repo.changelog.tip()
167 node = repo.changelog.tip()
162 if changeset:
168 if changeset:
163 node = repo.lookup(changeset)
169 node = repo.lookup(changeset)
164 repo.checkout(node)
170 repo.checkout(node)
165
171
166 def commit(ui, repo, *files):
172 def commit(ui, repo, *files):
167 """commit the specified files or all outstanding changes"""
173 """commit the specified files or all outstanding changes"""
168 repo.commit(relpath(repo, files))
174 repo.commit(relpath(repo, files))
169
175
176 def debugaddchangegroup(ui, repo):
177 data = sys.stdin.read()
178 repo.addchangegroup(data)
179
180 def debugchangegroup(ui, repo, roots):
181 newer = repo.newer(map(repo.lookup, roots))
182 for chunk in repo.changegroup(newer):
183 sys.stdout.write(chunk)
184
185 def debugindex(ui, file):
186 r = hg.revlog(open, file, "")
187 print " rev offset length base linkrev"+\
188 " p1 p2 nodeid"
189 for i in range(r.count()):
190 e = r.index[i]
191 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
192 i, e[0], e[1], e[2], e[3],
193 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
194
195 def debugindexdot(ui, file):
196 r = hg.revlog(open, file, "")
197 print "digraph G {"
198 for i in range(r.count()):
199 e = r.index[i]
200 print "\t%d -> %d" % (r.rev(e[4]), i)
201 if e[5] != hg.nullid:
202 print "\t%d -> %d" % (r.rev(e[5]), i)
203 print "}"
204
170 def diff(ui, repo, *files, **opts):
205 def diff(ui, repo, *files, **opts):
171 revs = []
206 revs = []
172 if opts['rev']:
207 if opts['rev']:
173 revs = map(lambda x: repo.lookup(x), opts['rev'])
208 revs = map(lambda x: repo.lookup(x), opts['rev'])
174
209
175 if len(revs) > 2:
210 if len(revs) > 2:
176 self.ui.warn("too many revisions to diff\n")
211 self.ui.warn("too many revisions to diff\n")
177 sys.exit(1)
212 sys.exit(1)
178
213
179 if files:
214 if files:
180 files = relpath(repo, files)
215 files = relpath(repo, files)
181 else:
216 else:
182 files = relpath(repo, [""])
217 files = relpath(repo, [""])
183
218
184 dodiff(repo, files, *revs)
219 dodiff(repo, files, *revs)
185
220
186 def export(ui, repo, changeset):
221 def export(ui, repo, changeset):
187 node = repo.lookup(changeset)
222 node = repo.lookup(changeset)
188 prev, other = repo.changelog.parents(node)
223 prev, other = repo.changelog.parents(node)
189 change = repo.changelog.read(node)
224 change = repo.changelog.read(node)
190 print "# HG changeset patch"
225 print "# HG changeset patch"
191 print "# User %s" % change[1]
226 print "# User %s" % change[1]
192 print "# Node ID %s" % hg.hex(node)
227 print "# Node ID %s" % hg.hex(node)
193 print "# Parent %s" % hg.hex(prev)
228 print "# Parent %s" % hg.hex(prev)
194 print
229 print
195 if other != hg.nullid:
230 if other != hg.nullid:
196 print "# Parent %s" % hg.hex(other)
231 print "# Parent %s" % hg.hex(other)
197 print change[4].rstrip()
232 print change[4].rstrip()
198 print
233 print
199
234
200 dodiff(repo, None, prev, node)
235 dodiff(repo, None, prev, node)
201
236
202 def forget(ui, repo, file, *files):
237 def forget(ui, repo, file, *files):
203 """don't add the specified files on the next commit"""
238 """don't add the specified files on the next commit"""
204 repo.forget(relpath(repo, (file,) + files))
239 repo.forget(relpath(repo, (file,) + files))
205
240
206 def heads(ui, repo):
241 def heads(ui, repo):
207 '''show current repository heads'''
242 '''show current repository heads'''
208 for n in repo.changelog.heads():
243 for n in repo.changelog.heads():
209 i = repo.changelog.rev(n)
244 i = repo.changelog.rev(n)
210 changes = repo.changelog.read(n)
245 changes = repo.changelog.read(n)
211 (p1, p2) = repo.changelog.parents(n)
246 (p1, p2) = repo.changelog.parents(n)
212 (h, h1, h2) = map(hg.hex, (n, p1, p2))
247 (h, h1, h2) = map(hg.hex, (n, p1, p2))
213 (i1, i2) = map(repo.changelog.rev, (p1, p2))
248 (i1, i2) = map(repo.changelog.rev, (p1, p2))
214 print "rev: %4d:%s" % (i, h)
249 print "rev: %4d:%s" % (i, h)
215 print "parents: %4d:%s" % (i1, h1)
250 print "parents: %4d:%s" % (i1, h1)
216 if i2: print " %4d:%s" % (i2, h2)
251 if i2: print " %4d:%s" % (i2, h2)
217 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
252 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
218 hg.hex(changes[0]))
253 hg.hex(changes[0]))
219 print "user:", changes[1]
254 print "user:", changes[1]
220 print "date:", time.asctime(
255 print "date:", time.asctime(
221 time.localtime(float(changes[2].split(' ')[0])))
256 time.localtime(float(changes[2].split(' ')[0])))
222 if ui.verbose: print "files:", " ".join(changes[3])
257 if ui.verbose: print "files:", " ".join(changes[3])
223 print "description:"
258 print "description:"
224 print changes[4]
259 print changes[4]
225
260
226 def history(ui, repo):
261 def history(ui, repo):
227 """show the changelog history"""
262 """show the changelog history"""
228 for i in range(repo.changelog.count()):
263 for i in range(repo.changelog.count()):
229 n = repo.changelog.node(i)
264 n = repo.changelog.node(i)
230 changes = repo.changelog.read(n)
265 changes = repo.changelog.read(n)
231 (p1, p2) = repo.changelog.parents(n)
266 (p1, p2) = repo.changelog.parents(n)
232 (h, h1, h2) = map(hg.hex, (n, p1, p2))
267 (h, h1, h2) = map(hg.hex, (n, p1, p2))
233 (i1, i2) = map(repo.changelog.rev, (p1, p2))
268 (i1, i2) = map(repo.changelog.rev, (p1, p2))
234 print "rev: %4d:%s" % (i, h)
269 print "rev: %4d:%s" % (i, h)
235 print "parents: %4d:%s" % (i1, h1)
270 print "parents: %4d:%s" % (i1, h1)
236 if i2: print " %4d:%s" % (i2, h2)
271 if i2: print " %4d:%s" % (i2, h2)
237 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
272 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
238 hg.hex(changes[0]))
273 hg.hex(changes[0]))
239 print "user:", changes[1]
274 print "user:", changes[1]
240 print "date:", time.asctime(
275 print "date:", time.asctime(
241 time.localtime(float(changes[2].split(' ')[0])))
276 time.localtime(float(changes[2].split(' ')[0])))
242 if ui.verbose: print "files:", " ".join(changes[3])
277 if ui.verbose: print "files:", " ".join(changes[3])
243 print "description:"
278 print "description:"
244 print changes[4]
279 print changes[4]
245
280
246 def patch(ui, repo, patches, opts):
281 def patch(ui, repo, patches, opts):
247 """import an ordered set of patches"""
282 """import an ordered set of patches"""
248 try:
283 try:
249 import psyco
284 import psyco
250 psyco.full()
285 psyco.full()
251 except:
286 except:
252 pass
287 pass
253
288
254 d = opts["base"]
289 d = opts["base"]
255 strip = opts["strip"]
290 strip = opts["strip"]
256 quiet = opts["quiet"] and "> /dev/null" or ""
291 quiet = opts["quiet"] and "> /dev/null" or ""
257
292
258 for patch in patches:
293 for patch in patches:
259 ui.status("applying %s\n" % patch)
294 ui.status("applying %s\n" % patch)
260 pf = os.path.join(d, patch)
295 pf = os.path.join(d, patch)
261
296
262 text = ""
297 text = ""
263 for l in file(pf):
298 for l in file(pf):
264 if l[:4] == "--- ": break
299 if l[:4] == "--- ": break
265 text += l
300 text += l
266
301
267 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
302 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
268 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
303 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
269 f.close()
304 f.close()
270
305
271 if files:
306 if files:
272 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
307 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
273 raise "patch failed!"
308 raise "patch failed!"
274 repo.commit(files, text)
309 repo.commit(files, text)
275
310
276 def init(ui):
311 def init(ui):
277 """create a repository"""
312 """create a repository"""
278 hg.repository(ui, ".", create=1)
313 hg.repository(ui, ".", create=1)
279
314
280 def log(ui, repo, f):
315 def log(ui, repo, f):
281 f = relpath(repo, [f])[0]
316 f = relpath(repo, [f])[0]
282
317
283 r = repo.file(f)
318 r = repo.file(f)
284 for i in range(r.count()):
319 for i in range(r.count()):
285 n = r.node(i)
320 n = r.node(i)
286 (p1, p2) = r.parents(n)
321 (p1, p2) = r.parents(n)
287 (h, h1, h2) = map(hg.hex, (n, p1, p2))
322 (h, h1, h2) = map(hg.hex, (n, p1, p2))
288 (i1, i2) = map(r.rev, (p1, p2))
323 (i1, i2) = map(r.rev, (p1, p2))
289 cr = r.linkrev(n)
324 cr = r.linkrev(n)
290 cn = hg.hex(repo.changelog.node(cr))
325 cn = hg.hex(repo.changelog.node(cr))
291 print "rev: %4d:%s" % (i, h)
326 print "rev: %4d:%s" % (i, h)
292 print "changeset: %4d:%s" % (cr, cn)
327 print "changeset: %4d:%s" % (cr, cn)
293 print "parents: %4d:%s" % (i1, h1)
328 print "parents: %4d:%s" % (i1, h1)
294 if i2: print " %4d:%s" % (i2, h2)
329 if i2: print " %4d:%s" % (i2, h2)
295 changes = repo.changelog.read(repo.changelog.node(cr))
330 changes = repo.changelog.read(repo.changelog.node(cr))
296 print "user: %s" % changes[1]
331 print "user: %s" % changes[1]
297 print "date: %s" % time.asctime(
332 print "date: %s" % time.asctime(
298 time.localtime(float(changes[2].split(' ')[0])))
333 time.localtime(float(changes[2].split(' ')[0])))
299 print "description:"
334 print "description:"
300 print changes[4].rstrip()
335 print changes[4].rstrip()
301 print
336 print
302
337
338 def manifest(ui, repo, rev = []):
339 n = repo.manifest.tip()
340 if rev:
341 n = repo.manifest.lookup(rev)
342 m = repo.manifest.read(n)
343 files = m.keys()
344 files.sort()
345
346 for f in files:
347 print hg.hex(m[f]), f
348
303 def parents(ui, repo, node = None):
349 def parents(ui, repo, node = None):
304 '''show the parents of the current working dir'''
350 '''show the parents of the current working dir'''
305 if node:
351 if node:
306 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
352 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
307 else:
353 else:
308 p = repo.dirstate.parents()
354 p = repo.dirstate.parents()
309
355
310 for n in p:
356 for n in p:
311 if n != hg.nullid:
357 if n != hg.nullid:
312 ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n)))
358 ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n)))
313
359
314 def pull(ui, repo, source):
360 def pull(ui, repo, source):
315 """pull changes from the specified source"""
361 """pull changes from the specified source"""
316 paths = {}
362 paths = {}
317 try:
363 try:
318 pf = os.path.expanduser("~/.hgpaths")
364 pf = os.path.expanduser("~/.hgpaths")
319 for l in file(pf):
365 for l in file(pf):
320 name, path = l.split()
366 name, path = l.split()
321 paths[name] = path
367 paths[name] = path
322 except IOError:
368 except IOError:
323 pass
369 pass
324
370
325 if source in paths: source = paths[source]
371 if source in paths: source = paths[source]
326
372
327 other = hg.repository(ui, source)
373 other = hg.repository(ui, source)
328 cg = repo.getchangegroup(other)
374 cg = repo.getchangegroup(other)
329 repo.addchangegroup(cg)
375 repo.addchangegroup(cg)
330
376
331 def rawcommit(ui, repo, files, rc):
377 def rawcommit(ui, repo, files, rc):
332 "raw commit interface"
378 "raw commit interface"
333
379
334 text = rc['text']
380 text = rc['text']
335 if not text and rc['logfile']:
381 if not text and rc['logfile']:
336 try: text = open(rc['logfile']).read()
382 try: text = open(rc['logfile']).read()
337 except IOError: pass
383 except IOError: pass
338 if not text and not rc['logfile']:
384 if not text and not rc['logfile']:
339 print "missing commit text"
385 print "missing commit text"
340 return 1
386 return 1
341
387
342 files = relpath(repo, files)
388 files = relpath(repo, files)
343 if rc['files']:
389 if rc['files']:
344 files += open(rc['files']).read().splitlines()
390 files += open(rc['files']).read().splitlines()
345
391
346 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
392 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
347
393
348 def recover(ui, repo):
394 def recover(ui, repo):
349 repo.recover()
395 repo.recover()
350
396
351 def remove(ui, repo, file, *files):
397 def remove(ui, repo, file, *files):
352 """remove the specified files on the next commit"""
398 """remove the specified files on the next commit"""
353 repo.remove(relpath(repo, (file,) + files))
399 repo.remove(relpath(repo, (file,) + files))
354
400
355 def resolve(ui, repo, node=None):
401 def resolve(ui, repo, node=None):
356 '''merge a given node or the current tip into the working dir'''
402 '''merge a given node or the current tip into the working dir'''
357 if not node:
403 if not node:
358 node = repo.changelog.tip()
404 node = repo.changelog.tip()
359 else:
405 else:
360 node = repo.lookup(node)
406 node = repo.lookup(node)
361 repo.resolve(node)
407 repo.resolve(node)
362
408
363 def serve(ui, repo, **opts):
409 def serve(ui, repo, **opts):
364 from mercurial import hgweb
410 from mercurial import hgweb
365 hgweb.server(repo.root, opts["name"], opts["templates"],
411 hgweb.server(repo.root, opts["name"], opts["templates"],
366 opts["address"], opts["port"])
412 opts["address"], opts["port"])
367
413
368 def status(ui, repo):
414 def status(ui, repo):
369 '''show changed files in the working directory
415 '''show changed files in the working directory
370
416
371 C = changed
417 C = changed
372 A = added
418 A = added
373 R = removed
419 R = removed
374 ? = not tracked'''
420 ? = not tracked'''
375
421
376 (c, a, d, u) = repo.diffdir(repo.root)
422 (c, a, d, u) = repo.diffdir(repo.root)
377 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
423 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
378
424
379 for f in c: print "C", f
425 for f in c: print "C", f
380 for f in a: print "A", f
426 for f in a: print "A", f
381 for f in d: print "R", f
427 for f in d: print "R", f
382 for f in u: print "?", f
428 for f in u: print "?", f
383
429
430 def tags(ui, repo):
431 repo.lookup(0) # prime the cache
432 i = repo.tags.items()
433 i.sort()
434 for k, n in i:
435 try:
436 r = repo.changelog.rev(n)
437 except KeyError:
438 r = "?"
439 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
440
384 def tip(ui, repo):
441 def tip(ui, repo):
385 n = repo.changelog.tip()
442 n = repo.changelog.tip()
386 t = repo.changelog.rev(n)
443 t = repo.changelog.rev(n)
387 ui.status("%d:%s\n" % (t, hg.hex(n)))
444 ui.status("%d:%s\n" % (t, hg.hex(n)))
388
445
389 def undo(ui, repo):
446 def undo(ui, repo):
390 repo.undo()
447 repo.undo()
391
448
392 def verify(ui, repo):
449 def verify(ui, repo):
393 """verify the integrity of the repository"""
450 """verify the integrity of the repository"""
394 return repo.verify()
451 return repo.verify()
395
452
396 table = {
453 table = {
397 "add": (add, [], "hg add [files]"),
454 "add": (add, [], "hg add [files]"),
398 "addremove": (addremove, [], "hg addremove"),
455 "addremove": (addremove, [], "hg addremove"),
399 "ann|annotate": (annotate,
456 "ann|annotate": (annotate,
400 [('r', 'revision', '', 'revision'),
457 [('r', 'revision', '', 'revision'),
401 ('u', 'user', None, 'show user'),
458 ('u', 'user', None, 'show user'),
402 ('n', 'number', None, 'show revision number'),
459 ('n', 'number', None, 'show revision number'),
403 ('c', 'changeset', None, 'show changeset')],
460 ('c', 'changeset', None, 'show changeset')],
404 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
461 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
405 "branch|clone": (branch, [], 'hg branch [path]'),
462 "branch|clone": (branch, [], 'hg branch [path]'),
463 "cat|dump": (cat, [], 'hg cat <file> [rev]'),
406 "checkout|co": (checkout, [], 'hg checkout [changeset]'),
464 "checkout|co": (checkout, [], 'hg checkout [changeset]'),
407 "commit|ci": (commit, [], 'hg commit [files]'),
465 "commit|ci": (commit, [], 'hg commit [files]'),
466 "debugaddchangegroup": (debugaddchangegroup, [], 'debugaddchangegroup'),
467 "debugchangegroup": (debugchangegroup, [], 'debugchangegroup [roots]'),
468 "debugindex": (debugindex, [], 'debugindex <file>'),
469 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
408 "diff": (diff, [('r', 'rev', [], 'revision')],
470 "diff": (diff, [('r', 'rev', [], 'revision')],
409 'hg diff [-r A] [-r B] [files]'),
471 'hg diff [-r A] [-r B] [files]'),
410 "export": (export, [], "hg export <changeset>"),
472 "export": (export, [], "hg export <changeset>"),
411 "forget": (forget, [], "hg forget [files]"),
473 "forget": (forget, [], "hg forget [files]"),
412 "heads": (heads, [], 'hg heads'),
474 "heads": (heads, [], 'hg heads'),
413 "history": (history, [], 'hg history'),
475 "history": (history, [], 'hg history'),
414 "help": (help, [], 'hg help [command]'),
476 "help": (help, [], 'hg help [command]'),
415 "init": (init, [], 'hg init'),
477 "init": (init, [], 'hg init'),
416 "log": (log, [], 'hg log <file>'),
478 "log": (log, [], 'hg log <file>'),
479 "manifest|dumpmanifest": (manifest, [], 'hg manifest [rev]'),
417 "parents": (parents, [], 'hg parents [node]'),
480 "parents": (parents, [], 'hg parents [node]'),
418 "patch|import": (patch,
481 "patch|import": (patch,
419 [('p', 'strip', 1, 'path strip'),
482 [('p', 'strip', 1, 'path strip'),
420 ('b', 'base', "", 'base path'),
483 ('b', 'base', "", 'base path'),
421 ('q', 'quiet', "", 'silence diff')],
484 ('q', 'quiet', "", 'silence diff')],
422 "hg import [options] patches"),
485 "hg import [options] patches"),
423 "pull|merge": (pull, [], 'hg pull [source]'),
486 "pull|merge": (pull, [], 'hg pull [source]'),
424 "rawcommit": (rawcommit,
487 "rawcommit": (rawcommit,
425 [('p', 'parent', [], 'parent'),
488 [('p', 'parent', [], 'parent'),
426 ('d', 'date', "", 'data'),
489 ('d', 'date', "", 'data'),
427 ('u', 'user', "", 'user'),
490 ('u', 'user', "", 'user'),
428 ('F', 'files', "", 'file list'),
491 ('F', 'files', "", 'file list'),
429 ('t', 'text', "", 'commit text'),
492 ('t', 'text', "", 'commit text'),
430 ('l', 'logfile', "", 'commit text file')],
493 ('l', 'logfile', "", 'commit text file')],
431 'hg rawcommit [options] [files]'),
494 'hg rawcommit [options] [files]'),
432 "recover": (recover, [], "hg recover"),
495 "recover": (recover, [], "hg recover"),
433 "remove": (remove, [], "hg remove [files]"),
496 "remove": (remove, [], "hg remove [files]"),
434 "resolve": (resolve, [], 'hg resolve [node]'),
497 "resolve": (resolve, [], 'hg resolve [node]'),
435 "serve": (serve, [('p', 'port', 8000, 'listen port'),
498 "serve": (serve, [('p', 'port', 8000, 'listen port'),
436 ('a', 'address', '', 'interface address'),
499 ('a', 'address', '', 'interface address'),
437 ('n', 'name', os.getcwd(), 'repository name'),
500 ('n', 'name', os.getcwd(), 'repository name'),
438 ('t', 'templates', "", 'template map')],
501 ('t', 'templates', "", 'template map')],
439 "hg serve [options]"),
502 "hg serve [options]"),
440 "status": (status, [], 'hg status'),
503 "status": (status, [], 'hg status'),
504 "tags": (tags, [], 'hg tags'),
441 "tip": (tip, [], 'hg tip'),
505 "tip": (tip, [], 'hg tip'),
442 "undo": (undo, [], 'hg undo'),
506 "undo": (undo, [], 'hg undo'),
443 "verify": (verify, [], 'hg verify'),
507 "verify": (verify, [], 'hg verify'),
444 }
508 }
445
509
446 norepo = "init branch help"
510 norepo = "init branch help debugindex debugindexdot"
447
511
448 def find(cmd):
512 def find(cmd):
449 i = None
513 i = None
450 for e in table.keys():
514 for e in table.keys():
451 if re.match(e + "$", cmd):
515 if re.match(e + "$", cmd):
452 return table[e]
516 return table[e]
453
517
454 raise UnknownCommand(cmd)
518 raise UnknownCommand(cmd)
455
519
456 class SignalInterrupt(Exception): pass
520 class SignalInterrupt(Exception): pass
457
521
458 def catchterm(*args):
522 def catchterm(*args):
459 raise SignalInterrupt
523 raise SignalInterrupt
460
524
461 def dispatch(args):
525 def dispatch(args):
462 options = {}
526 options = {}
463 opts = [('v', 'verbose', None, 'verbose'),
527 opts = [('v', 'verbose', None, 'verbose'),
464 ('d', 'debug', None, 'debug'),
528 ('d', 'debug', None, 'debug'),
465 ('q', 'quiet', None, 'quiet'),
529 ('q', 'quiet', None, 'quiet'),
466 ('y', 'noninteractive', None, 'run non-interactively'),
530 ('y', 'noninteractive', None, 'run non-interactively'),
467 ]
531 ]
468
532
469 args = fancyopts.fancyopts(args, opts, options,
533 args = fancyopts.fancyopts(args, opts, options,
470 'hg [options] <command> [options] [files]')
534 'hg [options] <command> [options] [files]')
471
535
472 if not args:
536 if not args:
473 cmd = "help"
537 cmd = "help"
474 else:
538 else:
475 cmd, args = args[0], args[1:]
539 cmd, args = args[0], args[1:]
476
540
477 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
541 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
478 not options["noninteractive"])
542 not options["noninteractive"])
479
543
480 # deal with unfound commands later
544 # deal with unfound commands later
481 i = find(cmd)
545 i = find(cmd)
482
546
483 signal.signal(signal.SIGTERM, catchterm)
547 signal.signal(signal.SIGTERM, catchterm)
484
548
485 cmdoptions = {}
549 cmdoptions = {}
486 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
550 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
487
551
488 if cmd not in norepo.split():
552 if cmd not in norepo.split():
489 repo = hg.repository(ui = u)
553 repo = hg.repository(ui = u)
490 d = lambda: i[0](u, repo, *args, **cmdoptions)
554 d = lambda: i[0](u, repo, *args, **cmdoptions)
491 else:
555 else:
492 d = lambda: i[0](u, *args, **cmdoptions)
556 d = lambda: i[0](u, *args, **cmdoptions)
493
557
494 try:
558 try:
495 return d()
559 return d()
496 except SignalInterrupt:
560 except SignalInterrupt:
497 u.warn("killed!\n")
561 u.warn("killed!\n")
498 except KeyboardInterrupt:
562 except KeyboardInterrupt:
499 u.warn("interrupted!\n")
563 u.warn("interrupted!\n")
500 except TypeError, inst:
564 except TypeError, inst:
501 # was this an argument error?
565 # was this an argument error?
502 tb = traceback.extract_tb(sys.exc_info()[2])
566 tb = traceback.extract_tb(sys.exc_info()[2])
503 if len(tb) > 2: # no
567 if len(tb) > 2: # no
504 raise
568 raise
505 u.warn("%s: invalid arguments\n" % i[0].__name__)
569 u.warn("%s: invalid arguments\n" % i[0].__name__)
506 u.warn("syntax: %s\n" % i[2])
570 u.warn("syntax: %s\n" % i[2])
507 sys.exit(-1)
571 sys.exit(-1)
General Comments 0
You need to be logged in to leave comments. Login now