|
9 | 9 | from ref import ReferenceDB |
10 | 10 |
|
11 | 11 | from gitdb.util import LazyMixin |
12 | | -from gitdb.exc import InvalidDBRoot |
| 12 | +from gitdb.exc import ( |
| 13 | + InvalidDBRoot, |
| 14 | + BadObject, |
| 15 | + AmbiguousObjectName |
| 16 | + ) |
13 | 17 | import os |
14 | 18 |
|
| 19 | +from gitdb.util import hex_to_bin |
| 20 | + |
15 | 21 | __all__ = ('GitDB', ) |
16 | 22 |
|
| 23 | + |
| 24 | +def _databases_recursive(database, output): |
| 25 | + """Fill output list with database from db, in order. Deals with Loose, Packed |
| 26 | + and compound databases.""" |
| 27 | + if isinstance(database, CompoundDB): |
| 28 | + compounds = list() |
| 29 | + dbs = database.databases() |
| 30 | + output.extend(db for db in dbs if not isinstance(db, CompoundDB)) |
| 31 | + for cdb in (db for db in dbs if isinstance(db, CompoundDB)): |
| 32 | + _databases_recursive(cdb, output) |
| 33 | + else: |
| 34 | + output.append(database) |
| 35 | + # END handle database type |
| 36 | + |
| 37 | + |
| 38 | + |
17 | 39 | class GitDB(FileDBBase, ObjectDBW, CompoundDB): |
18 | 40 | """A git-style object database, which contains all objects in the 'objects' |
19 | 41 | subdirectory""" |
@@ -71,4 +93,45 @@ def ostream(self): |
71 | 93 |
|
72 | 94 | def set_ostream(self, ostream): |
73 | 95 | return self._loose_db.set_ostream(ostream) |
| 96 | + |
74 | 97 | #} END objectdbw interface |
| 98 | + |
| 99 | + #{ Interface |
| 100 | + |
| 101 | + def partial_to_complete_sha_hex(self, partial_hexsha): |
| 102 | + """ |
| 103 | + :return: 20 byte binary sha1 from the given less-than-40 byte hexsha |
| 104 | + :param partial_hexsha: hexsha with less than 40 byte |
| 105 | + :raise AmbiguousObjectName: """ |
| 106 | + databases = list() |
| 107 | + _databases_recursive(self, databases) |
| 108 | + |
| 109 | + if len(partial_hexsha) % 2 != 0: |
| 110 | + partial_binsha = hex_to_bin(partial_hexsha + "0") |
| 111 | + else: |
| 112 | + partial_binsha = hex_to_bin(partial_hexsha) |
| 113 | + # END assure successful binary conversion |
| 114 | + |
| 115 | + candidate = None |
| 116 | + for db in databases: |
| 117 | + full_bin_sha = None |
| 118 | + try: |
| 119 | + if isinstance(db, LooseObjectDB): |
| 120 | + full_bin_sha = db.partial_to_complete_sha_hex(partial_hexsha) |
| 121 | + else: |
| 122 | + full_bin_sha = db.partial_to_complete_sha(partial_binsha) |
| 123 | + # END handle database type |
| 124 | + except BadObject: |
| 125 | + continue |
| 126 | + # END ignore bad objects |
| 127 | + if full_bin_sha: |
| 128 | + if candidate and candidate != full_bin_sha: |
| 129 | + raise AmbiguousObjectName(partial_hexsha) |
| 130 | + candidate = full_bin_sha |
| 131 | + # END handle candidate |
| 132 | + # END for each db |
| 133 | + if not candidate: |
| 134 | + raise BadObject(partial_binsha) |
| 135 | + return candidate |
| 136 | + |
| 137 | + #} END interface |
0 commit comments