Show More
@@ -187,7 +187,7 b' class changelog(revlog.revlog):' | |||||
187 |
|
187 | |||
188 | def reachableroots(self, minroot, heads, roots, includepath=False): |
|
188 | def reachableroots(self, minroot, heads, roots, includepath=False): | |
189 | return revset.baseset(sorted( |
|
189 | return revset.baseset(sorted( | |
190 | self.index.reachableroots(minroot, heads, roots, includepath))) |
|
190 | self.index.reachableroots2(minroot, heads, roots, includepath))) | |
191 |
|
191 | |||
192 | def headrevs(self): |
|
192 | def headrevs(self): | |
193 | if self.filteredrevs: |
|
193 | if self.filteredrevs: |
@@ -1108,16 +1108,15 b' static inline void set_phase_from_parent' | |||||
1108 | phases[i] = phases[parent_2]; |
|
1108 | phases[i] = phases[parent_2]; | |
1109 | } |
|
1109 | } | |
1110 |
|
1110 | |||
1111 | static PyObject *reachableroots(indexObject *self, PyObject *args) |
|
1111 | static PyObject *reachableroots2(indexObject *self, PyObject *args) | |
1112 | { |
|
1112 | { | |
1113 |
|
1113 | |||
1114 | /* Input */ |
|
1114 | /* Input */ | |
1115 | long minroot; |
|
1115 | long minroot; | |
1116 | PyObject *includepatharg = NULL; |
|
1116 | PyObject *includepatharg = NULL; | |
1117 | int includepath = 0; |
|
1117 | int includepath = 0; | |
1118 |
/* heads |
|
1118 | /* heads and roots are lists */ | |
1119 | PyObject *heads = NULL; |
|
1119 | PyObject *heads = NULL; | |
1120 | /* roots is a set */ |
|
|||
1121 | PyObject *roots = NULL; |
|
1120 | PyObject *roots = NULL; | |
1122 | PyObject *reachable = NULL; |
|
1121 | PyObject *reachable = NULL; | |
1123 |
|
1122 | |||
@@ -1136,12 +1135,13 b' static PyObject *reachableroots(indexObj' | |||||
1136 | * revstates: array of length len+1 (all revs + nullrev) */ |
|
1135 | * revstates: array of length len+1 (all revs + nullrev) */ | |
1137 | int *tovisit = NULL; |
|
1136 | int *tovisit = NULL; | |
1138 | long lentovisit = 0; |
|
1137 | long lentovisit = 0; | |
1139 | enum { RS_SEEN = 1 }; |
|
1138 | enum { RS_SEEN = 1, RS_ROOT = 2 }; | |
1140 | char *revstates = NULL; |
|
1139 | char *revstates = NULL; | |
1141 |
|
1140 | |||
1142 | /* Get arguments */ |
|
1141 | /* Get arguments */ | |
1143 | if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads, |
|
1142 | if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads, | |
1144 | &PySet_Type, &roots, &PyBool_Type, &includepatharg)) |
|
1143 | &PyList_Type, &roots, | |
|
1144 | &PyBool_Type, &includepatharg)) | |||
1145 | goto bail; |
|
1145 | goto bail; | |
1146 |
|
1146 | |||
1147 | if (includepatharg == Py_True) |
|
1147 | if (includepatharg == Py_True) | |
@@ -1167,6 +1167,18 b' static PyObject *reachableroots(indexObj' | |||||
1167 | goto bail; |
|
1167 | goto bail; | |
1168 | } |
|
1168 | } | |
1169 |
|
1169 | |||
|
1170 | l = PyList_GET_SIZE(roots); | |||
|
1171 | for (i = 0; i < l; i++) { | |||
|
1172 | revnum = PyInt_AsLong(PyList_GET_ITEM(roots, i)); | |||
|
1173 | if (revnum == -1 && PyErr_Occurred()) | |||
|
1174 | goto bail; | |||
|
1175 | /* If root is out of range, e.g. wdir(), it must be unreachable | |||
|
1176 | * from heads. So we can just ignore it. */ | |||
|
1177 | if (revnum + 1 < 0 || revnum + 1 >= len + 1) | |||
|
1178 | continue; | |||
|
1179 | revstates[revnum + 1] |= RS_ROOT; | |||
|
1180 | } | |||
|
1181 | ||||
1170 | /* Populate tovisit with all the heads */ |
|
1182 | /* Populate tovisit with all the heads */ | |
1171 | l = PyList_GET_SIZE(heads); |
|
1183 | l = PyList_GET_SIZE(heads); | |
1172 | for (i = 0; i < l; i++) { |
|
1184 | for (i = 0; i < l; i++) { | |
@@ -1188,17 +1200,15 b' static PyObject *reachableroots(indexObj' | |||||
1188 | while (k < lentovisit) { |
|
1200 | while (k < lentovisit) { | |
1189 | /* Add the node to reachable if it is a root*/ |
|
1201 | /* Add the node to reachable if it is a root*/ | |
1190 | revnum = tovisit[k++]; |
|
1202 | revnum = tovisit[k++]; | |
1191 | val = PyInt_FromLong(revnum); |
|
1203 | if (revstates[revnum + 1] & RS_ROOT) { | |
1192 | if (val == NULL) |
|
1204 | val = PyInt_FromLong(revnum); | |
1193 | goto bail; |
|
1205 | if (val == NULL) | |
1194 | if (PySet_Contains(roots, val) == 1) { |
|
1206 | goto bail; | |
1195 | PySet_Add(reachable, val); |
|
1207 | PySet_Add(reachable, val); | |
1196 | if (includepath == 0) { |
|
1208 | Py_DECREF(val); | |
1197 | Py_DECREF(val); |
|
1209 | if (includepath == 0) | |
1198 | continue; |
|
1210 | continue; | |
1199 | } |
|
|||
1200 | } |
|
1211 | } | |
1201 | Py_DECREF(val); |
|
|||
1202 |
|
1212 | |||
1203 | /* Add its parents to the list of nodes to visit */ |
|
1213 | /* Add its parents to the list of nodes to visit */ | |
1204 | if (revnum == -1) |
|
1214 | if (revnum == -1) | |
@@ -2434,7 +2444,7 b' static PyMethodDef index_methods[] = {' | |||||
2434 | "get an index entry"}, |
|
2444 | "get an index entry"}, | |
2435 | {"computephasesmapsets", (PyCFunction)compute_phases_map_sets, |
|
2445 | {"computephasesmapsets", (PyCFunction)compute_phases_map_sets, | |
2436 | METH_VARARGS, "compute phases"}, |
|
2446 | METH_VARARGS, "compute phases"}, | |
2437 | {"reachableroots", (PyCFunction)reachableroots, METH_VARARGS, |
|
2447 | {"reachableroots2", (PyCFunction)reachableroots2, METH_VARARGS, | |
2438 | "reachableroots"}, |
|
2448 | "reachableroots"}, | |
2439 | {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS, |
|
2449 | {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS, | |
2440 | "get head revisions"}, /* Can do filtering since 3.2 */ |
|
2450 | "get head revisions"}, /* Can do filtering since 3.2 */ |
@@ -94,6 +94,7 b' def reachablerootspure(repo, minroot, ro' | |||||
94 | if not roots: |
|
94 | if not roots: | |
95 | return baseset() |
|
95 | return baseset() | |
96 | parentrevs = repo.changelog.parentrevs |
|
96 | parentrevs = repo.changelog.parentrevs | |
|
97 | roots = set(roots) | |||
97 | visit = list(heads) |
|
98 | visit = list(heads) | |
98 | reachable = set() |
|
99 | reachable = set() | |
99 | seen = {} |
|
100 | seen = {} | |
@@ -133,7 +134,7 b' def reachableroots(repo, roots, heads, i' | |||||
133 | # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset |
|
134 | # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset | |
134 | # (and if it is not, it should.) |
|
135 | # (and if it is not, it should.) | |
135 | minroot = min(roots) |
|
136 | minroot = min(roots) | |
136 |
roots = s |
|
137 | roots = list(roots) | |
137 | heads = list(heads) |
|
138 | heads = list(heads) | |
138 | try: |
|
139 | try: | |
139 | return repo.changelog.reachableroots(minroot, heads, roots, includepath) |
|
140 | return repo.changelog.reachableroots(minroot, heads, roots, includepath) |
@@ -69,28 +69,53 b' Test SEGV caused by bad revision passed ' | |||||
69 | $ python <<EOF |
|
69 | $ python <<EOF | |
70 | > from mercurial import changelog, scmutil |
|
70 | > from mercurial import changelog, scmutil | |
71 | > cl = changelog.changelog(scmutil.vfs('.hg/store')) |
|
71 | > cl = changelog.changelog(scmutil.vfs('.hg/store')) | |
72 | > print 'goods:' |
|
72 | > print 'good heads:' | |
73 | > for head in [0, len(cl) - 1, -1]: |
|
73 | > for head in [0, len(cl) - 1, -1]: | |
74 |
> print'%s: %r' % (head, cl.reachableroots(0, [head], |
|
74 | > print'%s: %r' % (head, cl.reachableroots(0, [head], [0])) | |
75 | > print 'bads:' |
|
75 | > print 'bad heads:' | |
76 | > for head in [len(cl), 10000, -2, -10000, None]: |
|
76 | > for head in [len(cl), 10000, -2, -10000, None]: | |
77 | > print '%s:' % head, |
|
77 | > print '%s:' % head, | |
78 | > try: |
|
78 | > try: | |
79 |
> cl.reachableroots(0, [head], |
|
79 | > cl.reachableroots(0, [head], [0]) | |
80 | > print 'uncaught buffer overflow?' |
|
80 | > print 'uncaught buffer overflow?' | |
81 | > except (IndexError, TypeError) as inst: |
|
81 | > except (IndexError, TypeError) as inst: | |
82 | > print inst |
|
82 | > print inst | |
|
83 | > print 'good roots:' | |||
|
84 | > for root in [0, len(cl) - 1, -1]: | |||
|
85 | > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root])) | |||
|
86 | > print 'out-of-range roots are ignored:' | |||
|
87 | > for root in [len(cl), 10000, -2, -10000]: | |||
|
88 | > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root])) | |||
|
89 | > print 'bad roots:' | |||
|
90 | > for root in [None]: | |||
|
91 | > print '%s:' % root, | |||
|
92 | > try: | |||
|
93 | > cl.reachableroots(root, [len(cl) - 1], [root]) | |||
|
94 | > print 'uncaught error?' | |||
|
95 | > except TypeError as inst: | |||
|
96 | > print inst | |||
83 | > EOF |
|
97 | > EOF | |
84 | goods: |
|
98 | good heads: | |
85 | 0: <baseset [0]> |
|
99 | 0: <baseset [0]> | |
86 | 1: <baseset [0]> |
|
100 | 1: <baseset [0]> | |
87 | -1: <baseset []> |
|
101 | -1: <baseset []> | |
88 | bads: |
|
102 | bad heads: | |
89 | 2: head out of range |
|
103 | 2: head out of range | |
90 | 10000: head out of range |
|
104 | 10000: head out of range | |
91 | -2: head out of range |
|
105 | -2: head out of range | |
92 | -10000: head out of range |
|
106 | -10000: head out of range | |
93 | None: an integer is required |
|
107 | None: an integer is required | |
|
108 | good roots: | |||
|
109 | 0: <baseset [0]> | |||
|
110 | 1: <baseset [1]> | |||
|
111 | -1: <baseset [-1]> | |||
|
112 | out-of-range roots are ignored: | |||
|
113 | 2: <baseset []> | |||
|
114 | 10000: <baseset []> | |||
|
115 | -2: <baseset []> | |||
|
116 | -10000: <baseset []> | |||
|
117 | bad roots: | |||
|
118 | None: an integer is required | |||
94 |
|
119 | |||
95 | $ cd .. |
|
120 | $ cd .. | |
96 |
|
121 | |||
@@ -127,7 +152,7 b' Test corrupted p1/p2 fields that could c' | |||||
127 | > n0, n1 = cl.node(0), cl.node(1) |
|
152 | > n0, n1 = cl.node(0), cl.node(1) | |
128 | > ops = [ |
|
153 | > ops = [ | |
129 | > ('reachableroots', |
|
154 | > ('reachableroots', | |
130 |
> lambda: cl.index.reachableroots(0, [1], |
|
155 | > lambda: cl.index.reachableroots2(0, [1], [0], False)), | |
131 | > ('compute_phases_map_sets', lambda: cl.computephases([[0], []])), |
|
156 | > ('compute_phases_map_sets', lambda: cl.computephases([[0], []])), | |
132 | > ('index_headrevs', lambda: cl.headrevs()), |
|
157 | > ('index_headrevs', lambda: cl.headrevs()), | |
133 | > ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)), |
|
158 | > ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)), |
General Comments 0
You need to be logged in to leave comments.
Login now