From: Junio C Hamano Date: Tue, 8 May 2018 06:59:17 +0000 (+0900) Subject: Merge branch 'sb/submodule-move-nested' X-Git-Tag: v2.18.0-rc0~102 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c7ecb7c311d393db41f4d81a113ffc5f3b4498f;p=git Merge branch 'sb/submodule-move-nested' Moving a submodule that itself has submodule in it with "git mv" forgot to make necessary adjustment to the nested sub-submodules; now the codepath learned to recurse into the submodules. * sb/submodule-move-nested: submodule: fixup nested submodules after moving the submodule submodule-config: remove submodule_from_cache submodule-config: add repository argument to submodule_from_{name, path} submodule-config: allow submodule_free to handle arbitrary repositories grep: remove "repo" arg from non-supporting funcs submodule.h: drop declaration of connect_work_tree_and_git_dir --- 0c7ecb7c311d393db41f4d81a113ffc5f3b4498f diff --cc dir.c index 63a917be45,4f401b6a3c..be08d3d296 --- a/dir.c +++ b/dir.c @@@ -3007,11 -2986,60 +3008,60 @@@ void untracked_cache_remove_from_index( void untracked_cache_add_to_index(struct index_state *istate, const char *path) { - untracked_cache_invalidate_path(istate, path); + untracked_cache_invalidate_path(istate, path, 1); } - /* Update gitfile and core.worktree setting to connect work tree and git dir */ - void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_) + static void connect_wt_gitdir_in_nested(const char *sub_worktree, + const char *sub_gitdir) + { + int i; + struct repository subrepo; + struct strbuf sub_wt = STRBUF_INIT; + struct strbuf sub_gd = STRBUF_INIT; + + const struct submodule *sub; + + /* If the submodule has no working tree, we can ignore it. */ + if (repo_init(&subrepo, sub_gitdir, sub_worktree)) + return; + + if (repo_read_index(&subrepo) < 0) + die("index file corrupt in repo %s", subrepo.gitdir); + + for (i = 0; i < subrepo.index->cache_nr; i++) { + const struct cache_entry *ce = subrepo.index->cache[i]; + + if (!S_ISGITLINK(ce->ce_mode)) + continue; + + while (i + 1 < subrepo.index->cache_nr && + !strcmp(ce->name, subrepo.index->cache[i + 1]->name)) + /* + * Skip entries with the same name in different stages + * to make sure an entry is returned only once. + */ + i++; + + sub = submodule_from_path(&subrepo, &null_oid, ce->name); + if (!sub || !is_submodule_active(&subrepo, ce->name)) + /* .gitmodules broken or inactive sub */ + continue; + + strbuf_reset(&sub_wt); + strbuf_reset(&sub_gd); + strbuf_addf(&sub_wt, "%s/%s", sub_worktree, sub->path); + strbuf_addf(&sub_gd, "%s/modules/%s", sub_gitdir, sub->name); + + connect_work_tree_and_git_dir(sub_wt.buf, sub_gd.buf, 1); + } + strbuf_release(&sub_wt); + strbuf_release(&sub_gd); + repo_clear(&subrepo); + } + + void connect_work_tree_and_git_dir(const char *work_tree_, + const char *git_dir_, + int recurse_into_nested) { struct strbuf gitfile_sb = STRBUF_INIT; struct strbuf cfg_sb = STRBUF_INIT; diff --cc submodule.c index 9a50168b23,53c45e49d0..74d35b2577 --- a/submodule.c +++ b/submodule.c @@@ -1601,10 -1603,10 +1603,10 @@@ int submodule_move_head(const char *pat else error_code_ptr = NULL; - if (old && !is_submodule_populated_gently(path, error_code_ptr)) + if (old_head && !is_submodule_populated_gently(path, error_code_ptr)) return 0; - sub = submodule_from_path(&null_oid, path); + sub = submodule_from_path(the_repository, &null_oid, path); if (!sub) die("BUG: could not get submodule information for '%s'", path); @@@ -1630,10 -1632,10 +1632,10 @@@ submodule_reset_index(path); } - if (old && (flags & SUBMODULE_MOVE_HEAD_FORCE)) { + if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) { char *gitdir = xstrfmt("%s/modules/%s", get_git_common_dir(), sub->name); - connect_work_tree_and_git_dir(path, gitdir); + connect_work_tree_and_git_dir(path, gitdir, 1); free(gitdir); } }