##// END OF EJS Templates
Change hgit revision lookup to use repo.lookup
mason@suse.com -
r720:095dd8c7 default
parent child Browse files
Show More
@@ -1,255 +1,255 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # Minimal support for git commands on an hg repository
3 # Minimal support for git commands on an hg repository
4 #
4 #
5 # Copyright 2005 Chris Mason <mason@suse.com>
5 # Copyright 2005 Chris Mason <mason@suse.com>
6 #
6 #
7 # This software may be used and distributed according to the terms
7 # This software may be used and distributed according to the terms
8 # of the GNU General Public License, incorporated herein by reference.
8 # of the GNU General Public License, incorporated herein by reference.
9
9
10 import time, sys, signal
10 import time, sys, signal
11 from mercurial import hg, mdiff, fancyopts, commands, ui
11 from mercurial import hg, mdiff, fancyopts, commands, ui
12
12
13 def difftree(args, ui, repo):
13 def difftree(args, ui, repo):
14 def __difftree(repo, files = None, node1 = None, node2 = None):
14 def __difftree(repo, files = None, node1 = None, node2 = None):
15 def date(c):
15 def date(c):
16 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
16 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
17
17
18 if node2:
18 if node2:
19 change = repo.changelog.read(node2)
19 change = repo.changelog.read(node2)
20 mmap2 = repo.manifest.read(change[0])
20 mmap2 = repo.manifest.read(change[0])
21 (c, a, d, u) = repo.changes(node1, node2)
21 (c, a, d, u) = repo.changes(node1, node2)
22 def read(f): return repo.file(f).read(mmap2[f])
22 def read(f): return repo.file(f).read(mmap2[f])
23 date2 = date(change)
23 date2 = date(change)
24 else:
24 else:
25 date2 = time.asctime()
25 date2 = time.asctime()
26 (c, a, d, u) = repo.diffdir(repo.root, node1)
26 (c, a, d, u) = repo.diffdir(repo.root, node1)
27 if not node1:
27 if not node1:
28 node1 = repo.dirstate.parents()[0]
28 node1 = repo.dirstate.parents()[0]
29 def read(f): return file(os.path.join(repo.root, f)).read()
29 def read(f): return file(os.path.join(repo.root, f)).read()
30
30
31 change = repo.changelog.read(node1)
31 change = repo.changelog.read(node1)
32 mmap = repo.manifest.read(change[0])
32 mmap = repo.manifest.read(change[0])
33 date1 = date(change)
33 date1 = date(change)
34 empty = "0" * 40;
34 empty = "0" * 40;
35
35
36 if files:
36 if files:
37 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
37 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
38
38
39 for f in c:
39 for f in c:
40 # TODO get file permissions
40 # TODO get file permissions
41 print ":100664 100664 %s %s M\t%s\t%s" % (hg.hex(mmap[f]),
41 print ":100664 100664 %s %s M\t%s\t%s" % (hg.hex(mmap[f]),
42 hg.hex(mmap2[f]), f, f)
42 hg.hex(mmap2[f]), f, f)
43 for f in a:
43 for f in a:
44 print ":000000 100664 %s %s N\t%s\t%s" % (empty, hg.hex(mmap2[f]), f, f)
44 print ":000000 100664 %s %s N\t%s\t%s" % (empty, hg.hex(mmap2[f]), f, f)
45 for f in d:
45 for f in d:
46 print ":100664 000000 %s %s D\t%s\t%s" % (hg.hex(mmap[f]), empty, f, f)
46 print ":100664 000000 %s %s D\t%s\t%s" % (hg.hex(mmap[f]), empty, f, f)
47 ##
47 ##
48
48
49 revs = []
49 revs = []
50 if args:
50 if args:
51 doptions = {}
51 doptions = {}
52 opts = [('p', 'patch', None, 'patch'),
52 opts = [('p', 'patch', None, 'patch'),
53 ('r', 'recursive', None, 'recursive')]
53 ('r', 'recursive', None, 'recursive')]
54 args = fancyopts.fancyopts(args, opts, doptions)
54 args = fancyopts.fancyopts(args, opts, doptions)
55
55
56 if len(args) < 2:
56 if len(args) < 2:
57 help()
57 help()
58 sys.exit(1)
58 sys.exit(1)
59 revs.append(repo.lookup(args[0]))
59 revs.append(repo.lookup(args[0]))
60 revs.append(repo.lookup(args[1]))
60 revs.append(repo.lookup(args[1]))
61 args = args[2:]
61 args = args[2:]
62 if doptions['patch']:
62 if doptions['patch']:
63 commands.dodiff(sys.stdout, ui, repo, args, *revs)
63 commands.dodiff(sys.stdout, ui, repo, args, *revs)
64 else:
64 else:
65 __difftree(repo, args, *revs)
65 __difftree(repo, args, *revs)
66
66
67 def catcommit(repo, n, prefix):
67 def catcommit(repo, n, prefix):
68 nlprefix = '\n' + prefix;
68 nlprefix = '\n' + prefix;
69 changes = repo.changelog.read(n)
69 changes = repo.changelog.read(n)
70 (p1, p2) = repo.changelog.parents(n)
70 (p1, p2) = repo.changelog.parents(n)
71 (h, h1, h2) = map(hg.hex, (n, p1, p2))
71 (h, h1, h2) = map(hg.hex, (n, p1, p2))
72 (i1, i2) = map(repo.changelog.rev, (p1, p2))
72 (i1, i2) = map(repo.changelog.rev, (p1, p2))
73 print "tree %s" % (h)
73 print "tree %s" % (h)
74 if i1 != -1: print "%sparent %s" % (prefix, h1)
74 if i1 != -1: print "%sparent %s" % (prefix, h1)
75 if i2 != -1: print "%sparent %s" % (prefix, h2)
75 if i2 != -1: print "%sparent %s" % (prefix, h2)
76 date_ar = changes[2].split(' ')
76 date_ar = changes[2].split(' ')
77 date = int(float(date_ar[0]))
77 date = int(float(date_ar[0]))
78 print "%sauthor <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
78 print "%sauthor <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
79 print "%scommitter <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
79 print "%scommitter <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
80 print prefix
80 print prefix
81 if prefix != "":
81 if prefix != "":
82 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
82 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
83 else:
83 else:
84 print changes[4]
84 print changes[4]
85
85
86 def catfile(args, ui, repo):
86 def catfile(args, ui, repo):
87 doptions = {}
87 doptions = {}
88 opts = [('s', 'stdin', None, 'stdin')]
88 opts = [('s', 'stdin', None, 'stdin')]
89 args = fancyopts.fancyopts(args, opts, doptions)
89 args = fancyopts.fancyopts(args, opts, doptions)
90
90
91 # in stdin mode, every line except the commit is prefixed with two
91 # in stdin mode, every line except the commit is prefixed with two
92 # spaces. This way the our caller can find the commit without magic
92 # spaces. This way the our caller can find the commit without magic
93 # strings
93 # strings
94 #
94 #
95 prefix = ""
95 prefix = ""
96 if doptions['stdin']:
96 if doptions['stdin']:
97 try:
97 try:
98 (type, r) = raw_input().split(' ');
98 (type, r) = raw_input().split(' ');
99 prefix = " "
99 prefix = " "
100 except EOFError:
100 except EOFError:
101 return
101 return
102
102
103 else:
103 else:
104 if len(args) < 2:
104 if len(args) < 2:
105 help()
105 help()
106 sys.exit(1)
106 sys.exit(1)
107 type = args[0]
107 type = args[0]
108 r = args[1]
108 r = args[1]
109
109
110 while r:
110 while r:
111 if type != "commit":
111 if type != "commit":
112 sys.stderr.write("aborting hg cat-file only understands commits\n")
112 sys.stderr.write("aborting hg cat-file only understands commits\n")
113 sys.exit(1);
113 sys.exit(1);
114 n = repo.changelog.lookup(r)
114 n = repo.lookup(r)
115 catcommit(repo, n, prefix)
115 catcommit(repo, n, prefix)
116 if doptions['stdin']:
116 if doptions['stdin']:
117 try:
117 try:
118 (type, r) = raw_input().split(' ');
118 (type, r) = raw_input().split(' ');
119 except EOFError:
119 except EOFError:
120 break
120 break
121 else:
121 else:
122 break
122 break
123
123
124 # git rev-tree is a confusing thing. You can supply a number of
124 # git rev-tree is a confusing thing. You can supply a number of
125 # commit sha1s on the command line, and it walks the commit history
125 # commit sha1s on the command line, and it walks the commit history
126 # telling you which commits are reachable from the supplied ones via
126 # telling you which commits are reachable from the supplied ones via
127 # a bitmask based on arg position.
127 # a bitmask based on arg position.
128 # you can specify a commit to stop at by starting the sha1 with ^
128 # you can specify a commit to stop at by starting the sha1 with ^
129 def revtree(args, repo, full="tree", maxnr=0):
129 def revtree(args, repo, full="tree", maxnr=0):
130 # calculate and return the reachability bitmask for sha
130 # calculate and return the reachability bitmask for sha
131 def is_reachable(ar, reachable, sha):
131 def is_reachable(ar, reachable, sha):
132 if len(ar) == 0:
132 if len(ar) == 0:
133 return 1
133 return 1
134 mask = 0
134 mask = 0
135 for i in range(len(ar)):
135 for i in range(len(ar)):
136 if sha in reachable[i]:
136 if sha in reachable[i]:
137 mask |= 1 << i
137 mask |= 1 << i
138
138
139 return mask
139 return mask
140
140
141 reachable = []
141 reachable = []
142 stop_sha1 = []
142 stop_sha1 = []
143 want_sha1 = []
143 want_sha1 = []
144 count = 0
144 count = 0
145
145
146 # figure out which commits they are asking for and which ones they
146 # figure out which commits they are asking for and which ones they
147 # want us to stop on
147 # want us to stop on
148 for i in range(len(args)):
148 for i in range(len(args)):
149 if args[i].count('^'):
149 if args[i].startswith('^'):
150 s = args[i].split('^')[1]
150 s = repo.lookup(args[i][1:])
151 stop_sha1.append(repo.changelog.lookup(s))
151 stop_sha1.append(s)
152 want_sha1.append(s)
152 want_sha1.append(s)
153 elif args[i] != 'HEAD':
153 elif args[i] != 'HEAD':
154 want_sha1.append(args[i])
154 want_sha1.append(repo.lookup(args[i]))
155
155
156 # calculate the graph for the supplied commits
156 # calculate the graph for the supplied commits
157 for i in range(len(want_sha1)):
157 for i in range(len(want_sha1)):
158 reachable.append({});
158 reachable.append({});
159 n = repo.changelog.lookup(want_sha1[i]);
159 n = want_sha1[i];
160 visit = [n];
160 visit = [n];
161 reachable[i][n] = 1
161 reachable[i][n] = 1
162 while visit:
162 while visit:
163 n = visit.pop(0)
163 n = visit.pop(0)
164 if n in stop_sha1:
164 if n in stop_sha1:
165 break
165 break
166 for p in repo.changelog.parents(n):
166 for p in repo.changelog.parents(n):
167 if p not in reachable[i]:
167 if p not in reachable[i]:
168 reachable[i][p] = 1
168 reachable[i][p] = 1
169 visit.append(p)
169 visit.append(p)
170 if p in stop_sha1:
170 if p in stop_sha1:
171 break
171 break
172
172
173 # walk the repository looking for commits that are in our
173 # walk the repository looking for commits that are in our
174 # reachability graph
174 # reachability graph
175 for i in range(repo.changelog.count()-1, -1, -1):
175 for i in range(repo.changelog.count()-1, -1, -1):
176 n = repo.changelog.node(i)
176 n = repo.changelog.node(i)
177 mask = is_reachable(want_sha1, reachable, n)
177 mask = is_reachable(want_sha1, reachable, n)
178 if mask:
178 if mask:
179 if not full:
179 if not full:
180 print hg.hex(n)
180 print hg.hex(n)
181 elif full is "commit":
181 elif full is "commit":
182 print hg.hex(n)
182 print hg.hex(n)
183 catcommit(repo, n, ' ')
183 catcommit(repo, n, ' ')
184 else:
184 else:
185 changes = repo.changelog.read(n)
185 changes = repo.changelog.read(n)
186 (p1, p2) = repo.changelog.parents(n)
186 (p1, p2) = repo.changelog.parents(n)
187 (h, h1, h2) = map(hg.hex, (n, p1, p2))
187 (h, h1, h2) = map(hg.hex, (n, p1, p2))
188 (i1, i2) = map(repo.changelog.rev, (p1, p2))
188 (i1, i2) = map(repo.changelog.rev, (p1, p2))
189
189
190 date = changes[2].split(' ')[0]
190 date = changes[2].split(' ')[0]
191 print "%s %s:%s" % (date, h, mask),
191 print "%s %s:%s" % (date, h, mask),
192 mask = is_reachable(want_sha1, reachable, p1)
192 mask = is_reachable(want_sha1, reachable, p1)
193 if i1 != -1 and mask > 0:
193 if i1 != -1 and mask > 0:
194 print "%s:%s " % (h1, mask),
194 print "%s:%s " % (h1, mask),
195 mask = is_reachable(want_sha1, reachable, p2)
195 mask = is_reachable(want_sha1, reachable, p2)
196 if i2 != -1 and mask > 0:
196 if i2 != -1 and mask > 0:
197 print "%s:%s " % (h2, mask),
197 print "%s:%s " % (h2, mask),
198 print ""
198 print ""
199 if maxnr and count >= maxnr:
199 if maxnr and count >= maxnr:
200 break
200 break
201 count += 1
201 count += 1
202
202
203 # git rev-list tries to order things by date, and has the ability to stop
203 # git rev-list tries to order things by date, and has the ability to stop
204 # at a given commit without walking the whole repo. TODO add the stop
204 # at a given commit without walking the whole repo. TODO add the stop
205 # parameter
205 # parameter
206 def revlist(args, repo):
206 def revlist(args, repo):
207 doptions = {}
207 doptions = {}
208 opts = [('c', 'commit', None, 'commit'),
208 opts = [('c', 'commit', None, 'commit'),
209 ('n', 'max-nr', 0, 'max-nr')]
209 ('n', 'max-nr', 0, 'max-nr')]
210 args = fancyopts.fancyopts(args, opts, doptions)
210 args = fancyopts.fancyopts(args, opts, doptions)
211 if doptions['commit']:
211 if doptions['commit']:
212 full = "commit"
212 full = "commit"
213 else:
213 else:
214 full = None
214 full = None
215 for i in range(1, len(args)):
215 for i in range(1, len(args)):
216 args[i] = '^' + args[i]
216 args[i] = '^' + args[i]
217 revtree(args, repo, full, doptions['max-nr'])
217 revtree(args, repo, full, doptions['max-nr'])
218
218
219 def catchterm(*args):
219 def catchterm(*args):
220 raise SignalInterrupt
220 raise SignalInterrupt
221
221
222 def help():
222 def help():
223 sys.stderr.write("commands:\n")
223 sys.stderr.write("commands:\n")
224 sys.stderr.write(" hgit cat-file [type] sha1\n")
224 sys.stderr.write(" hgit cat-file [type] sha1\n")
225 sys.stderr.write(" hgit diff-tree [-p] [-r] sha1 sha1\n")
225 sys.stderr.write(" hgit diff-tree [-p] [-r] sha1 sha1\n")
226 sys.stderr.write(" hgit rev-tree [sha1 ... [^stop sha1]]\n")
226 sys.stderr.write(" hgit rev-tree [sha1 ... [^stop sha1]]\n")
227 sys.stderr.write(" hgit rev-list [-c]\n")
227 sys.stderr.write(" hgit rev-list [-c] [sha1 [stop sha1]\n")
228
228
229 cmd = sys.argv[1]
229 cmd = sys.argv[1]
230 args = sys.argv[2:]
230 args = sys.argv[2:]
231 u = ui.ui()
231 u = ui.ui()
232 signal.signal(signal.SIGTERM, catchterm)
232 signal.signal(signal.SIGTERM, catchterm)
233 repo = hg.repository(ui = u)
233 repo = hg.repository(ui = u)
234
234
235 if cmd == "diff-tree":
235 if cmd == "diff-tree":
236 difftree(args, u, repo)
236 difftree(args, u, repo)
237
237
238 elif cmd == "cat-file":
238 elif cmd == "cat-file":
239 catfile(args, u, repo)
239 catfile(args, u, repo)
240
240
241 elif cmd == "rev-tree":
241 elif cmd == "rev-tree":
242 revtree(args, repo)
242 revtree(args, repo)
243
243
244 elif cmd == "rev-list":
244 elif cmd == "rev-list":
245 revlist(args, repo)
245 revlist(args, repo)
246
246
247 elif cmd == "help":
247 elif cmd == "help":
248 help()
248 help()
249
249
250 else:
250 else:
251 if cmd: sys.stderr.write("unknown command\n\n")
251 if cmd: sys.stderr.write("unknown command\n\n")
252 help()
252 help()
253 sys.exit(1)
253 sys.exit(1)
254
254
255 sys.exit(0)
255 sys.exit(0)
General Comments 0
You need to be logged in to leave comments. Login now