50 |
50 |
51 def _hlp2(i): |
51 def _hlp2(i): |
52 """return highest power of two lower than 'i'""" |
52 """return highest power of two lower than 'i'""" |
53 return 2 ** int(math.log(i - 1, 2)) |
53 return 2 ** int(math.log(i - 1, 2)) |
54 |
54 |
55 def subrangesclosure(repo, heads): |
55 def subrangesclosure(repo, stablerange, heads): |
56 """set of all standard subrange under heads |
56 """set of all standard subrange under heads |
57 |
57 |
58 This is intended for debug purposes. Range are returned from largest to |
58 This is intended for debug purposes. Range are returned from largest to |
59 smallest in terms of number of revision it contains.""" |
59 smallest in terms of number of revision it contains.""" |
60 subranges = repo.stablerange.subranges |
60 subranges = stablerange.subranges |
61 toproceed = [(r, 0, ) for r in heads] |
61 toproceed = [(r, 0, ) for r in heads] |
62 ranges = set(toproceed) |
62 ranges = set(toproceed) |
63 while toproceed: |
63 while toproceed: |
64 entry = toproceed.pop() |
64 entry = toproceed.pop() |
65 for r in subranges(repo, entry): |
65 for r in subranges(repo, entry): |
66 if r not in ranges: |
66 if r not in ranges: |
67 ranges.add(r) |
67 ranges.add(r) |
68 toproceed.append(r) |
68 toproceed.append(r) |
69 ranges = list(ranges) |
69 ranges = list(ranges) |
70 n = repo.changelog.node |
70 n = repo.changelog.node |
71 rangelength = repo.stablerange.rangelength |
71 rangelength = stablerange.rangelength |
72 ranges.sort(key=lambda r: (-rangelength(repo, r), n(r[0]))) |
72 ranges.sort(key=lambda r: (-rangelength(repo, r), n(r[0]))) |
73 return ranges |
73 return ranges |
|
74 |
|
75 _stablerangemethodmap = { |
|
76 'branchpoint': lambda repo: repo.stablerange, |
|
77 } |
74 |
78 |
75 @eh.command( |
79 @eh.command( |
76 'debugstablerange', |
80 'debugstablerange', |
77 [ |
81 [ |
78 ('', 'rev', [], 'operate on (rev, 0) ranges for rev in REVS'), |
82 ('r', 'rev', [], 'operate on (rev, 0) ranges for rev in REVS'), |
79 ('', 'subranges', False, 'recursively display data for subranges too'), |
83 ('', 'subranges', False, 'recursively display data for subranges too'), |
80 ('', 'verify', False, 'checks subranges content (EXPENSIVE)'), |
84 ('', 'verify', False, 'checks subranges content (EXPENSIVE)'), |
|
85 ('', 'method', 'branchpoint', |
|
86 'method to use, one of "branchpoint", "mergepoint"') |
81 ], |
87 ], |
82 _('')) |
88 _('')) |
83 def debugstablerange(ui, repo, **opts): |
89 def debugstablerange(ui, repo, **opts): |
84 """display standard stable subrange for a set of ranges |
90 """display standard stable subrange for a set of ranges |
85 |
91 |
86 Range as displayed as '<node>-<index> (<rev>, <depth>, <length>)', use |
92 Range as displayed as '<node>-<index> (<rev>, <depth>, <length>)', use |
87 --verbose to get the extra details in (). |
93 --verbose to get the extra details in (). |
88 """ |
94 """ |
89 short = nodemod.short |
95 short = nodemod.short |
90 revs = scmutil.revrange(repo, opts['rev']) |
96 revs = scmutil.revrange(repo, opts['rev']) |
91 # prewarm depth cache |
|
92 unfi = repo.unfiltered() |
|
93 node = unfi.changelog.node |
|
94 stablerange = unfi.stablerange |
|
95 depth = stablerange.depthrev |
|
96 length = stablerange.rangelength |
|
97 subranges = stablerange.subranges |
|
98 if not revs: |
97 if not revs: |
99 raise error.Abort('no revisions specified') |
98 raise error.Abort('no revisions specified') |
100 repo.stablerange.warmup(repo, max(revs)) |
|
101 if opts['subranges']: |
|
102 ranges = subrangesclosure(repo, revs) |
|
103 else: |
|
104 ranges = [(r, 0) for r in revs] |
|
105 if ui.verbose: |
99 if ui.verbose: |
106 template = '%s-%d (%d, %d, %d)' |
100 template = '%s-%d (%d, %d, %d)' |
107 |
101 |
108 def _rangestring(repo, rangeid): |
102 def _rangestring(repo, rangeid): |
109 return template % ( |
103 return template % ( |
119 def _rangestring(repo, rangeid): |
113 def _rangestring(repo, rangeid): |
120 return template % ( |
114 return template % ( |
121 short(node(rangeid[0])), |
115 short(node(rangeid[0])), |
122 rangeid[1], |
116 rangeid[1], |
123 ) |
117 ) |
|
118 # prewarm depth cache |
|
119 unfi = repo.unfiltered() |
|
120 node = unfi.changelog.node |
|
121 |
|
122 method = opts['method'] |
|
123 getstablerange = _stablerangemethodmap.get(method) |
|
124 if getstablerange is None: |
|
125 raise error.Abort('unknown stable sort method: "%s"' % method) |
|
126 |
|
127 stablerange = getstablerange(unfi) |
|
128 depth = stablerange.depthrev |
|
129 length = stablerange.rangelength |
|
130 subranges = stablerange.subranges |
|
131 stablerange.warmup(repo, max(revs)) |
|
132 |
|
133 if opts['subranges']: |
|
134 ranges = subrangesclosure(repo, stablerange, revs) |
|
135 else: |
|
136 ranges = [(r, 0) for r in revs] |
124 |
137 |
125 for r in ranges: |
138 for r in ranges: |
126 subs = subranges(unfi, r) |
139 subs = subranges(unfi, r) |
127 subsstr = ', '.join(_rangestring(unfi, s) for s in subs) |
140 subsstr = ', '.join(_rangestring(unfi, s) for s in subs) |
128 rstr = _rangestring(unfi, r) |
141 rstr = _rangestring(unfi, r) |