##// END OF EJS Templates
Add -q option to import...
mpm@selenic.com -
r50:0263ce8b default
parent child Browse files
Show More
@@ -1,358 +1,362 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.4d "oedipa maas"
4 # v0.4d "oedipa maas"
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, os, time
19 import sys, os, time
20 from mercurial import hg, mdiff, fancyopts
20 from mercurial import hg, mdiff, fancyopts
21
21
22 def help():
22 def help():
23 print """\
23 print """\
24 commands:
24 commands:
25
25
26 init create a new repository in this directory
26 init create a new repository in this directory
27 branch <path> create a branch of <path> in this directory
27 branch <path> create a branch of <path> in this directory
28 merge <path> merge changes from <path> into local repository
28 merge <path> merge changes from <path> into local repository
29 checkout [changeset] checkout the latest or given changeset
29 checkout [changeset] checkout the latest or given changeset
30 status show new, missing, and changed files in working dir
30 status show new, missing, and changed files in working dir
31 add [files...] add the given files in the next commit
31 add [files...] add the given files in the next commit
32 remove [files...] remove the given files in the next commit
32 remove [files...] remove the given files in the next commit
33 addremove add all new files, delete all missing files
33 addremove add all new files, delete all missing files
34 commit commit all changes to the repository
34 commit commit all changes to the repository
35 history show changeset history
35 history show changeset history
36 log <file> show revision history of a single file
36 log <file> show revision history of a single file
37 dump <file> [rev] dump the latest or given revision of a file
37 dump <file> [rev] dump the latest or given revision of a file
38 dumpmanifest [rev] dump the latest or given revision of the manifest
38 dumpmanifest [rev] dump the latest or given revision of the manifest
39 diff [files...] diff working directory (or selected files)
39 diff [files...] diff working directory (or selected files)
40 """
40 """
41
41
42 def filterfiles(list, files):
42 def filterfiles(list, files):
43 l = [ x for x in list if x in files ]
43 l = [ x for x in list if x in files ]
44
44
45 for f in files:
45 for f in files:
46 if f[-1] != os.sep: f += os.sep
46 if f[-1] != os.sep: f += os.sep
47 l += [ x for x in list if x.startswith(f) ]
47 l += [ x for x in list if x.startswith(f) ]
48 return l
48 return l
49
49
50 def diff(files = None, node1 = None, node2 = None):
50 def diff(files = None, node1 = None, node2 = None):
51
51
52 if node2:
52 if node2:
53 change = repo.changelog.read(node2)
53 change = repo.changelog.read(node2)
54 mmap2 = repo.manifest.read(change[0])
54 mmap2 = repo.manifest.read(change[0])
55 (c, a, d) = repo.diffrevs(node1, node2)
55 (c, a, d) = repo.diffrevs(node1, node2)
56 def read(f): return repo.file(f).read(mmap2[f])
56 def read(f): return repo.file(f).read(mmap2[f])
57 else:
57 else:
58 if not node1:
58 if not node1:
59 node1 = repo.current
59 node1 = repo.current
60 (c, a, d) = repo.diffdir(repo.root, node1)
60 (c, a, d) = repo.diffdir(repo.root, node1)
61 def read(f): return file(f).read()
61 def read(f): return file(f).read()
62
62
63 change = repo.changelog.read(node1)
63 change = repo.changelog.read(node1)
64 mmap = repo.manifest.read(change[0])
64 mmap = repo.manifest.read(change[0])
65
65
66 if files:
66 if files:
67 (c, a, d) = map(lambda x: filterfiles(x, files), (c, a, d))
67 (c, a, d) = map(lambda x: filterfiles(x, files), (c, a, d))
68
68
69 for f in c:
69 for f in c:
70 to = repo.file(f).read(mmap[f])
70 to = repo.file(f).read(mmap[f])
71 tn = read(f)
71 tn = read(f)
72 sys.stdout.write(mdiff.unidiff(to, tn, f))
72 sys.stdout.write(mdiff.unidiff(to, tn, f))
73 for f in a:
73 for f in a:
74 to = ""
74 to = ""
75 tn = read(f)
75 tn = read(f)
76 sys.stdout.write(mdiff.unidiff(to, tn, f))
76 sys.stdout.write(mdiff.unidiff(to, tn, f))
77 for f in d:
77 for f in d:
78 to = repo.file(f).read(mmap[f])
78 to = repo.file(f).read(mmap[f])
79 tn = ""
79 tn = ""
80 sys.stdout.write(mdiff.unidiff(to, tn, f))
80 sys.stdout.write(mdiff.unidiff(to, tn, f))
81
81
82
82
83 options = {}
83 options = {}
84 opts = [('v', 'verbose', None, 'verbose'),
84 opts = [('v', 'verbose', None, 'verbose'),
85 ('d', 'debug', None, 'debug')]
85 ('d', 'debug', None, 'debug')]
86
86
87 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
87 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
88 'hg [options] <command> [command options] [files]')
88 'hg [options] <command> [command options] [files]')
89
89
90 try:
90 try:
91 cmd = args[0]
91 cmd = args[0]
92 args = args[1:]
92 args = args[1:]
93 except:
93 except:
94 cmd = ""
94 cmd = ""
95
95
96 ui = hg.ui(options["verbose"], options["debug"])
96 ui = hg.ui(options["verbose"], options["debug"])
97
97
98 if cmd == "init":
98 if cmd == "init":
99 repo = hg.repository(ui, ".", create=1)
99 repo = hg.repository(ui, ".", create=1)
100 sys.exit(0)
100 sys.exit(0)
101 elif cmd == "branch" or cmd == "clone":
101 elif cmd == "branch" or cmd == "clone":
102 os.system("cp -al %s/.hg .hg" % args[0])
102 os.system("cp -al %s/.hg .hg" % args[0])
103 sys.exit(0)
103 sys.exit(0)
104 elif cmd == "help":
104 elif cmd == "help":
105 help()
105 help()
106 sys.exit(0)
106 sys.exit(0)
107 else:
107 else:
108 try:
108 try:
109 repo = hg.repository(ui=ui)
109 repo = hg.repository(ui=ui)
110 except:
110 except:
111 print "Unable to open repository"
111 print "Unable to open repository"
112 sys.exit(0)
112 sys.exit(0)
113
113
114 if cmd == "checkout" or cmd == "co":
114 if cmd == "checkout" or cmd == "co":
115 node = repo.changelog.tip()
115 node = repo.changelog.tip()
116 if args:
116 if args:
117 node = repo.changelog.lookup(args[0])
117 node = repo.changelog.lookup(args[0])
118 repo.checkout(node)
118 repo.checkout(node)
119
119
120 elif cmd == "add":
120 elif cmd == "add":
121 repo.add(args)
121 repo.add(args)
122
122
123 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
123 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
124 repo.remove(args)
124 repo.remove(args)
125
125
126 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
126 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
127 if 1:
127 if 1:
128 if len(args) > 0:
128 if len(args) > 0:
129 repo.commit(repo.current, args)
129 repo.commit(repo.current, args)
130 else:
130 else:
131 repo.commit(repo.current)
131 repo.commit(repo.current)
132
132
133 elif cmd == "import" or cmd == "patch":
133 elif cmd == "import" or cmd == "patch":
134 ioptions = {}
134 ioptions = {}
135 opts = [('p', 'strip', 1, 'path strip'),
135 opts = [('p', 'strip', 1, 'path strip'),
136 ('b', 'base', "", 'base path')]
136 ('b', 'base', "", 'base path'),
137 ('q', 'quiet', "", 'silence diff')
138 ]
137
139
138 args = fancyopts.fancyopts(args, opts, ioptions,
140 args = fancyopts.fancyopts(args, opts, ioptions,
139 'hg import [options] <patch names>')
141 'hg import [options] <patch names>')
140 d = ioptions["base"]
142 d = ioptions["base"]
141 strip = ioptions["strip"]
143 strip = ioptions["strip"]
144 quiet = ioptions["quiet"] and "> /dev/null" or ""
142
145
143 for patch in args:
146 for patch in args:
144 ui.status("applying %s\n" % patch)
147 ui.status("applying %s\n" % patch)
145 pf = os.path.join(d, patch)
148 pf = os.path.join(d, patch)
146
149
147 text = ""
150 text = ""
148 for l in file(pf):
151 for l in file(pf):
149 if l[:3] == "---": break
152 if l[:3] == "---": break
150 text += l
153 text += l
151
154
152 os.system("patch -p%d < %s > /dev/null" % (strip, pf))
155 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
156 raise "patch failed!"
153 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
157 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
154 files = f.read().splitlines()
158 files = f.read().splitlines()
155 f.close()
159 f.close()
156 repo.commit(repo.current, files, text)
160 repo.commit(repo.current, files, text)
157
161
158 elif cmd == "status":
162 elif cmd == "status":
159 (c, a, d) = repo.diffdir(repo.root, repo.current)
163 (c, a, d) = repo.diffdir(repo.root, repo.current)
160 for f in c: print "C", f
164 for f in c: print "C", f
161 for f in a: print "?", f
165 for f in a: print "?", f
162 for f in d: print "R", f
166 for f in d: print "R", f
163
167
164 elif cmd == "diff":
168 elif cmd == "diff":
165 revs = []
169 revs = []
166
170
167 if args:
171 if args:
168 doptions = {}
172 doptions = {}
169 opts = [('r', 'revision', [], 'revision')]
173 opts = [('r', 'revision', [], 'revision')]
170 args = fancyopts.fancyopts(args, opts, doptions,
174 args = fancyopts.fancyopts(args, opts, doptions,
171 'hg diff [options] [files]')
175 'hg diff [options] [files]')
172 revs = map(lambda x: repo.changelog.lookup(x), doptions['revision'])
176 revs = map(lambda x: repo.changelog.lookup(x), doptions['revision'])
173
177
174 if len(revs) > 2:
178 if len(revs) > 2:
175 print "too many revisions to diff"
179 print "too many revisions to diff"
176 sys.exit(1)
180 sys.exit(1)
177 else:
181 else:
178 diff(args, *revs)
182 diff(args, *revs)
179
183
180 elif cmd == "export":
184 elif cmd == "export":
181 node = repo.changelog.lookup(args[0])
185 node = repo.changelog.lookup(args[0])
182 prev = repo.changelog.parents(node)[0]
186 prev = repo.changelog.parents(node)[0]
183 diff(None, prev, node)
187 diff(None, prev, node)
184
188
185 elif cmd == "debugchangegroup":
189 elif cmd == "debugchangegroup":
186 newer = repo.newer(repo.changelog.lookup(args[0]))
190 newer = repo.newer(repo.changelog.lookup(args[0]))
187 cg = repo.changegroup(newer)
191 cg = repo.changegroup(newer)
188 sys.stdout.write(cg)
192 sys.stdout.write(cg)
189
193
190 elif cmd == "debugaddchangegroup":
194 elif cmd == "debugaddchangegroup":
191 data = sys.stdin.read()
195 data = sys.stdin.read()
192 repo.addchangegroup(data)
196 repo.addchangegroup(data)
193
197
194 elif cmd == "addremove":
198 elif cmd == "addremove":
195 (c, a, d) = repo.diffdir(repo.root, repo.current)
199 (c, a, d) = repo.diffdir(repo.root, repo.current)
196 repo.add(a)
200 repo.add(a)
197 repo.remove(d)
201 repo.remove(d)
198
202
199 elif cmd == "history":
203 elif cmd == "history":
200 for i in range(repo.changelog.count()):
204 for i in range(repo.changelog.count()):
201 n = repo.changelog.node(i)
205 n = repo.changelog.node(i)
202 changes = repo.changelog.read(n)
206 changes = repo.changelog.read(n)
203 (p1, p2) = repo.changelog.parents(n)
207 (p1, p2) = repo.changelog.parents(n)
204 (h, h1, h2) = map(hg.hex, (n, p1, p2))
208 (h, h1, h2) = map(hg.hex, (n, p1, p2))
205 (i1, i2) = map(repo.changelog.rev, (p1, p2))
209 (i1, i2) = map(repo.changelog.rev, (p1, p2))
206 print "rev: %4d:%s" % (i, h)
210 print "rev: %4d:%s" % (i, h)
207 print "parents: %4d:%s" % (i1, h1)
211 print "parents: %4d:%s" % (i1, h1)
208 if i2: print " %4d:%s" % (i2, h2)
212 if i2: print " %4d:%s" % (i2, h2)
209 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
213 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
210 hg.hex(changes[0]))
214 hg.hex(changes[0]))
211 print "user:", changes[1]
215 print "user:", changes[1]
212 print "date:", time.asctime(
216 print "date:", time.asctime(
213 time.localtime(float(changes[2].split(' ')[0])))
217 time.localtime(float(changes[2].split(' ')[0])))
214 print "files:", " ".join(changes[3])
218 print "files:", " ".join(changes[3])
215 print "description:"
219 print "description:"
216 print changes[4]
220 print changes[4]
217
221
218 elif cmd == "log":
222 elif cmd == "log":
219 if args:
223 if args:
220 r = repo.file(args[0])
224 r = repo.file(args[0])
221 for i in range(r.count()):
225 for i in range(r.count()):
222 n = r.node(i)
226 n = r.node(i)
223 (p1, p2) = r.parents(n)
227 (p1, p2) = r.parents(n)
224 (h, h1, h2) = map(hg.hex, (n, p1, p2))
228 (h, h1, h2) = map(hg.hex, (n, p1, p2))
225 (i1, i2) = map(r.rev, (p1, p2))
229 (i1, i2) = map(r.rev, (p1, p2))
226 cr = r.linkrev(n)
230 cr = r.linkrev(n)
227 cn = hg.hex(repo.changelog.node(cr))
231 cn = hg.hex(repo.changelog.node(cr))
228 print "rev: %4d:%s" % (i, h)
232 print "rev: %4d:%s" % (i, h)
229 print "changeset: %4d:%s" % (cr, cn)
233 print "changeset: %4d:%s" % (cr, cn)
230 print "parents: %4d:%s" % (i1, h1)
234 print "parents: %4d:%s" % (i1, h1)
231 if i2: print " %4d:%s" % (i2, h2)
235 if i2: print " %4d:%s" % (i2, h2)
232 else:
236 else:
233 print "missing filename"
237 print "missing filename"
234
238
235 elif cmd == "dump":
239 elif cmd == "dump":
236 if args:
240 if args:
237 r = repo.file(args[0])
241 r = repo.file(args[0])
238 n = r.tip()
242 n = r.tip()
239 if len(args) > 1: n = r.lookup(args[1])
243 if len(args) > 1: n = r.lookup(args[1])
240 sys.stdout.write(r.read(n))
244 sys.stdout.write(r.read(n))
241 else:
245 else:
242 print "missing filename"
246 print "missing filename"
243
247
244 elif cmd == "dumpmanifest":
248 elif cmd == "dumpmanifest":
245 n = repo.manifest.tip()
249 n = repo.manifest.tip()
246 if len(args) > 0:
250 if len(args) > 0:
247 n = repo.manifest.lookup(args[0])
251 n = repo.manifest.lookup(args[0])
248 m = repo.manifest.read(n)
252 m = repo.manifest.read(n)
249 files = m.keys()
253 files = m.keys()
250 files.sort()
254 files.sort()
251
255
252 for f in files:
256 for f in files:
253 print hg.hex(m[f]), f
257 print hg.hex(m[f]), f
254
258
255 elif cmd == "debughash":
259 elif cmd == "debughash":
256 f = repo.file(args[0])
260 f = repo.file(args[0])
257 print f.encodepath(args[0])
261 print f.encodepath(args[0])
258
262
259 elif cmd == "debugindex":
263 elif cmd == "debugindex":
260 r = hg.revlog(open, args[0], "")
264 r = hg.revlog(open, args[0], "")
261 print " rev offset length base linkrev"+\
265 print " rev offset length base linkrev"+\
262 " p1 p2 nodeid"
266 " p1 p2 nodeid"
263 for i in range(r.count()):
267 for i in range(r.count()):
264 e = r.index[i]
268 e = r.index[i]
265 print "% 6d % 9d % 7d % 5d % 7d %s.. %s.. %s.." % (
269 print "% 6d % 9d % 7d % 5d % 7d %s.. %s.. %s.." % (
266 i, e[0], e[1], e[2], e[3],
270 i, e[0], e[1], e[2], e[3],
267 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
271 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
268
272
269 elif cmd == "merge":
273 elif cmd == "merge":
270 if args:
274 if args:
271 other = hg.repository(ui, args[0])
275 other = hg.repository(ui, args[0])
272 repo.merge(other)
276 repo.merge(other)
273 else:
277 else:
274 print "missing source repository"
278 print "missing source repository"
275
279
276 elif cmd == "verify":
280 elif cmd == "verify":
277 filelinkrevs = {}
281 filelinkrevs = {}
278 filenodes = {}
282 filenodes = {}
279 manifestchangeset = {}
283 manifestchangeset = {}
280 changesets = revisions = files = 0
284 changesets = revisions = files = 0
281
285
282 print "checking changesets"
286 print "checking changesets"
283 for i in range(repo.changelog.count()):
287 for i in range(repo.changelog.count()):
284 changesets += 1
288 changesets += 1
285 n = repo.changelog.node(i)
289 n = repo.changelog.node(i)
286 changes = repo.changelog.read(n)
290 changes = repo.changelog.read(n)
287 manifestchangeset[changes[0]] = n
291 manifestchangeset[changes[0]] = n
288 for f in changes[3]:
292 for f in changes[3]:
289 revisions += 1
293 revisions += 1
290 filelinkrevs.setdefault(f, []).append(i)
294 filelinkrevs.setdefault(f, []).append(i)
291
295
292 print "checking manifests"
296 print "checking manifests"
293 for i in range(repo.manifest.count()):
297 for i in range(repo.manifest.count()):
294 n = repo.manifest.node(i)
298 n = repo.manifest.node(i)
295 ca = repo.changelog.node(repo.manifest.linkrev(n))
299 ca = repo.changelog.node(repo.manifest.linkrev(n))
296 cc = manifestchangeset[n]
300 cc = manifestchangeset[n]
297 if ca != cc:
301 if ca != cc:
298 print "manifest %s points to %s, not %s" % \
302 print "manifest %s points to %s, not %s" % \
299 (hg.hex(n), hg.hex(ca), hg.hex(cc))
303 (hg.hex(n), hg.hex(ca), hg.hex(cc))
300 m = repo.manifest.read(n)
304 m = repo.manifest.read(n)
301 for f, fn in m.items():
305 for f, fn in m.items():
302 filenodes.setdefault(f, {})[fn] = 1
306 filenodes.setdefault(f, {})[fn] = 1
303
307
304 print "crosschecking files in changesets and manifests"
308 print "crosschecking files in changesets and manifests"
305 for f in filenodes:
309 for f in filenodes:
306 if f not in filelinkrevs:
310 if f not in filelinkrevs:
307 print "file %s in manifest but not in changesets"
311 print "file %s in manifest but not in changesets"
308
312
309 for f in filelinkrevs:
313 for f in filelinkrevs:
310 if f not in filenodes:
314 if f not in filenodes:
311 print "file %s in changeset but not in manifest"
315 print "file %s in changeset but not in manifest"
312
316
313 print "checking files"
317 print "checking files"
314 for f in filenodes:
318 for f in filenodes:
315 files += 1
319 files += 1
316 fl = repo.file(f)
320 fl = repo.file(f)
317 nodes = {"\0"*20: 1}
321 nodes = {"\0"*20: 1}
318 for i in range(fl.count()):
322 for i in range(fl.count()):
319 n = fl.node(i)
323 n = fl.node(i)
320
324
321 if n not in filenodes[f]:
325 if n not in filenodes[f]:
322 print "%s:%s not in manifests" % (f, hg.hex(n))
326 print "%s:%s not in manifests" % (f, hg.hex(n))
323 else:
327 else:
324 del filenodes[f][n]
328 del filenodes[f][n]
325
329
326 flr = fl.linkrev(n)
330 flr = fl.linkrev(n)
327 if flr not in filelinkrevs[f]:
331 if flr not in filelinkrevs[f]:
328 print "%s:%s points to unexpected changeset rev %d" \
332 print "%s:%s points to unexpected changeset rev %d" \
329 % (f, hg.hex(n), fl.linkrev(n))
333 % (f, hg.hex(n), fl.linkrev(n))
330 else:
334 else:
331 filelinkrevs[f].remove(flr)
335 filelinkrevs[f].remove(flr)
332
336
333 # verify contents
337 # verify contents
334 t = fl.read(n)
338 t = fl.read(n)
335
339
336 # verify parents
340 # verify parents
337 (p1, p2) = fl.parents(n)
341 (p1, p2) = fl.parents(n)
338 if p1 not in nodes:
342 if p1 not in nodes:
339 print "%s:%s unknown parent 1 %s" % (f, hg.hex(n), hg.hex(p1))
343 print "%s:%s unknown parent 1 %s" % (f, hg.hex(n), hg.hex(p1))
340 if p2 not in nodes:
344 if p2 not in nodes:
341 print "file %s:%s unknown parent %s" % (f, hg.hex(n), hg.hex(p1))
345 print "file %s:%s unknown parent %s" % (f, hg.hex(n), hg.hex(p1))
342 nodes[n] = 1
346 nodes[n] = 1
343
347
344 # cross-check
348 # cross-check
345 for flr in filelinkrevs[f]:
349 for flr in filelinkrevs[f]:
346 print "changeset rev %d not in %s" % (flr, f)
350 print "changeset rev %d not in %s" % (flr, f)
347
351
348 for node in filenodes[f]:
352 for node in filenodes[f]:
349 print "node %s in manifests not in %s" % (hg.hex(n), f)
353 print "node %s in manifests not in %s" % (hg.hex(n), f)
350
354
351
355
352 print "%d files, %d changesets, %d total revisions" % (files, changesets,
356 print "%d files, %d changesets, %d total revisions" % (files, changesets,
353 revisions)
357 revisions)
354
358
355 else:
359 else:
356 print "unknown command\n"
360 print "unknown command\n"
357 help()
361 help()
358 sys.exit(1)
362 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now