##// END OF EJS Templates
hgit: remove tabs...
mpm@selenic.com -
r334:29057420 default
parent child Browse files
Show More
@@ -1,243 +1,243
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, repo):
13 def difftree(args, 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) = repo.diffrevs(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 %s %s" % (hg.hex(mmap[f]),
41 print ":100664 100664 %s %s %s %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 %s %s" % (empty, hg.hex(mmap2[f]), f, f)
44 print ":000000 100664 %s %s %s %s" % (empty, hg.hex(mmap2[f]), f, f)
45 for f in d:
45 for f in d:
46 print ":100664 000000 %s %s %s %s" % (hg.hex(mmap[f]), empty, f, f)
46 print ":100664 000000 %s %s %s %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')
55 'hg diff-tree [options] sha1 sha1')
56
56
57 if len(args) < 2:
57 if len(args) < 2:
58 help()
58 help()
59 sys.exit(1)
59 sys.exit(1)
60 revs.append(repo.lookup(args[0]))
60 revs.append(repo.lookup(args[0]))
61 revs.append(repo.lookup(args[1]))
61 revs.append(repo.lookup(args[1]))
62 args = args[2:]
62 args = args[2:]
63 if doptions['patch']:
63 if doptions['patch']:
64 commands.dodiff(repo, args, *revs)
64 commands.dodiff(repo, args, *revs)
65 else:
65 else:
66 __difftree(repo, args, *revs)
66 __difftree(repo, args, *revs)
67
67
68 def catcommit(repo, n, prefix):
68 def catcommit(repo, n, prefix):
69 nlprefix = '\n' + prefix;
69 nlprefix = '\n' + prefix;
70 changes = repo.changelog.read(n)
70 changes = repo.changelog.read(n)
71 (p1, p2) = repo.changelog.parents(n)
71 (p1, p2) = repo.changelog.parents(n)
72 (h, h1, h2) = map(hg.hex, (n, p1, p2))
72 (h, h1, h2) = map(hg.hex, (n, p1, p2))
73 (i1, i2) = map(repo.changelog.rev, (p1, p2))
73 (i1, i2) = map(repo.changelog.rev, (p1, p2))
74 print "tree %s" % (h)
74 print "tree %s" % (h)
75 if i1 != -1: print "%sparent %s" % (prefix, h1)
75 if i1 != -1: print "%sparent %s" % (prefix, h1)
76 if i2 != -1: print "%sparent %s" % (prefix, h2)
76 if i2 != -1: print "%sparent %s" % (prefix, h2)
77 date_ar = changes[2].split(' ')
77 date_ar = changes[2].split(' ')
78 date = int(float(date_ar[0]))
78 date = int(float(date_ar[0]))
79 print "%sauthor <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
79 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])
80 print "%scommitter <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
81 print prefix
81 print prefix
82 if prefix != "":
82 if prefix != "":
83 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
83 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
84 else:
84 else:
85 print changes[4]
85 print changes[4]
86
86
87 def catfile(args, ui, repo):
87 def catfile(args, ui, repo):
88 doptions = {}
88 doptions = {}
89 opts = [('s', 'stdin', None, 'stdin')]
89 opts = [('s', 'stdin', None, 'stdin')]
90 args = fancyopts.fancyopts(args, opts, doptions,
90 args = fancyopts.fancyopts(args, opts, doptions,
91 'hg cat-file type sha1')
91 'hg cat-file type sha1')
92
92
93 # in stdin mode, every line except the commit is prefixed with two
93 # 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
94 # spaces. This way the our caller can find the commit without magic
95 # strings
95 # strings
96 #
96 #
97 prefix = ""
97 prefix = ""
98 if doptions['stdin']:
98 if doptions['stdin']:
99 try:
99 try:
100 (type, r) = raw_input().split(' ');
100 (type, r) = raw_input().split(' ');
101 prefix = " "
101 prefix = " "
102 except EOFError:
102 except EOFError:
103 return
103 return
104
104
105 else:
105 else:
106 if len(args) < 2:
106 if len(args) < 2:
107 help()
107 help()
108 sys.exit(1)
108 sys.exit(1)
109 type = args[0]
109 type = args[0]
110 r = args[1]
110 r = args[1]
111
111
112 while r:
112 while r:
113 if type != "commit":
113 if type != "commit":
114 sys.stderr.write("aborting hg cat-file only understands commits\n")
114 sys.stderr.write("aborting hg cat-file only understands commits\n")
115 sys.exit(1);
115 sys.exit(1);
116 n = repo.changelog.lookup(r)
116 n = repo.changelog.lookup(r)
117 catcommit(repo, n, prefix)
117 catcommit(repo, n, prefix)
118 if doptions['stdin']:
118 if doptions['stdin']:
119 try:
119 try:
120 (type, r) = raw_input().split(' ');
120 (type, r) = raw_input().split(' ');
121 except EOFError:
121 except EOFError:
122 break
122 break
123 else:
123 else:
124 break
124 break
125
125
126 # git rev-tree is a confusing thing. You can supply a number of
126 # 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
127 # commit sha1s on the command line, and it walks the commit history
128 # telling you which commits are reachable from the supplied ones via
128 # telling you which commits are reachable from the supplied ones via
129 # a bitmask based on arg position.
129 # a bitmask based on arg position.
130 # you can specify a commit to stop at by starting the sha1 with ^
130 # you can specify a commit to stop at by starting the sha1 with ^
131 def revtree(args, repo):
131 def revtree(args, repo):
132 # calculate and return the reachability bitmask for sha
132 # calculate and return the reachability bitmask for sha
133 def is_reachable(ar, reachable, sha):
133 def is_reachable(ar, reachable, sha):
134 if len(ar) == 0:
134 if len(ar) == 0:
135 return 1
135 return 1
136 mask = 0
136 mask = 0
137 for i in range(len(ar)):
137 for i in range(len(ar)):
138 if sha in reachable[i]:
138 if sha in reachable[i]:
139 mask |= 1 << i
139 mask |= 1 << i
140
140
141 return mask
141 return mask
142
142
143 reachable = []
143 reachable = []
144 stop_sha1 = []
144 stop_sha1 = []
145 want_sha1 = []
145 want_sha1 = []
146
146
147 # figure out which commits they are asking for and which ones they
147 # figure out which commits they are asking for and which ones they
148 # want us to stop on
148 # want us to stop on
149 for i in range(len(args)):
149 for i in range(len(args)):
150 if args[i].count('^'):
150 if args[i].count('^'):
151 s = args[i].split('^')[1]
151 s = args[i].split('^')[1]
152 stop_sha1.append(repo.changelog.lookup(s))
152 stop_sha1.append(repo.changelog.lookup(s))
153 want_sha1.append(s)
153 want_sha1.append(s)
154 elif args[i] != 'HEAD':
154 elif args[i] != 'HEAD':
155 want_sha1.append(args[i])
155 want_sha1.append(args[i])
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 = repo.changelog.lookup(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 # walk the repository looking for commits that are in our
172 # walk the repository looking for commits that are in our
173 # reachability graph
173 # reachability graph
174 for i in range(repo.changelog.count()):
174 for i in range(repo.changelog.count()):
175 n = repo.changelog.node(i)
175 n = repo.changelog.node(i)
176 mask = is_reachable(want_sha1, reachable, n)
176 mask = is_reachable(want_sha1, reachable, n)
177 if mask:
177 if mask:
178 changes = repo.changelog.read(n)
178 changes = repo.changelog.read(n)
179 (p1, p2) = repo.changelog.parents(n)
179 (p1, p2) = repo.changelog.parents(n)
180 (h, h1, h2) = map(hg.hex, (n, p1, p2))
180 (h, h1, h2) = map(hg.hex, (n, p1, p2))
181 (i1, i2) = map(repo.changelog.rev, (p1, p2))
181 (i1, i2) = map(repo.changelog.rev, (p1, p2))
182
182
183 date = changes[2].split(' ')[0]
183 date = changes[2].split(' ')[0]
184 print "%s %s:%s" % (date, h, mask),
184 print "%s %s:%s" % (date, h, mask),
185 mask = is_reachable(want_sha1, reachable, p1)
185 mask = is_reachable(want_sha1, reachable, p1)
186 if i1 != -1 and mask > 0:
186 if i1 != -1 and mask > 0:
187 print "%s:%s " % (h1, mask),
187 print "%s:%s " % (h1, mask),
188 mask = is_reachable(want_sha1, reachable, p2)
188 mask = is_reachable(want_sha1, reachable, p2)
189 if i2 != -1 and mask > 0:
189 if i2 != -1 and mask > 0:
190 print "%s:%s " % (h2, mask),
190 print "%s:%s " % (h2, mask),
191 print ""
191 print ""
192
192
193 # git rev-list tries to order things by date, and has the ability to stop
193 # git rev-list tries to order things by date, and has the ability to stop
194 # at a given commit without walking the whole repo. TODO add the stop
194 # at a given commit without walking the whole repo. TODO add the stop
195 # parameter
195 # parameter
196 def revlist(args, repo):
196 def revlist(args, repo):
197 doptions = {}
197 doptions = {}
198 opts = [('c', 'commit', None, 'commit')]
198 opts = [('c', 'commit', None, 'commit')]
199 args = fancyopts.fancyopts(args, opts, doptions,
199 args = fancyopts.fancyopts(args, opts, doptions,
200 'hg rev-list')
200 'hg rev-list')
201 for i in range(repo.changelog.count()):
201 for i in range(repo.changelog.count()):
202 n = repo.changelog.node(i)
202 n = repo.changelog.node(i)
203 print hg.hex(n)
203 print hg.hex(n)
204 if doptions['commit']:
204 if doptions['commit']:
205 catcommit(repo, n, ' ')
205 catcommit(repo, n, ' ')
206
206
207 def catchterm(*args):
207 def catchterm(*args):
208 raise SignalInterrupt
208 raise SignalInterrupt
209
209
210 def help():
210 def help():
211 sys.stderr.write("commands:\n")
211 sys.stderr.write("commands:\n")
212 sys.stderr.write(" hgit cat-file [type] sha1\n")
212 sys.stderr.write(" hgit cat-file [type] sha1\n")
213 sys.stderr.write(" hgit diff-tree [-p] [-r] sha1 sha1\n")
213 sys.stderr.write(" hgit diff-tree [-p] [-r] sha1 sha1\n")
214 sys.stderr.write(" hgit rev-tree [sha1 ... [^stop sha1]]\n")
214 sys.stderr.write(" hgit rev-tree [sha1 ... [^stop sha1]]\n")
215 sys.stderr.write(" hgit rev-list [-c]\n")
215 sys.stderr.write(" hgit rev-list [-c]\n")
216
216
217 cmd = sys.argv[1]
217 cmd = sys.argv[1]
218 args = sys.argv[2:]
218 args = sys.argv[2:]
219 u = ui.ui()
219 u = ui.ui()
220 signal.signal(signal.SIGTERM, catchterm)
220 signal.signal(signal.SIGTERM, catchterm)
221 repo = hg.repository(ui = u)
221 repo = hg.repository(ui = u)
222
222
223 if cmd == "diff-tree":
223 if cmd == "diff-tree":
224 difftree(args, repo)
224 difftree(args, repo)
225
225
226 elif cmd == "cat-file":
226 elif cmd == "cat-file":
227 catfile(args, ui, repo)
227 catfile(args, ui, repo)
228
228
229 elif cmd == "rev-tree":
229 elif cmd == "rev-tree":
230 revtree(args, repo)
230 revtree(args, repo)
231
231
232 elif cmd == "rev-list":
232 elif cmd == "rev-list":
233 revlist(args, repo)
233 revlist(args, repo)
234
234
235 elif cmd == "help":
235 elif cmd == "help":
236 help()
236 help()
237
237
238 else:
238 else:
239 if cmd: sys.stderr.write("unknown command\n\n")
239 if cmd: sys.stderr.write("unknown command\n\n")
240 help()
240 help()
241 sys.exit(1)
241 sys.exit(1)
242
242
243 sys.exit(0)
243 sys.exit(0)
General Comments 0
You need to be logged in to leave comments. Login now