##// END OF EJS Templates
hgk: remove unused code, node2 is always set
Benoit Boissinot -
r3978:ee5663cb default
parent child Browse files
Show More
@@ -1,308 +1,303 b''
1 1 # Minimal support for git commands on an hg repository
2 2 #
3 3 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 import sys, os
9 9 from mercurial import hg, fancyopts, commands, ui, util, patch, revlog
10 10
11 11 def difftree(ui, repo, node1=None, node2=None, *files, **opts):
12 12 """diff trees from two commits"""
13 13 def __difftree(repo, node1, node2, files=[]):
14 if node2:
15 change = repo.changelog.read(node2)
16 mmap2 = repo.manifest.read(change[0])
17 status = repo.status(node1, node2, files=files)[:5]
18 modified, added, removed, deleted, unknown = status
19 else:
20 status = repo.status(node1, files=files)[:5]
21 modified, added, removed, deleted, unknown = status
22 if not node1:
23 node1 = repo.dirstate.parents()[0]
14 assert node2 is not None
15 change = repo.changelog.read(node2)
16 mmap2 = repo.manifest.read(change[0])
17 status = repo.status(node1, node2, files=files)[:5]
18 modified, added, removed, deleted, unknown = status
24 19
25 20 change = repo.changelog.read(node1)
26 21 mmap = repo.manifest.read(change[0])
27 22 empty = hg.short(hg.nullid)
28 23
29 24 for f in modified:
30 25 # TODO get file permissions
31 26 print ":100664 100664 %s %s M\t%s\t%s" % (hg.short(mmap[f]),
32 27 hg.short(mmap2[f]),
33 28 f, f)
34 29 for f in added:
35 30 print ":000000 100664 %s %s N\t%s\t%s" % (empty,
36 31 hg.short(mmap2[f]),
37 32 f, f)
38 33 for f in removed:
39 34 print ":100664 000000 %s %s D\t%s\t%s" % (hg.short(mmap[f]),
40 35 empty,
41 36 f, f)
42 37 ##
43 38
44 39 while True:
45 40 if opts['stdin']:
46 41 try:
47 42 line = raw_input().split(' ')
48 43 node1 = line[0]
49 44 if len(line) > 1:
50 45 node2 = line[1]
51 46 else:
52 47 node2 = None
53 48 except EOFError:
54 49 break
55 50 node1 = repo.lookup(node1)
56 51 if node2:
57 52 node2 = repo.lookup(node2)
58 53 else:
59 54 node2 = node1
60 55 node1 = repo.changelog.parents(node1)[0]
61 56 if opts['patch']:
62 57 if opts['pretty']:
63 58 catcommit(repo, node2, "")
64 59 patch.diff(repo, node1, node2,
65 60 files=files,
66 61 opts=patch.diffopts(ui, {'git': True}))
67 62 else:
68 63 __difftree(repo, node1, node2, files=files)
69 64 if not opts['stdin']:
70 65 break
71 66
72 67 def catcommit(repo, n, prefix, changes=None):
73 68 nlprefix = '\n' + prefix;
74 69 (p1, p2) = repo.changelog.parents(n)
75 70 (h, h1, h2) = map(hg.short, (n, p1, p2))
76 71 (i1, i2) = map(repo.changelog.rev, (p1, p2))
77 72 if not changes:
78 73 changes = repo.changelog.read(n)
79 74 print "tree %s" % (hg.short(changes[0]))
80 75 if i1 != hg.nullrev: print "parent %s" % (h1)
81 76 if i2 != hg.nullrev: print "parent %s" % (h2)
82 77 date_ar = changes[2]
83 78 date = int(float(date_ar[0]))
84 79 lines = changes[4].splitlines()
85 80 if lines and lines[-1].startswith('committer:'):
86 81 committer = lines[-1].split(': ')[1].rstrip()
87 82 else:
88 83 committer = changes[1]
89 84
90 85 print "author %s %s %s" % (changes[1], date, date_ar[1])
91 86 print "committer %s %s %s" % (committer, date, date_ar[1])
92 87 print "revision %d" % repo.changelog.rev(n)
93 88 print ""
94 89 if prefix != "":
95 90 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
96 91 else:
97 92 print changes[4]
98 93 if prefix:
99 94 sys.stdout.write('\0')
100 95
101 96 def base(ui, repo, node1, node2):
102 97 """Output common ancestor information"""
103 98 node1 = repo.lookup(node1)
104 99 node2 = repo.lookup(node2)
105 100 n = repo.changelog.ancestor(node1, node2)
106 101 print hg.short(n)
107 102
108 103 def catfile(ui, repo, type=None, r=None, **opts):
109 104 """cat a specific revision"""
110 105 # in stdin mode, every line except the commit is prefixed with two
111 106 # spaces. This way the our caller can find the commit without magic
112 107 # strings
113 108 #
114 109 prefix = ""
115 110 if opts['stdin']:
116 111 try:
117 112 (type, r) = raw_input().split(' ');
118 113 prefix = " "
119 114 except EOFError:
120 115 return
121 116
122 117 else:
123 118 if not type or not r:
124 119 ui.warn("cat-file: type or revision not supplied\n")
125 120 commands.help_(ui, 'cat-file')
126 121
127 122 while r:
128 123 if type != "commit":
129 124 sys.stderr.write("aborting hg cat-file only understands commits\n")
130 125 sys.exit(1);
131 126 n = repo.lookup(r)
132 127 catcommit(repo, n, prefix)
133 128 if opts['stdin']:
134 129 try:
135 130 (type, r) = raw_input().split(' ');
136 131 except EOFError:
137 132 break
138 133 else:
139 134 break
140 135
141 136 # git rev-tree is a confusing thing. You can supply a number of
142 137 # commit sha1s on the command line, and it walks the commit history
143 138 # telling you which commits are reachable from the supplied ones via
144 139 # a bitmask based on arg position.
145 140 # you can specify a commit to stop at by starting the sha1 with ^
146 141 def revtree(args, repo, full="tree", maxnr=0, parents=False):
147 142 def chlogwalk():
148 143 ch = repo.changelog
149 144 count = ch.count()
150 145 i = count
151 146 l = [0] * 100
152 147 chunk = 100
153 148 while True:
154 149 if chunk > i:
155 150 chunk = i
156 151 i = 0
157 152 else:
158 153 i -= chunk
159 154
160 155 for x in xrange(0, chunk):
161 156 if i + x >= count:
162 157 l[chunk - x:] = [0] * (chunk - x)
163 158 break
164 159 if full != None:
165 160 l[x] = ch.read(ch.node(i + x))
166 161 else:
167 162 l[x] = 1
168 163 for x in xrange(chunk-1, -1, -1):
169 164 if l[x] != 0:
170 165 yield (i + x, full != None and l[x] or None)
171 166 if i == 0:
172 167 break
173 168
174 169 # calculate and return the reachability bitmask for sha
175 170 def is_reachable(ar, reachable, sha):
176 171 if len(ar) == 0:
177 172 return 1
178 173 mask = 0
179 174 for i in xrange(len(ar)):
180 175 if sha in reachable[i]:
181 176 mask |= 1 << i
182 177
183 178 return mask
184 179
185 180 reachable = []
186 181 stop_sha1 = []
187 182 want_sha1 = []
188 183 count = 0
189 184
190 185 # figure out which commits they are asking for and which ones they
191 186 # want us to stop on
192 187 for i in xrange(len(args)):
193 188 if args[i].startswith('^'):
194 189 s = repo.lookup(args[i][1:])
195 190 stop_sha1.append(s)
196 191 want_sha1.append(s)
197 192 elif args[i] != 'HEAD':
198 193 want_sha1.append(repo.lookup(args[i]))
199 194
200 195 # calculate the graph for the supplied commits
201 196 for i in xrange(len(want_sha1)):
202 197 reachable.append({});
203 198 n = want_sha1[i];
204 199 visit = [n];
205 200 reachable[i][n] = 1
206 201 while visit:
207 202 n = visit.pop(0)
208 203 if n in stop_sha1:
209 204 continue
210 205 for p in repo.changelog.parents(n):
211 206 if p not in reachable[i]:
212 207 reachable[i][p] = 1
213 208 visit.append(p)
214 209 if p in stop_sha1:
215 210 continue
216 211
217 212 # walk the repository looking for commits that are in our
218 213 # reachability graph
219 214 for i, changes in chlogwalk():
220 215 n = repo.changelog.node(i)
221 216 mask = is_reachable(want_sha1, reachable, n)
222 217 if mask:
223 218 parentstr = ""
224 219 if parents:
225 220 pp = repo.changelog.parents(n)
226 221 if pp[0] != hg.nullid:
227 222 parentstr += " " + hg.short(pp[0])
228 223 if pp[1] != hg.nullid:
229 224 parentstr += " " + hg.short(pp[1])
230 225 if not full:
231 226 print hg.short(n) + parentstr
232 227 elif full == "commit":
233 228 print hg.short(n) + parentstr
234 229 catcommit(repo, n, ' ', changes)
235 230 else:
236 231 (p1, p2) = repo.changelog.parents(n)
237 232 (h, h1, h2) = map(hg.short, (n, p1, p2))
238 233 (i1, i2) = map(repo.changelog.rev, (p1, p2))
239 234
240 235 date = changes[2][0]
241 236 print "%s %s:%s" % (date, h, mask),
242 237 mask = is_reachable(want_sha1, reachable, p1)
243 238 if i1 != hg.nullrev and mask > 0:
244 239 print "%s:%s " % (h1, mask),
245 240 mask = is_reachable(want_sha1, reachable, p2)
246 241 if i2 != hg.nullrev and mask > 0:
247 242 print "%s:%s " % (h2, mask),
248 243 print ""
249 244 if maxnr and count >= maxnr:
250 245 break
251 246 count += 1
252 247
253 248 def revparse(ui, repo, *revs, **opts):
254 249 """Parse given revisions"""
255 250 def revstr(rev):
256 251 if rev == 'HEAD':
257 252 rev = 'tip'
258 253 return revlog.hex(repo.lookup(rev))
259 254
260 255 for r in revs:
261 256 revrange = r.split(':', 1)
262 257 ui.write('%s\n' % revstr(revrange[0]))
263 258 if len(revrange) == 2:
264 259 ui.write('^%s\n' % revstr(revrange[1]))
265 260
266 261 # git rev-list tries to order things by date, and has the ability to stop
267 262 # at a given commit without walking the whole repo. TODO add the stop
268 263 # parameter
269 264 def revlist(ui, repo, *revs, **opts):
270 265 """print revisions"""
271 266 if opts['header']:
272 267 full = "commit"
273 268 else:
274 269 full = None
275 270 copy = [x for x in revs]
276 271 revtree(copy, repo, full, opts['max_count'], opts['parents'])
277 272
278 273 def view(ui, repo, *etc, **opts):
279 274 "start interactive history viewer"
280 275 os.chdir(repo.root)
281 276 optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
282 277 cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))
283 278 ui.debug("running %s\n" % cmd)
284 279 os.system(cmd)
285 280
286 281 cmdtable = {
287 282 "^view": (view,
288 283 [('l', 'limit', '', 'limit number of changes displayed')],
289 284 'hg view [-l LIMIT] [REVRANGE]'),
290 285 "debug-diff-tree": (difftree, [('p', 'patch', None, 'generate patch'),
291 286 ('r', 'recursive', None, 'recursive'),
292 287 ('P', 'pretty', None, 'pretty'),
293 288 ('s', 'stdin', None, 'stdin'),
294 289 ('C', 'copy', None, 'detect copies'),
295 290 ('S', 'search', "", 'search')],
296 291 "hg git-diff-tree [options] node1 node2 [files...]"),
297 292 "debug-cat-file": (catfile, [('s', 'stdin', None, 'stdin')],
298 293 "hg debug-cat-file [options] type file"),
299 294 "debug-merge-base": (base, [], "hg debug-merge-base node node"),
300 295 'debug-rev-parse': (revparse,
301 296 [('', 'default', '', 'ignored')],
302 297 "hg debug-rev-parse rev"),
303 298 "debug-rev-list": (revlist, [('H', 'header', None, 'header'),
304 299 ('t', 'topo-order', None, 'topo-order'),
305 300 ('p', 'parents', None, 'parents'),
306 301 ('n', 'max-count', 0, 'max-count')],
307 302 "hg debug-rev-list [options] revs"),
308 303 }
General Comments 0
You need to be logged in to leave comments. Login now