aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--object-file.c68
-rw-r--r--object-file.h15
-rw-r--r--odb.c9
-rw-r--r--streaming.c11
4 files changed, 50 insertions, 53 deletions
diff --git a/object-file.c b/object-file.c
index ccc67713fa..6d6e9a5a2a 100644
--- a/object-file.c
+++ b/object-file.c
@@ -167,25 +167,22 @@ int stream_object_signature(struct repository *r, const struct object_id *oid)
}
/*
- * Find "oid" as a loose object in the local repository or in an alternate.
+ * Find "oid" as a loose object in given source.
* Returns 0 on success, negative on failure.
*
* The "path" out-parameter will give the path of the object we found (if any).
* Note that it may point to static storage and is only valid until another
* call to stat_loose_object().
*/
-static int stat_loose_object(struct repository *r, const struct object_id *oid,
+static int stat_loose_object(struct odb_source_loose *loose,
+ const struct object_id *oid,
struct stat *st, const char **path)
{
- struct odb_source *source;
static struct strbuf buf = STRBUF_INIT;
- odb_prepare_alternates(r->objects);
- for (source = r->objects->sources; source; source = source->next) {
- *path = odb_loose_path(source, &buf, oid);
- if (!lstat(*path, st))
- return 0;
- }
+ *path = odb_loose_path(loose->source, &buf, oid);
+ if (!lstat(*path, st))
+ return 0;
return -1;
}
@@ -194,39 +191,24 @@ static int stat_loose_object(struct repository *r, const struct object_id *oid,
* Like stat_loose_object(), but actually open the object and return the
* descriptor. See the caveats on the "path" parameter above.
*/
-static int open_loose_object(struct repository *r,
+static int open_loose_object(struct odb_source_loose *loose,
const struct object_id *oid, const char **path)
{
- int fd;
- struct odb_source *source;
- int most_interesting_errno = ENOENT;
static struct strbuf buf = STRBUF_INIT;
+ int fd;
- odb_prepare_alternates(r->objects);
- for (source = r->objects->sources; source; source = source->next) {
- *path = odb_loose_path(source, &buf, oid);
- fd = git_open(*path);
- if (fd >= 0)
- return fd;
+ *path = odb_loose_path(loose->source, &buf, oid);
+ fd = git_open(*path);
+ if (fd >= 0)
+ return fd;
- if (most_interesting_errno == ENOENT)
- most_interesting_errno = errno;
- }
- errno = most_interesting_errno;
return -1;
}
-static int quick_has_loose(struct repository *r,
+static int quick_has_loose(struct odb_source_loose *loose,
const struct object_id *oid)
{
- struct odb_source *source;
-
- odb_prepare_alternates(r->objects);
- for (source = r->objects->sources; source; source = source->next) {
- if (oidtree_contains(odb_source_loose_cache(source, oid), oid))
- return 1;
- }
- return 0;
+ return !!oidtree_contains(odb_source_loose_cache(loose->source, oid), oid);
}
/*
@@ -252,12 +234,12 @@ static void *map_fd(int fd, const char *path, unsigned long *size)
return map;
}
-void *map_loose_object(struct repository *r,
- const struct object_id *oid,
- unsigned long *size)
+void *odb_source_loose_map_object(struct odb_source *source,
+ const struct object_id *oid,
+ unsigned long *size)
{
const char *p;
- int fd = open_loose_object(r, oid, &p);
+ int fd = open_loose_object(source->loose, oid, &p);
if (fd < 0)
return NULL;
@@ -407,9 +389,9 @@ int parse_loose_header(const char *hdr, struct object_info *oi)
return 0;
}
-int loose_object_info(struct repository *r,
- const struct object_id *oid,
- struct object_info *oi, int flags)
+int odb_source_loose_read_object_info(struct odb_source *source,
+ const struct object_id *oid,
+ struct object_info *oi, int flags)
{
int status = 0;
int fd;
@@ -422,7 +404,7 @@ int loose_object_info(struct repository *r,
enum object_type type_scratch;
if (oi->delta_base_oid)
- oidclr(oi->delta_base_oid, r->hash_algo);
+ oidclr(oi->delta_base_oid, source->odb->repo->hash_algo);
/*
* If we don't care about type or size, then we don't
@@ -435,15 +417,15 @@ int loose_object_info(struct repository *r,
if (!oi->typep && !oi->sizep && !oi->contentp) {
struct stat st;
if (!oi->disk_sizep && (flags & OBJECT_INFO_QUICK))
- return quick_has_loose(r, oid) ? 0 : -1;
- if (stat_loose_object(r, oid, &st, &path) < 0)
+ return quick_has_loose(source->loose, oid) ? 0 : -1;
+ if (stat_loose_object(source->loose, oid, &st, &path) < 0)
return -1;
if (oi->disk_sizep)
*oi->disk_sizep = st.st_size;
return 0;
}
- fd = open_loose_object(r, oid, &path);
+ fd = open_loose_object(source->loose, oid, &path);
if (fd < 0) {
if (errno != ENOENT)
error_errno(_("unable to open loose object %s"), oid_to_hex(oid));
diff --git a/object-file.h b/object-file.h
index f8a96a45f5..ca13d3d64e 100644
--- a/object-file.h
+++ b/object-file.h
@@ -43,6 +43,14 @@ void odb_source_loose_free(struct odb_source_loose *loose);
/* Reprepare the loose source by emptying the loose object cache. */
void odb_source_loose_reprepare(struct odb_source *source);
+int odb_source_loose_read_object_info(struct odb_source *source,
+ const struct object_id *oid,
+ struct object_info *oi, int flags);
+
+void *odb_source_loose_map_object(struct odb_source *source,
+ const struct object_id *oid,
+ unsigned long *size);
+
/*
* Populate and return the loose object cache array corresponding to the
* given object ID.
@@ -66,9 +74,6 @@ const char *odb_loose_path(struct odb_source *source,
int has_loose_object(struct odb_source *source,
const struct object_id *oid);
-void *map_loose_object(struct repository *r, const struct object_id *oid,
- unsigned long *size);
-
/*
* Iterate over the files in the loose-object parts of the object
* directory "path", triggering the following callbacks:
@@ -196,10 +201,6 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
*/
int stream_object_signature(struct repository *r, const struct object_id *oid);
-int loose_object_info(struct repository *r,
- const struct object_id *oid,
- struct object_info *oi, int flags);
-
enum finalize_object_file_flags {
FOF_SKIP_COLLISION_CHECK = 1,
};
diff --git a/odb.c b/odb.c
index d1df9609e2..4c0b4fdcd5 100644
--- a/odb.c
+++ b/odb.c
@@ -697,13 +697,18 @@ static int do_oid_object_info_extended(struct object_database *odb,
return 0;
}
+ odb_prepare_alternates(odb);
+
while (1) {
+ struct odb_source *source;
+
if (find_pack_entry(odb->repo, real, &e))
break;
/* Most likely it's a loose object. */
- if (!loose_object_info(odb->repo, real, oi, flags))
- return 0;
+ for (source = odb->sources; source; source = source->next)
+ if (!odb_source_loose_read_object_info(source, real, oi, flags))
+ return 0;
/* Not a loose object; someone else may have just packed it. */
if (!(flags & OBJECT_INFO_QUICK)) {
diff --git a/streaming.c b/streaming.c
index 4b13827668..00ad649ae3 100644
--- a/streaming.c
+++ b/streaming.c
@@ -230,12 +230,21 @@ static int open_istream_loose(struct git_istream *st, struct repository *r,
enum object_type *type)
{
struct object_info oi = OBJECT_INFO_INIT;
+ struct odb_source *source;
+
oi.sizep = &st->size;
oi.typep = type;
- st->u.loose.mapped = map_loose_object(r, oid, &st->u.loose.mapsize);
+ odb_prepare_alternates(r->objects);
+ for (source = r->objects->sources; source; source = source->next) {
+ st->u.loose.mapped = odb_source_loose_map_object(source, oid,
+ &st->u.loose.mapsize);
+ if (st->u.loose.mapped)
+ break;
+ }
if (!st->u.loose.mapped)
return -1;
+
switch (unpack_loose_header(&st->z, st->u.loose.mapped,
st->u.loose.mapsize, st->u.loose.hdr,
sizeof(st->u.loose.hdr))) {