From: Junio C Hamano Date: Tue, 19 Sep 2017 03:52:27 +0000 (+0900) Subject: Merge branch 'jn/per-repo-object-store-fixes' into next X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/95aef30d5b4e557afb40994afdd079ea2d68eaf7?hp=-c Merge branch 'jn/per-repo-object-store-fixes' into next Step #0 of a planned & larger series to make the in-core object store per in-core repository object. * jn/per-repo-object-store-fixes: replace-objects: evaluate replacement refs without using the object store push, fetch: error out for submodule entries not pointing to commits pack: make packed_git_mru global a value instead of a pointer --- 95aef30d5b4e557afb40994afdd079ea2d68eaf7 diff --combined refs.c index e8b67ddce8,cd84ed9710..0d5fe7442a --- a/refs.c +++ b/refs.c @@@ -336,6 -336,12 +336,6 @@@ int for_each_tag_ref(each_ref_fn fn, vo return refs_for_each_tag_ref(get_main_ref_store(), fn, cb_data); } -int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return refs_for_each_tag_ref(get_submodule_ref_store(submodule), - fn, cb_data); -} - int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) { return refs_for_each_ref_in(refs, "refs/heads/", fn, cb_data); @@@ -346,6 -352,12 +346,6 @@@ int for_each_branch_ref(each_ref_fn fn return refs_for_each_branch_ref(get_main_ref_store(), fn, cb_data); } -int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return refs_for_each_branch_ref(get_submodule_ref_store(submodule), - fn, cb_data); -} - int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) { return refs_for_each_ref_in(refs, "refs/remotes/", fn, cb_data); @@@ -356,6 -368,12 +356,6 @@@ int for_each_remote_ref(each_ref_fn fn return refs_for_each_remote_ref(get_main_ref_store(), fn, cb_data); } -int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return refs_for_each_remote_ref(get_submodule_ref_store(submodule), - fn, cb_data); -} - int head_ref_namespaced(each_ref_fn fn, void *cb_data) { struct strbuf buf = STRBUF_INIT; @@@ -594,7 -612,7 +594,7 @@@ static int write_pseudoref(const char * if (fd < 0) { strbuf_addf(err, "could not open '%s' for writing: %s", filename, strerror(errno)); - return -1; + goto done; } if (old_sha1) { @@@ -609,7 -627,7 +609,7 @@@ } } - if (write_in_full(fd, buf.buf, buf.len) != buf.len) { + if (write_in_full(fd, buf.buf, buf.len) < 0) { strbuf_addf(err, "could not write to '%s'", filename); rollback_lock_file(&lock); goto done; @@@ -1248,13 -1266,19 +1248,13 @@@ int refs_rename_ref_available(struct re return ok; } -int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) { struct object_id oid; int flag; - if (submodule) { - if (resolve_gitlink_ref(submodule, "HEAD", oid.hash) == 0) - return fn("HEAD", &oid, 0, cb_data); - - return 0; - } - - if (!read_ref_full("HEAD", RESOLVE_REF_READING, oid.hash, &flag)) + if (!refs_read_ref_full(refs, "HEAD", RESOLVE_REF_READING, + oid.hash, &flag)) return fn("HEAD", &oid, flag, cb_data); return 0; @@@ -1262,7 -1286,7 +1262,7 @@@ int head_ref(each_ref_fn fn, void *cb_data) { - return head_ref_submodule(NULL, fn, cb_data); + return refs_head_ref(get_main_ref_store(), fn, cb_data); } struct ref_iterator *refs_ref_iterator_begin( @@@ -1320,6 -1344,11 +1320,6 @@@ int for_each_ref(each_ref_fn fn, void * return refs_for_each_ref(get_main_ref_store(), fn, cb_data); } -int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return refs_for_each_ref(get_submodule_ref_store(submodule), fn, cb_data); -} - int refs_for_each_ref_in(struct ref_store *refs, const char *prefix, each_ref_fn fn, void *cb_data) { @@@ -1341,15 -1370,23 +1341,15 @@@ int for_each_fullref_in(const char *pre prefix, fn, 0, flag, cb_data); } -int for_each_ref_in_submodule(const char *submodule, const char *prefix, - each_ref_fn fn, void *cb_data) -{ - return refs_for_each_ref_in(get_submodule_ref_store(submodule), - prefix, fn, cb_data); -} - -int for_each_fullref_in_submodule(const char *submodule, const char *prefix, - each_ref_fn fn, void *cb_data, - unsigned int broken) +int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix, + each_ref_fn fn, void *cb_data, + unsigned int broken) { unsigned int flag = 0; if (broken) flag = DO_FOR_EACH_INCLUDE_BROKEN; - return do_for_each_ref(get_submodule_ref_store(submodule), - prefix, fn, 0, flag, cb_data); + return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data); } int for_each_replace_ref(each_ref_fn fn, void *cb_data) @@@ -1357,7 -1394,7 +1357,7 @@@ return do_for_each_ref(get_main_ref_store(), git_replace_ref_base, fn, strlen(git_replace_ref_base), - 0, cb_data); + DO_FOR_EACH_INCLUDE_BROKEN, cb_data); } int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) @@@ -1484,10 -1521,25 +1484,10 @@@ const char *resolve_ref_unsafe(const ch int resolve_gitlink_ref(const char *submodule, const char *refname, unsigned char *sha1) { - size_t len = strlen(submodule); struct ref_store *refs; int flags; - while (len && submodule[len - 1] == '/') - len--; - - if (!len) - return -1; - - if (submodule[len]) { - /* We need to strip off one or more trailing slashes */ - char *stripped = xmemdupz(submodule, len); - - refs = get_submodule_ref_store(stripped); - free(stripped); - } else { - refs = get_submodule_ref_store(submodule); - } + refs = get_submodule_ref_store(submodule); if (!refs) return -1; @@@ -1602,32 -1654,31 +1602,32 @@@ struct ref_store *get_submodule_ref_sto { struct strbuf submodule_sb = STRBUF_INIT; struct ref_store *refs; - int ret; + char *to_free = NULL; + size_t len; - if (!submodule || !*submodule) { - /* - * FIXME: This case is ideally not allowed. But that - * can't happen until we clean up all the callers. - */ - return get_main_ref_store(); - } + if (!submodule) + return NULL; + + len = strlen(submodule); + while (len && is_dir_sep(submodule[len - 1])) + len--; + if (!len) + return NULL; + + if (submodule[len]) + /* We need to strip off one or more trailing slashes */ + submodule = to_free = xmemdupz(submodule, len); refs = lookup_ref_store_map(&submodule_ref_stores, submodule); if (refs) - return refs; + goto done; strbuf_addstr(&submodule_sb, submodule); - ret = is_nonbare_repository_dir(&submodule_sb); - strbuf_release(&submodule_sb); - if (!ret) - return NULL; + if (!is_nonbare_repository_dir(&submodule_sb)) + goto done; - ret = submodule_to_gitdir(&submodule_sb, submodule); - if (ret) { - strbuf_release(&submodule_sb); - return NULL; - } + if (submodule_to_gitdir(&submodule_sb, submodule)) + goto done; /* assume that add_submodule_odb() has been called */ refs = ref_store_init(submodule_sb.buf, @@@ -1635,10 -1686,7 +1635,10 @@@ register_ref_store_map(&submodule_ref_stores, "submodule", refs, submodule); +done: strbuf_release(&submodule_sb); + free(to_free); + return refs; } diff --combined submodule.c index 075c55f3ca,e0da55920d..b12600fc79 --- a/submodule.c +++ b/submodule.c @@@ -69,13 -69,6 +69,13 @@@ int is_staging_gitmodules_ok(const stru return 1; } +static int for_each_remote_ref_submodule(const char *submodule, + each_ref_fn fn, void *cb_data) +{ + return refs_for_each_remote_ref(get_submodule_ref_store(submodule), + fn, cb_data); +} + /* * Try to update the "path" entry in the "submodule." section of the * .gitmodules file. Return 0 only if a .gitmodules file was found, a section @@@ -774,19 -767,36 +774,36 @@@ static int append_oid_to_argv(const str return 0; } + struct has_commit_data { + int result; + const char *path; + }; + static int check_has_commit(const struct object_id *oid, void *data) { - int *has_commit = data; + struct has_commit_data *cb = data; - if (!lookup_commit_reference(oid)) - *has_commit = 0; + enum object_type type = sha1_object_info(oid->hash, NULL); - return 0; + switch (type) { + case OBJ_COMMIT: + return 0; + case OBJ_BAD: + /* + * Object is missing or invalid. If invalid, an error message + * has already been printed. + */ + cb->result = 0; + return 0; + default: + die(_("submodule entry '%s' (%s) is a %s, not a commit"), + cb->path, oid_to_hex(oid), typename(type)); + } } static int submodule_has_commits(const char *path, struct oid_array *commits) { - int has_commit = 1; + struct has_commit_data has_commit = { 1, path }; /* * Perform a cheap, but incorrect check for the existence of 'commits'. @@@ -802,7 -812,7 +819,7 @@@ oid_array_for_each_unique(commits, check_has_commit, &has_commit); - if (has_commit) { + if (has_commit.result) { /* * Even if the submodule is checked out and the commit is * present, make sure it exists in the submodule's object store @@@ -821,12 -831,12 +838,12 @@@ cp.dir = path; if (capture_command(&cp, &out, GIT_MAX_HEXSZ + 1) || out.len) - has_commit = 0; + has_commit.result = 0; strbuf_release(&out); } - return has_commit; + return has_commit.result; } static int submodule_needs_pushing(const char *path, struct oid_array *commits) @@@ -1634,8 -1644,6 +1651,8 @@@ static int find_first_merges(struct obj oid_to_hex(&a->object.oid)); init_revisions(&revs, NULL); rev_opts.submodule = path; + /* FIXME: can't handle linked worktrees in submodules yet */ + revs.single_worktree = path != NULL; setup_revisions(ARRAY_SIZE(rev_args)-1, rev_args, &revs, &rev_opts); /* save all revisions from the above list that contain b */