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, full="tree", maxnr=0): |
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 |
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 count = 0 |
146 |
147 |
147 # figure out which commits they are asking for and which ones they |
148 # figure out which commits they are asking for and which ones they |
148 # want us to stop on |
149 # want us to stop on |
149 for i in range(len(args)): |
150 for i in range(len(args)): |
150 if args[i].count('^'): |
151 if args[i].count('^'): |
151 s = args[i].split('^')[1] |
152 s = args[i].split('^')[1] |
152 stop_sha1.append(repo.changelog.lookup(s)) |
153 stop_sha1.append(repo.changelog.lookup(s)) |
153 want_sha1.append(s) |
154 want_sha1.append(s) |
154 elif args[i] != 'HEAD': |
155 elif args[i] != 'HEAD': |
155 want_sha1.append(args[i]) |
156 want_sha1.append(args[i]) |
|
157 |
156 # calculate the graph for the supplied commits |
158 # calculate the graph for the supplied commits |
157 for i in range(len(want_sha1)): |
159 for i in range(len(want_sha1)): |
158 reachable.append({}); |
160 reachable.append({}); |
159 n = repo.changelog.lookup(want_sha1[i]); |
161 n = repo.changelog.lookup(want_sha1[i]); |
160 visit = [n]; |
162 visit = [n]; |
167 if p not in reachable[i]: |
169 if p not in reachable[i]: |
168 reachable[i][p] = 1 |
170 reachable[i][p] = 1 |
169 visit.append(p) |
171 visit.append(p) |
170 if p in stop_sha1: |
172 if p in stop_sha1: |
171 break |
173 break |
|
174 |
172 # walk the repository looking for commits that are in our |
175 # walk the repository looking for commits that are in our |
173 # reachability graph |
176 # reachability graph |
174 for i in range(repo.changelog.count()): |
177 for i in range(repo.changelog.count()-1, -1, -1): |
175 n = repo.changelog.node(i) |
178 n = repo.changelog.node(i) |
176 mask = is_reachable(want_sha1, reachable, n) |
179 mask = is_reachable(want_sha1, reachable, n) |
177 if mask: |
180 if mask: |
178 changes = repo.changelog.read(n) |
181 if not full: |
179 (p1, p2) = repo.changelog.parents(n) |
182 print hg.hex(n) |
180 (h, h1, h2) = map(hg.hex, (n, p1, p2)) |
183 elif full is "commit": |
181 (i1, i2) = map(repo.changelog.rev, (p1, p2)) |
184 print hg.hex(n) |
182 |
185 catcommit(repo, n, ' ') |
183 date = changes[2].split(' ')[0] |
186 else: |
184 print "%s %s:%s" % (date, h, mask), |
187 changes = repo.changelog.read(n) |
185 mask = is_reachable(want_sha1, reachable, p1) |
188 (p1, p2) = repo.changelog.parents(n) |
186 if i1 != -1 and mask > 0: |
189 (h, h1, h2) = map(hg.hex, (n, p1, p2)) |
187 print "%s:%s " % (h1, mask), |
190 (i1, i2) = map(repo.changelog.rev, (p1, p2)) |
188 mask = is_reachable(want_sha1, reachable, p2) |
191 |
189 if i2 != -1 and mask > 0: |
192 date = changes[2].split(' ')[0] |
190 print "%s:%s " % (h2, mask), |
193 print "%s %s:%s" % (date, h, mask), |
191 print "" |
194 mask = is_reachable(want_sha1, reachable, p1) |
|
195 if i1 != -1 and mask > 0: |
|
196 print "%s:%s " % (h1, mask), |
|
197 mask = is_reachable(want_sha1, reachable, p2) |
|
198 if i2 != -1 and mask > 0: |
|
199 print "%s:%s " % (h2, mask), |
|
200 print "" |
|
201 if maxnr and count >= maxnr: |
|
202 break |
|
203 count += 1 |
192 |
204 |
193 # git rev-list tries to order things by date, and has the ability to stop |
205 # 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 |
206 # at a given commit without walking the whole repo. TODO add the stop |
195 # parameter |
207 # parameter |
196 def revlist(args, repo): |
208 def revlist(args, repo): |
197 doptions = {} |
209 doptions = {} |
198 opts = [('c', 'commit', None, 'commit')] |
210 opts = [('c', 'commit', None, 'commit'), |
|
211 ('n', 'max-nr', 0, 'max-nr')] |
199 args = fancyopts.fancyopts(args, opts, doptions, |
212 args = fancyopts.fancyopts(args, opts, doptions, |
200 'hg rev-list') |
213 'hg rev-list') |
201 for i in range(repo.changelog.count()): |
214 if doptions['commit']: |
202 n = repo.changelog.node(i) |
215 full = "commit" |
203 print hg.hex(n) |
216 else: |
204 if doptions['commit']: |
217 full = None |
205 catcommit(repo, n, ' ') |
218 for i in range(1, len(args)): |
|
219 args[i] = '^' + args[i] |
|
220 revtree(args, repo, full, doptions['max-nr']) |
206 |
221 |
207 def catchterm(*args): |
222 def catchterm(*args): |
208 raise SignalInterrupt |
223 raise SignalInterrupt |
209 |
224 |
210 def help(): |
225 def help(): |