Commits

Anonymous committed 800b256

Handle duplicate objects from different backends in git_odb_read_prefix().

Conflicts:
src/odb.c

Comments (0)

Files changed (1)

 {
 	unsigned int i;
 	int error = GIT_ENOTFOUND;
-	git_oid full_oid;
+	git_oid found_full_oid = {{0}};
 	git_rawobj raw;
 	int found = 0;
 
 			return GIT_SUCCESS;
 	}
 
-	for (i = 0; i < db->backends.length && found < 2; ++i) {
+	for (i = 0; i < db->backends.length; ++i) {
 		backend_internal *internal = git_vector_get(&db->backends, i);
 		git_odb_backend *b = internal->backend;
 
 		if (b->read != NULL) {
+			git_oid full_oid;
 			error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
-			switch (error) {
-			case GIT_SUCCESS:
-				found++;
-				break;
-			case GIT_ENOTFOUND:
-			case GIT_EPASSTHROUGH:
-				break;
-			case GIT_EAMBIGUOUSOIDPREFIX:
-				return git__rethrow(error, "Failed to read object. Ambiguous sha1 prefix");
-			default:
-				return git__rethrow(error, "Failed to read object");
-			}
+			if (error == GIT_ENOTFOUND || error == GIT_EPASSTHROUGH)
+				continue;
+
+			if (error)
+				return error;
+
+			if (found && git_oid_cmp(&full_oid, &found_full_oid))
+				return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to read object. Ambiguous sha1 prefix");
+
+			found_full_oid = full_oid;
+			found = 1;
 		}
 	}
 
-	if (found == 1) {
-		*out = git_cache_try_store(&db->cache, new_odb_object(&full_oid, &raw));
-	} else if (found > 1) {
-		return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to read object. Ambiguous sha1 prefix");
-	} else {
+	if (!found)
 		return git__throw(GIT_ENOTFOUND, "Failed to read object. Object not found");
-	}
 
+	*out = git_cache_try_store(&db->cache, new_odb_object(&found_full_oid, &raw));
 	return GIT_SUCCESS;
 }