The new function add_alt_odb() can be used to add alternate object databases dynamically (i.e. after parsing of objects/info/alternates). It will be used by git-archive to implement inclusion of submodules by adding submodule object databases during tree traversal. To make the function usable from call-sites which doesn't require the add_alt_odb() to succeed, it takes a 'quiet' parameter which is passed on to the underlying alt-odb-related functions. Signed-off-by: Lars Hjemli <hjemli@xxxxxxxxx> --- cache.h | 1 + sha1_file.c | 40 +++++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/cache.h b/cache.h index 8e1af26..ccfad5f 100644 --- a/cache.h +++ b/cache.h @@ -724,6 +724,7 @@ extern struct alternate_object_database { char base[FLEX_ARRAY]; /* more */ } *alt_odb_list; extern void prepare_alt_odb(void); +extern int add_alt_odb(char *path, int quiet); extern void add_to_alternates_file(const char *reference); typedef int alt_odb_fn(struct alternate_object_database *, void *); extern void foreach_alt_odb(alt_odb_fn, void*); diff --git a/sha1_file.c b/sha1_file.c index f08493f..8b5540d 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -235,7 +235,7 @@ char *sha1_pack_index_name(const unsigned char *sha1) struct alternate_object_database *alt_odb_list; static struct alternate_object_database **alt_odb_tail; -static void read_info_alternates(const char * alternates, int depth); +static void read_info_alternates(const char * alternates, int depth, int quiet); /* * Prepare alternate object database registry. @@ -252,7 +252,8 @@ static void read_info_alternates(const char * alternates, int depth); * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth) +static int link_alt_odb_entry(const char * entry, int len, + const char * relative_base, int depth, int quiet) { const char *objdir = get_object_directory(); struct alternate_object_database *ent; @@ -285,9 +286,10 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative /* Detect cases where alternate disappeared */ if (!is_directory(ent->base)) { - error("object directory %s does not exist; " - "check .git/objects/info/alternates.", - ent->base); + if (!quiet) + error("object directory %s does not exist; " + "check .git/objects/info/alternates.", + ent->base); free(ent); return -1; } @@ -312,7 +314,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative ent->next = NULL; /* recursively add alternates */ - read_info_alternates(ent->base, depth + 1); + read_info_alternates(ent->base, depth + 1, quiet); ent->base[pfxlen] = '/'; @@ -320,7 +322,8 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative } static void link_alt_odb_entries(const char *alt, const char *ep, int sep, - const char *relative_base, int depth) + const char *relative_base, int depth, + int quiet) { const char *cp, *last; @@ -343,11 +346,12 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, cp++; if (last != cp) { if (!is_absolute_path(last) && depth) { + if (!quiet) error("%s: ignoring relative alternate object store %s", relative_base, last); } else { link_alt_odb_entry(last, cp - last, - relative_base, depth); + relative_base, depth, quiet); } } while (cp < ep && *cp == sep) @@ -356,7 +360,8 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, } } -static void read_info_alternates(const char * relative_base, int depth) +static void read_info_alternates(const char * relative_base, int depth, + int quiet) { char *map; size_t mapsz; @@ -380,7 +385,8 @@ static void read_info_alternates(const char * relative_base, int depth) map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - link_alt_odb_entries(map, map + mapsz, '\n', relative_base, depth); + link_alt_odb_entries(map, map + mapsz, '\n', relative_base, depth, + quiet); munmap(map, mapsz); } @@ -394,7 +400,7 @@ void add_to_alternates_file(const char *reference) if (commit_lock_file(lock)) die("could not close alternates file"); if (alt_odb_tail) - link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0); + link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0, 0); } void foreach_alt_odb(alt_odb_fn fn, void *cb) @@ -418,9 +424,9 @@ void prepare_alt_odb(void) if (!alt) alt = ""; alt_odb_tail = &alt_odb_list; - link_alt_odb_entries(alt, alt + strlen(alt), PATH_SEP, NULL, 0); + link_alt_odb_entries(alt, alt + strlen(alt), PATH_SEP, NULL, 0, 0); - read_info_alternates(get_object_directory(), 0); + read_info_alternates(get_object_directory(), 0, 0); } static int has_loose_object_local(const unsigned char *sha1) @@ -2573,3 +2579,11 @@ int read_pack_header(int fd, struct pack_header *header) return PH_ERROR_PROTOCOL; return 0; } + +int add_alt_odb(char *path, int quiet) +{ + int err = link_alt_odb_entry(path, strlen(path), NULL, 0, quiet); + if (!err) + prepare_packed_git_one(path, 0); + return err; +} -- 1.6.1.150.g5e733b -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html