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