Show More
@@ -713,7 +713,7 b' void dirs_module_init(PyObject *mod);' | |||||
713 | void manifest_module_init(PyObject *mod); |
|
713 | void manifest_module_init(PyObject *mod); | |
714 | void revlog_module_init(PyObject *mod); |
|
714 | void revlog_module_init(PyObject *mod); | |
715 |
|
715 | |||
716 |
static const int version = |
|
716 | static const int version = 5; | |
717 |
|
717 | |||
718 | static void module_init(PyObject *mod) |
|
718 | static void module_init(PyObject *mod) | |
719 | { |
|
719 | { |
@@ -1259,6 +1259,55 b' static int nt_partialmatch(indexObject *' | |||||
1259 | return nt_find(self, node, nodelen, 1); |
|
1259 | return nt_find(self, node, nodelen, 1); | |
1260 | } |
|
1260 | } | |
1261 |
|
1261 | |||
|
1262 | /* | |||
|
1263 | * Find the length of the shortest unique prefix of node. | |||
|
1264 | * | |||
|
1265 | * Return values: | |||
|
1266 | * | |||
|
1267 | * -3: error (exception set) | |||
|
1268 | * -2: not found (no exception set) | |||
|
1269 | * rest: length of shortest prefix | |||
|
1270 | */ | |||
|
1271 | static int nt_shortest(indexObject *self, const char *node) | |||
|
1272 | { | |||
|
1273 | int level, off; | |||
|
1274 | ||||
|
1275 | if (nt_init(self) == -1) | |||
|
1276 | return -3; | |||
|
1277 | if (nt_populate(self) == -1) | |||
|
1278 | return -3; | |||
|
1279 | ||||
|
1280 | for (level = off = 0; level < 40; level++) { | |||
|
1281 | int k, v; | |||
|
1282 | nodetree *n = &self->nt[off]; | |||
|
1283 | k = nt_level(node, level); | |||
|
1284 | v = n->children[k]; | |||
|
1285 | if (v < 0) { | |||
|
1286 | const char *n; | |||
|
1287 | v = -(v + 1); | |||
|
1288 | n = index_node(self, v); | |||
|
1289 | if (memcmp(node, n, 20) != 0) | |||
|
1290 | /* | |||
|
1291 | * Found a unique prefix, but it wasn't for the | |||
|
1292 | * requested node (i.e the requested node does | |||
|
1293 | * not exist). | |||
|
1294 | */ | |||
|
1295 | return -2; | |||
|
1296 | return level + 1; | |||
|
1297 | } | |||
|
1298 | if (v == 0) | |||
|
1299 | return -2; | |||
|
1300 | off = v; | |||
|
1301 | } | |||
|
1302 | /* | |||
|
1303 | * The node was still not unique after 40 hex digits, so this won't | |||
|
1304 | * happen. Also, if we get here, then there's a programming error in | |||
|
1305 | * this file that made us insert a node longer than 40 hex digits. | |||
|
1306 | */ | |||
|
1307 | PyErr_SetString(PyExc_Exception, "broken node tree"); | |||
|
1308 | return -3; | |||
|
1309 | } | |||
|
1310 | ||||
1262 | static PyObject *index_partialmatch(indexObject *self, PyObject *args) |
|
1311 | static PyObject *index_partialmatch(indexObject *self, PyObject *args) | |
1263 | { |
|
1312 | { | |
1264 | const char *fullnode; |
|
1313 | const char *fullnode; | |
@@ -1307,6 +1356,29 b' static PyObject *index_partialmatch(inde' | |||||
1307 | return PyBytes_FromStringAndSize(fullnode, 20); |
|
1356 | return PyBytes_FromStringAndSize(fullnode, 20); | |
1308 | } |
|
1357 | } | |
1309 |
|
1358 | |||
|
1359 | static PyObject *index_shortest(indexObject *self, PyObject *args) | |||
|
1360 | { | |||
|
1361 | Py_ssize_t nodelen; | |||
|
1362 | PyObject *val; | |||
|
1363 | char *node; | |||
|
1364 | int length; | |||
|
1365 | ||||
|
1366 | if (!PyArg_ParseTuple(args, "O", &val)) | |||
|
1367 | return NULL; | |||
|
1368 | if (node_check(val, &node, &nodelen) == -1) | |||
|
1369 | return NULL; | |||
|
1370 | ||||
|
1371 | self->ntlookups++; | |||
|
1372 | length = nt_shortest(self, node); | |||
|
1373 | if (length == -3) | |||
|
1374 | return NULL; | |||
|
1375 | if (length == -2) { | |||
|
1376 | raise_revlog_error(); | |||
|
1377 | return NULL; | |||
|
1378 | } | |||
|
1379 | return PyInt_FromLong(length); | |||
|
1380 | } | |||
|
1381 | ||||
1310 | static PyObject *index_m_get(indexObject *self, PyObject *args) |
|
1382 | static PyObject *index_m_get(indexObject *self, PyObject *args) | |
1311 | { |
|
1383 | { | |
1312 | Py_ssize_t nodelen; |
|
1384 | Py_ssize_t nodelen; | |
@@ -1995,6 +2067,8 b' static PyMethodDef index_methods[] = {' | |||||
1995 | "insert an index entry"}, |
|
2067 | "insert an index entry"}, | |
1996 | {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS, |
|
2068 | {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS, | |
1997 | "match a potentially ambiguous node ID"}, |
|
2069 | "match a potentially ambiguous node ID"}, | |
|
2070 | {"shortest", (PyCFunction)index_shortest, METH_VARARGS, | |||
|
2071 | "find length of shortest hex nodeid of a binary ID"}, | |||
1998 | {"stats", (PyCFunction)index_stats, METH_NOARGS, |
|
2072 | {"stats", (PyCFunction)index_stats, METH_NOARGS, | |
1999 | "stats for the index"}, |
|
2073 | "stats for the index"}, | |
2000 | {NULL} /* Sentinel */ |
|
2074 | {NULL} /* Sentinel */ |
@@ -69,7 +69,7 b' def _importfrom(pkgname, modname):' | |||||
69 | (r'cext', r'bdiff'): 3, |
|
69 | (r'cext', r'bdiff'): 3, | |
70 | (r'cext', r'mpatch'): 1, |
|
70 | (r'cext', r'mpatch'): 1, | |
71 | (r'cext', r'osutil'): 4, |
|
71 | (r'cext', r'osutil'): 4, | |
72 |
(r'cext', r'parsers'): |
|
72 | (r'cext', r'parsers'): 5, | |
73 | } |
|
73 | } | |
74 |
|
74 | |||
75 | # map import request to other package or module |
|
75 | # map import request to other package or module |
@@ -1526,7 +1526,33 b' class revlog(object):' | |||||
1526 | raise LookupError(node, self.indexfile, _('no node')) |
|
1526 | raise LookupError(node, self.indexfile, _('no node')) | |
1527 | return not isrev(prefix) |
|
1527 | return not isrev(prefix) | |
1528 |
|
1528 | |||
|
1529 | def maybewdir(prefix): | |||
|
1530 | return all(c == 'f' for c in prefix) | |||
|
1531 | ||||
1529 | hexnode = hex(node) |
|
1532 | hexnode = hex(node) | |
|
1533 | ||||
|
1534 | def disambiguate(hexnode, minlength): | |||
|
1535 | for length in range(minlength, 41): | |||
|
1536 | prefix = hexnode[:length] | |||
|
1537 | if not isrev(prefix) and not maybewdir(prefix): | |||
|
1538 | return prefix | |||
|
1539 | ||||
|
1540 | if not getattr(self, 'filteredrevs', None): | |||
|
1541 | try: | |||
|
1542 | length = max(self.index.shortest(node), minlength) | |||
|
1543 | return disambiguate(hexnode, length) | |||
|
1544 | except RevlogError: | |||
|
1545 | if node == wdirid: | |||
|
1546 | for length in range(minlength, 41): | |||
|
1547 | prefix = hexnode[:length] | |||
|
1548 | if isvalid(prefix): | |||
|
1549 | return prefix | |||
|
1550 | else: | |||
|
1551 | raise LookupError(node, self.indexfile, _('no node')) | |||
|
1552 | except AttributeError: | |||
|
1553 | # Fall through to pure code | |||
|
1554 | pass | |||
|
1555 | ||||
1530 | shortest = hexnode |
|
1556 | shortest = hexnode | |
1531 | startlength = max(6, minlength) |
|
1557 | startlength = max(6, minlength) | |
1532 | length = startlength |
|
1558 | length = startlength |
General Comments 0
You need to be logged in to leave comments.
Login now