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