|
2 | 2 | from gitdb.util import ( |
3 | 3 | pool, |
4 | 4 | join, |
5 | | - LazyMixin |
| 5 | + LazyMixin, |
| 6 | + hex_to_bin |
6 | 7 | ) |
7 | 8 |
|
8 | | -from gitdb.exc import BadObject |
| 9 | +from gitdb.exc import ( |
| 10 | + BadObject, |
| 11 | + AmbiguousObjectName |
| 12 | + ) |
9 | 13 |
|
10 | 14 | from async import ( |
11 | 15 | ChannelThreadTask |
@@ -186,6 +190,22 @@ def update_cache(self, force=False): |
186 | 190 | # END interface |
187 | 191 |
|
188 | 192 |
|
| 193 | + |
| 194 | + |
| 195 | +def _databases_recursive(database, output): |
| 196 | + """Fill output list with database from db, in order. Deals with Loose, Packed |
| 197 | + and compound databases.""" |
| 198 | + if isinstance(database, CompoundDB): |
| 199 | + compounds = list() |
| 200 | + dbs = database.databases() |
| 201 | + output.extend(db for db in dbs if not isinstance(db, CompoundDB)) |
| 202 | + for cdb in (db for db in dbs if isinstance(db, CompoundDB)): |
| 203 | + _databases_recursive(cdb, output) |
| 204 | + else: |
| 205 | + output.append(database) |
| 206 | + # END handle database type |
| 207 | + |
| 208 | + |
189 | 209 | class CompoundDB(ObjectDBR, LazyMixin, CachingDB): |
190 | 210 | """A database which delegates calls to sub-databases. |
191 | 211 | |
@@ -258,6 +278,43 @@ def update_cache(self, force=False): |
258 | 278 | # END if is caching db |
259 | 279 | # END for each database to update |
260 | 280 | return stat |
| 281 | + |
| 282 | + def partial_to_complete_sha_hex(self, partial_hexsha): |
| 283 | + """ |
| 284 | + :return: 20 byte binary sha1 from the given less-than-40 byte hexsha |
| 285 | + :param partial_hexsha: hexsha with less than 40 byte |
| 286 | + :raise AmbiguousObjectName: """ |
| 287 | + databases = list() |
| 288 | + _databases_recursive(self, databases) |
| 289 | + |
| 290 | + if len(partial_hexsha) % 2 != 0: |
| 291 | + partial_binsha = hex_to_bin(partial_hexsha + "0") |
| 292 | + else: |
| 293 | + partial_binsha = hex_to_bin(partial_hexsha) |
| 294 | + # END assure successful binary conversion |
| 295 | + |
| 296 | + candidate = None |
| 297 | + for db in databases: |
| 298 | + full_bin_sha = None |
| 299 | + try: |
| 300 | + if hasattr(db, 'partial_to_complete_sha_hex'): |
| 301 | + full_bin_sha = db.partial_to_complete_sha_hex(partial_hexsha) |
| 302 | + else: |
| 303 | + full_bin_sha = db.partial_to_complete_sha(partial_binsha) |
| 304 | + # END handle database type |
| 305 | + except BadObject: |
| 306 | + continue |
| 307 | + # END ignore bad objects |
| 308 | + if full_bin_sha: |
| 309 | + if candidate and candidate != full_bin_sha: |
| 310 | + raise AmbiguousObjectName(partial_hexsha) |
| 311 | + candidate = full_bin_sha |
| 312 | + # END handle candidate |
| 313 | + # END for each db |
| 314 | + if not candidate: |
| 315 | + raise BadObject(partial_binsha) |
| 316 | + return candidate |
| 317 | + |
261 | 318 | #} END interface |
262 | 319 |
|
263 | 320 |
|
0 commit comments