This patch separates submodule odb sources from ordinary alternate sources. The new sources can be accessed with ODB_EXTALT (e.g. via read_sha1_file_extended). ODB_EXTALT is only added to odb_default in certain cases. Basically: - External commands do not access submodule odb by default - unpack-objects, index-pack and rev-list do not - All other builtin commands do unpack-objects, index-pack and rev-list take new objects from outside and have to make sure the repository is still in good state. They should not pay attention to submodule's odb, especially rev-list because it does connectivity check. External commands also do not have default access to submodule odb, simply because I see no reasons why the should. They don't usually play a big role in the user front, where submodule integration happens and requires looking into submodule odb. The die() in add_submodule_odb() may be too strong. There might be a use case where somebody wants to add_submodule_odb() and look some up with read_sha1_file_extended() even if odb_default does not contain ODB_EXTALT. Right now such a use case may need to work around die() by temporarily adding ODB_EXTALT to odb_default. Not nice, but as no such use case exists yet to worry about. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- cache.h | 1 + git.c | 10 +++++++--- sha1_file.c | 24 +++++++++++++++++------- submodule.c | 3 +++ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/cache.h b/cache.h index b8d8e03..bc3ccd8 100644 --- a/cache.h +++ b/cache.h @@ -759,6 +759,7 @@ int offset_1st_component(const char *path); * function cals explicitly. */ #define ODB_DEFAULT 8 +#define ODB_EXTALT 16 extern unsigned int odb_default; diff --git a/git.c b/git.c index 1ada169..49a66fa 100644 --- a/git.c +++ b/git.c @@ -242,6 +242,7 @@ static int handle_alias(int *argcp, const char ***argv) * RUN_SETUP for reading from the configuration file. */ #define NEED_WORK_TREE (1<<3) +#define NO_ODB_EXTALT (1<<4) struct cmd_struct { const char *cmd; @@ -258,6 +259,9 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) prefix = NULL; help = argc == 2 && !strcmp(argv[1], "-h"); if (!help) { + if (!(p->option & NO_ODB_EXTALT)) + odb_default |= ODB_EXTALT; + if (p->option & RUN_SETUP) prefix = setup_git_directory(); if (p->option & RUN_SETUP_GENTLY) { @@ -349,7 +353,7 @@ static void handle_internal_command(int argc, const char **argv) { "grep", cmd_grep, RUN_SETUP_GENTLY }, { "hash-object", cmd_hash_object }, { "help", cmd_help }, - { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, + { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY | NO_ODB_EXTALT }, { "init", cmd_init_db }, { "init-db", cmd_init_db }, { "log", cmd_log, RUN_SETUP }, @@ -392,7 +396,7 @@ static void handle_internal_command(int argc, const char **argv) { "repo-config", cmd_repo_config, RUN_SETUP_GENTLY }, { "rerere", cmd_rerere, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP }, - { "rev-list", cmd_rev_list, RUN_SETUP }, + { "rev-list", cmd_rev_list, RUN_SETUP | NO_ODB_EXTALT }, { "rev-parse", cmd_rev_parse }, { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE }, { "rm", cmd_rm, RUN_SETUP }, @@ -408,7 +412,7 @@ static void handle_internal_command(int argc, const char **argv) { "tag", cmd_tag, RUN_SETUP }, { "tar-tree", cmd_tar_tree }, { "unpack-file", cmd_unpack_file, RUN_SETUP }, - { "unpack-objects", cmd_unpack_objects, RUN_SETUP }, + { "unpack-objects", cmd_unpack_objects, RUN_SETUP | NO_ODB_EXTALT }, { "update-index", cmd_update_index, RUN_SETUP }, { "update-ref", cmd_update_ref, RUN_SETUP }, { "update-server-info", cmd_update_server_info, RUN_SETUP }, diff --git a/sha1_file.c b/sha1_file.c index eb682b3..53f93ab 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -37,6 +37,10 @@ static inline uintmax_t sz_fmt(size_t s) { return s; } const unsigned char null_sha1[20]; /* + * Some commands may not want to touch ODB_EXTALT at all. So + * ODB_EXTALT is only enabled later, not now, when we know which + * command is running. + * * clear_delta_base_cache() may be needed if odb_default is changed to * a narrower origin set. */ @@ -433,10 +437,12 @@ void foreach_alt_odb(alt_odb_fn fn, void *cb) return; } -static inline int match_origin(unsigned int origin, int pack_local) +static inline int match_origin(unsigned int origin, + struct alternate_object_database *alt) { - return (pack_local && (origin & ODB_LOCAL)) || - (!pack_local && (origin & ODB_ALT)); + return (!alt && (origin & ODB_LOCAL)) || + (alt && (origin & ODB_ALT) && !alt->external) || + (alt && (origin & ODB_EXTALT) && alt->external); } void prepare_alt_odb(void) @@ -464,10 +470,12 @@ static int has_loose_object_extended(const unsigned char *sha1, return 1; } - if (origin & ODB_ALT) { + if (origin & (ODB_ALT | ODB_EXTALT)) { struct alternate_object_database *alt; prepare_alt_odb(); for (alt = alt_odb_list; alt; alt = alt->next) { + if (!match_origin(origin, alt)) + continue; fill_sha1_path(alt->name, sha1); if (!access(alt->base, F_OK)) return 1; @@ -478,7 +486,7 @@ static int has_loose_object_extended(const unsigned char *sha1, int has_loose_object_nonlocal(const unsigned char *sha1) { - unsigned int origin = ODB_ALT; + unsigned int origin = ODB_ALT | ODB_EXTALT; return has_loose_object_extended(sha1, origin); } @@ -1354,7 +1362,7 @@ static int open_sha1_file(const unsigned char *sha1, unsigned int origin) (fd = git_open_noatime(name)) >= 0) return fd; - if (!(origin & ODB_ALT)) { + if (!(origin & (ODB_ALT | ODB_EXTALT))) { errno = ENOENT; return -1; } @@ -1362,6 +1370,8 @@ static int open_sha1_file(const unsigned char *sha1, unsigned int origin) prepare_alt_odb(); errno = ENOENT; for (alt = alt_odb_list; alt; alt = alt->next) { + if (!match_origin(origin, alt)) + continue; name = alt->name; fill_sha1_path(name, sha1); fd = git_open_noatime(alt->base); @@ -2336,7 +2346,7 @@ static int fill_pack_entry(const unsigned char *sha1, { off_t offset; - if (!match_origin(origin, p->pack_local)) + if (!match_origin(origin, p->alt)) return 0; if (p->num_bad_objects) { diff --git a/submodule.c b/submodule.c index 3cb63f7..1271366 100644 --- a/submodule.c +++ b/submodule.c @@ -37,6 +37,9 @@ static int add_submodule_odb(const char *path) int ret = 0; const char *git_dir; + if (!(odb_default & ODB_EXTALT)) + die("BUG: this command does not support submodule odb"); + strbuf_addf(&objects_directory, "%s/.git", path); git_dir = read_gitfile(objects_directory.buf); if (git_dir) { -- 1.8.2.83.gc99314b -- 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