##// END OF EJS Templates
Fix hgit usage of repo.changes and fancyopts to reflect current hg api
mason@suse.com -
r719:dda25857 default
parent child Browse files
Show More
@@ -1,258 +1,255
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) = repo.diffrevs(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 'hg diff-tree [options] sha1 sha1')
56
55
57 if len(args) < 2:
56 if len(args) < 2:
58 help()
57 help()
59 sys.exit(1)
58 sys.exit(1)
60 revs.append(repo.lookup(args[0]))
59 revs.append(repo.lookup(args[0]))
61 revs.append(repo.lookup(args[1]))
60 revs.append(repo.lookup(args[1]))
62 args = args[2:]
61 args = args[2:]
63 if doptions['patch']:
62 if doptions['patch']:
64 commands.dodiff(ui, repo, "", args, *revs)
63 commands.dodiff(sys.stdout, ui, repo, args, *revs)
65 else:
64 else:
66 __difftree(repo, args, *revs)
65 __difftree(repo, args, *revs)
67
66
68 def catcommit(repo, n, prefix):
67 def catcommit(repo, n, prefix):
69 nlprefix = '\n' + prefix;
68 nlprefix = '\n' + prefix;
70 changes = repo.changelog.read(n)
69 changes = repo.changelog.read(n)
71 (p1, p2) = repo.changelog.parents(n)
70 (p1, p2) = repo.changelog.parents(n)
72 (h, h1, h2) = map(hg.hex, (n, p1, p2))
71 (h, h1, h2) = map(hg.hex, (n, p1, p2))
73 (i1, i2) = map(repo.changelog.rev, (p1, p2))
72 (i1, i2) = map(repo.changelog.rev, (p1, p2))
74 print "tree %s" % (h)
73 print "tree %s" % (h)
75 if i1 != -1: print "%sparent %s" % (prefix, h1)
74 if i1 != -1: print "%sparent %s" % (prefix, h1)
76 if i2 != -1: print "%sparent %s" % (prefix, h2)
75 if i2 != -1: print "%sparent %s" % (prefix, h2)
77 date_ar = changes[2].split(' ')
76 date_ar = changes[2].split(' ')
78 date = int(float(date_ar[0]))
77 date = int(float(date_ar[0]))
79 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])
80 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])
81 print prefix
80 print prefix
82 if prefix != "":
81 if prefix != "":
83 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
82 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
84 else:
83 else:
85 print changes[4]
84 print changes[4]
86
85
87 def catfile(args, ui, repo):
86 def catfile(args, ui, repo):
88 doptions = {}
87 doptions = {}
89 opts = [('s', 'stdin', None, 'stdin')]
88 opts = [('s', 'stdin', None, 'stdin')]
90 args = fancyopts.fancyopts(args, opts, doptions,
89 args = fancyopts.fancyopts(args, opts, doptions)
91 'hg cat-file type sha1')
92
90
93 # 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
94 # 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
95 # strings
93 # strings
96 #
94 #
97 prefix = ""
95 prefix = ""
98 if doptions['stdin']:
96 if doptions['stdin']:
99 try:
97 try:
100 (type, r) = raw_input().split(' ');
98 (type, r) = raw_input().split(' ');
101 prefix = " "
99 prefix = " "
102 except EOFError:
100 except EOFError:
103 return
101 return
104
102
105 else:
103 else:
106 if len(args) < 2:
104 if len(args) < 2:
107 help()
105 help()
108 sys.exit(1)
106 sys.exit(1)
109 type = args[0]
107 type = args[0]
110 r = args[1]
108 r = args[1]
111
109
112 while r:
110 while r:
113 if type != "commit":
111 if type != "commit":
114 sys.stderr.write("aborting hg cat-file only understands commits\n")
112 sys.stderr.write("aborting hg cat-file only understands commits\n")
115 sys.exit(1);
113 sys.exit(1);
116 n = repo.changelog.lookup(r)
114 n = repo.changelog.lookup(r)
117 catcommit(repo, n, prefix)
115 catcommit(repo, n, prefix)
118 if doptions['stdin']:
116 if doptions['stdin']:
119 try:
117 try:
120 (type, r) = raw_input().split(' ');
118 (type, r) = raw_input().split(' ');
121 except EOFError:
119 except EOFError:
122 break
120 break
123 else:
121 else:
124 break
122 break
125
123
126 # 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
127 # 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
128 # telling you which commits are reachable from the supplied ones via
126 # telling you which commits are reachable from the supplied ones via
129 # a bitmask based on arg position.
127 # a bitmask based on arg position.
130 # 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 ^
131 def revtree(args, repo, full="tree", maxnr=0):
129 def revtree(args, repo, full="tree", maxnr=0):
132 # calculate and return the reachability bitmask for sha
130 # calculate and return the reachability bitmask for sha
133 def is_reachable(ar, reachable, sha):
131 def is_reachable(ar, reachable, sha):
134 if len(ar) == 0:
132 if len(ar) == 0:
135 return 1
133 return 1
136 mask = 0
134 mask = 0
137 for i in range(len(ar)):
135 for i in range(len(ar)):
138 if sha in reachable[i]:
136 if sha in reachable[i]:
139 mask |= 1 << i
137 mask |= 1 << i
140
138
141 return mask
139 return mask
142
140
143 reachable = []
141 reachable = []
144 stop_sha1 = []
142 stop_sha1 = []
145 want_sha1 = []
143 want_sha1 = []
146 count = 0
144 count = 0
147
145
148 # 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
149 # want us to stop on
147 # want us to stop on
150 for i in range(len(args)):
148 for i in range(len(args)):
151 if args[i].count('^'):
149 if args[i].count('^'):
152 s = args[i].split('^')[1]
150 s = args[i].split('^')[1]
153 stop_sha1.append(repo.changelog.lookup(s))
151 stop_sha1.append(repo.changelog.lookup(s))
154 want_sha1.append(s)
152 want_sha1.append(s)
155 elif args[i] != 'HEAD':
153 elif args[i] != 'HEAD':
156 want_sha1.append(args[i])
154 want_sha1.append(args[i])
157
155
158 # calculate the graph for the supplied commits
156 # calculate the graph for the supplied commits
159 for i in range(len(want_sha1)):
157 for i in range(len(want_sha1)):
160 reachable.append({});
158 reachable.append({});
161 n = repo.changelog.lookup(want_sha1[i]);
159 n = repo.changelog.lookup(want_sha1[i]);
162 visit = [n];
160 visit = [n];
163 reachable[i][n] = 1
161 reachable[i][n] = 1
164 while visit:
162 while visit:
165 n = visit.pop(0)
163 n = visit.pop(0)
166 if n in stop_sha1:
164 if n in stop_sha1:
167 break
165 break
168 for p in repo.changelog.parents(n):
166 for p in repo.changelog.parents(n):
169 if p not in reachable[i]:
167 if p not in reachable[i]:
170 reachable[i][p] = 1
168 reachable[i][p] = 1
171 visit.append(p)
169 visit.append(p)
172 if p in stop_sha1:
170 if p in stop_sha1:
173 break
171 break
174
172
175 # walk the repository looking for commits that are in our
173 # walk the repository looking for commits that are in our
176 # reachability graph
174 # reachability graph
177 for i in range(repo.changelog.count()-1, -1, -1):
175 for i in range(repo.changelog.count()-1, -1, -1):
178 n = repo.changelog.node(i)
176 n = repo.changelog.node(i)
179 mask = is_reachable(want_sha1, reachable, n)
177 mask = is_reachable(want_sha1, reachable, n)
180 if mask:
178 if mask:
181 if not full:
179 if not full:
182 print hg.hex(n)
180 print hg.hex(n)
183 elif full is "commit":
181 elif full is "commit":
184 print hg.hex(n)
182 print hg.hex(n)
185 catcommit(repo, n, ' ')
183 catcommit(repo, n, ' ')
186 else:
184 else:
187 changes = repo.changelog.read(n)
185 changes = repo.changelog.read(n)
188 (p1, p2) = repo.changelog.parents(n)
186 (p1, p2) = repo.changelog.parents(n)
189 (h, h1, h2) = map(hg.hex, (n, p1, p2))
187 (h, h1, h2) = map(hg.hex, (n, p1, p2))
190 (i1, i2) = map(repo.changelog.rev, (p1, p2))
188 (i1, i2) = map(repo.changelog.rev, (p1, p2))
191
189
192 date = changes[2].split(' ')[0]
190 date = changes[2].split(' ')[0]
193 print "%s %s:%s" % (date, h, mask),
191 print "%s %s:%s" % (date, h, mask),
194 mask = is_reachable(want_sha1, reachable, p1)
192 mask = is_reachable(want_sha1, reachable, p1)
195 if i1 != -1 and mask > 0:
193 if i1 != -1 and mask > 0:
196 print "%s:%s " % (h1, mask),
194 print "%s:%s " % (h1, mask),
197 mask = is_reachable(want_sha1, reachable, p2)
195 mask = is_reachable(want_sha1, reachable, p2)
198 if i2 != -1 and mask > 0:
196 if i2 != -1 and mask > 0:
199 print "%s:%s " % (h2, mask),
197 print "%s:%s " % (h2, mask),
200 print ""
198 print ""
201 if maxnr and count >= maxnr:
199 if maxnr and count >= maxnr:
202 break
200 break
203 count += 1
201 count += 1
204
202
205 # 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
206 # 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
207 # parameter
205 # parameter
208 def revlist(args, repo):
206 def revlist(args, repo):
209 doptions = {}
207 doptions = {}
210 opts = [('c', 'commit', None, 'commit'),
208 opts = [('c', 'commit', None, 'commit'),
211 ('n', 'max-nr', 0, 'max-nr')]
209 ('n', 'max-nr', 0, 'max-nr')]
212 args = fancyopts.fancyopts(args, opts, doptions,
210 args = fancyopts.fancyopts(args, opts, doptions)
213 'hg rev-list')
214 if doptions['commit']:
211 if doptions['commit']:
215 full = "commit"
212 full = "commit"
216 else:
213 else:
217 full = None
214 full = None
218 for i in range(1, len(args)):
215 for i in range(1, len(args)):
219 args[i] = '^' + args[i]
216 args[i] = '^' + args[i]
220 revtree(args, repo, full, doptions['max-nr'])
217 revtree(args, repo, full, doptions['max-nr'])
221
218
222 def catchterm(*args):
219 def catchterm(*args):
223 raise SignalInterrupt
220 raise SignalInterrupt
224
221
225 def help():
222 def help():
226 sys.stderr.write("commands:\n")
223 sys.stderr.write("commands:\n")
227 sys.stderr.write(" hgit cat-file [type] sha1\n")
224 sys.stderr.write(" hgit cat-file [type] sha1\n")
228 sys.stderr.write(" hgit diff-tree [-p] [-r] sha1 sha1\n")
225 sys.stderr.write(" hgit diff-tree [-p] [-r] sha1 sha1\n")
229 sys.stderr.write(" hgit rev-tree [sha1 ... [^stop sha1]]\n")
226 sys.stderr.write(" hgit rev-tree [sha1 ... [^stop sha1]]\n")
230 sys.stderr.write(" hgit rev-list [-c]\n")
227 sys.stderr.write(" hgit rev-list [-c]\n")
231
228
232 cmd = sys.argv[1]
229 cmd = sys.argv[1]
233 args = sys.argv[2:]
230 args = sys.argv[2:]
234 u = ui.ui()
231 u = ui.ui()
235 signal.signal(signal.SIGTERM, catchterm)
232 signal.signal(signal.SIGTERM, catchterm)
236 repo = hg.repository(ui = u)
233 repo = hg.repository(ui = u)
237
234
238 if cmd == "diff-tree":
235 if cmd == "diff-tree":
239 difftree(args, u, repo)
236 difftree(args, u, repo)
240
237
241 elif cmd == "cat-file":
238 elif cmd == "cat-file":
242 catfile(args, u, repo)
239 catfile(args, u, repo)
243
240
244 elif cmd == "rev-tree":
241 elif cmd == "rev-tree":
245 revtree(args, repo)
242 revtree(args, repo)
246
243
247 elif cmd == "rev-list":
244 elif cmd == "rev-list":
248 revlist(args, repo)
245 revlist(args, repo)
249
246
250 elif cmd == "help":
247 elif cmd == "help":
251 help()
248 help()
252
249
253 else:
250 else:
254 if cmd: sys.stderr.write("unknown command\n\n")
251 if cmd: sys.stderr.write("unknown command\n\n")
255 help()
252 help()
256 sys.exit(1)
253 sys.exit(1)
257
254
258 sys.exit(0)
255 sys.exit(0)
General Comments 0
You need to be logged in to leave comments. Login now