Git fork

Merge branch 'jt/submodule-name-to-gitdir'

Code refactoring.

* jt/submodule-name-to-gitdir:
submodule: extract path to submodule gitdir func

+72 -27
+8 -2
builtin/submodule--helper.c
··· 1668 1668 * standard layout with .git/(modules/<name>)+/objects 1669 1669 */ 1670 1670 if (strip_suffix(odb->path, "/objects", &len)) { 1671 + struct repository alternate; 1671 1672 char *sm_alternate; 1672 1673 struct strbuf sb = STRBUF_INIT; 1673 1674 struct strbuf err = STRBUF_INIT; 1674 1675 strbuf_add(&sb, odb->path, len); 1676 + 1677 + repo_init(&alternate, sb.buf, NULL); 1675 1678 1676 1679 /* 1677 1680 * We need to end the new path with '/' to mark it as a dir, ··· 1679 1682 * as the last part of a missing submodule reference would 1680 1683 * be taken as a file name. 1681 1684 */ 1682 - strbuf_addf(&sb, "/modules/%s/", sas->submodule_name); 1685 + strbuf_reset(&sb); 1686 + submodule_name_to_gitdir(&sb, &alternate, sas->submodule_name); 1687 + strbuf_addch(&sb, '/'); 1688 + repo_clear(&alternate); 1683 1689 1684 1690 sm_alternate = compute_alternate_path(sb.buf, &err); 1685 1691 if (sm_alternate) { ··· 1749 1755 struct strbuf sb = STRBUF_INIT; 1750 1756 struct child_process cp = CHILD_PROCESS_INIT; 1751 1757 1752 - strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), clone_data->name); 1758 + submodule_name_to_gitdir(&sb, the_repository, clone_data->name); 1753 1759 sm_gitdir = absolute_pathdup(sb.buf); 1754 1760 strbuf_reset(&sb); 1755 1761
+1 -1
dir.c
··· 3799 3799 strbuf_reset(&sub_wt); 3800 3800 strbuf_reset(&sub_gd); 3801 3801 strbuf_addf(&sub_wt, "%s/%s", sub_worktree, sub->path); 3802 - strbuf_addf(&sub_gd, "%s/modules/%s", sub_gitdir, sub->name); 3802 + submodule_name_to_gitdir(&sub_gd, &subrepo, sub->name); 3803 3803 3804 3804 connect_work_tree_and_git_dir(sub_wt.buf, sub_gd.buf, 1); 3805 3805 }
+1 -2
repository.c
··· 213 213 * submodule would not have a worktree. 214 214 */ 215 215 strbuf_reset(&gitdir); 216 - strbuf_repo_git_path(&gitdir, superproject, 217 - "modules/%s", sub->name); 216 + submodule_name_to_gitdir(&gitdir, superproject, sub->name); 218 217 219 218 if (repo_init(subrepo, gitdir.buf, NULL)) { 220 219 ret = -1;
+55 -22
submodule.c
··· 1859 1859 1860 1860 void submodule_unset_core_worktree(const struct submodule *sub) 1861 1861 { 1862 - char *config_path = xstrfmt("%s/modules/%s/config", 1863 - get_git_dir(), sub->name); 1862 + struct strbuf config_path = STRBUF_INIT; 1864 1863 1865 - if (git_config_set_in_file_gently(config_path, "core.worktree", NULL)) 1864 + submodule_name_to_gitdir(&config_path, the_repository, sub->name); 1865 + strbuf_addstr(&config_path, "/config"); 1866 + 1867 + if (git_config_set_in_file_gently(config_path.buf, "core.worktree", NULL)) 1866 1868 warning(_("Could not unset core.worktree setting in submodule '%s'"), 1867 1869 sub->path); 1868 1870 1869 - free(config_path); 1871 + strbuf_release(&config_path); 1870 1872 } 1871 1873 1872 1874 static const char *get_super_prefix_or_empty(void) ··· 1962 1964 absorb_git_dir_into_superproject(path, 1963 1965 ABSORB_GITDIR_RECURSE_SUBMODULES); 1964 1966 } else { 1965 - char *gitdir = xstrfmt("%s/modules/%s", 1966 - get_git_dir(), sub->name); 1967 - connect_work_tree_and_git_dir(path, gitdir, 0); 1968 - free(gitdir); 1967 + struct strbuf gitdir = STRBUF_INIT; 1968 + submodule_name_to_gitdir(&gitdir, the_repository, 1969 + sub->name); 1970 + connect_work_tree_and_git_dir(path, gitdir.buf, 0); 1971 + strbuf_release(&gitdir); 1969 1972 1970 1973 /* make sure the index is clean as well */ 1971 1974 submodule_reset_index(path); 1972 1975 } 1973 1976 1974 1977 if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) { 1975 - char *gitdir = xstrfmt("%s/modules/%s", 1976 - get_git_dir(), sub->name); 1977 - connect_work_tree_and_git_dir(path, gitdir, 1); 1978 - free(gitdir); 1978 + struct strbuf gitdir = STRBUF_INIT; 1979 + submodule_name_to_gitdir(&gitdir, the_repository, 1980 + sub->name); 1981 + connect_work_tree_and_git_dir(path, gitdir.buf, 1); 1982 + strbuf_release(&gitdir); 1979 1983 } 1980 1984 } 1981 1985 ··· 2090 2094 static void relocate_single_git_dir_into_superproject(const char *path) 2091 2095 { 2092 2096 char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL; 2093 - char *new_git_dir; 2097 + struct strbuf new_gitdir = STRBUF_INIT; 2094 2098 const struct submodule *sub; 2095 2099 2096 2100 if (submodule_uses_worktrees(path)) ··· 2108 2112 if (!sub) 2109 2113 die(_("could not lookup name for submodule '%s'"), path); 2110 2114 2111 - new_git_dir = git_pathdup("modules/%s", sub->name); 2112 - if (validate_submodule_git_dir(new_git_dir, sub->name) < 0) 2115 + submodule_name_to_gitdir(&new_gitdir, the_repository, sub->name); 2116 + if (validate_submodule_git_dir(new_gitdir.buf, sub->name) < 0) 2113 2117 die(_("refusing to move '%s' into an existing git dir"), 2114 2118 real_old_git_dir); 2115 - if (safe_create_leading_directories_const(new_git_dir) < 0) 2116 - die(_("could not create directory '%s'"), new_git_dir); 2117 - real_new_git_dir = real_pathdup(new_git_dir, 1); 2118 - free(new_git_dir); 2119 + if (safe_create_leading_directories_const(new_gitdir.buf) < 0) 2120 + die(_("could not create directory '%s'"), new_gitdir.buf); 2121 + real_new_git_dir = real_pathdup(new_gitdir.buf, 1); 2119 2122 2120 2123 fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"), 2121 2124 get_super_prefix_or_empty(), path, ··· 2126 2129 free(old_git_dir); 2127 2130 free(real_old_git_dir); 2128 2131 free(real_new_git_dir); 2132 + strbuf_release(&new_gitdir); 2129 2133 } 2130 2134 2131 2135 /* ··· 2145 2149 /* Not populated? */ 2146 2150 if (!sub_git_dir) { 2147 2151 const struct submodule *sub; 2152 + struct strbuf sub_gitdir = STRBUF_INIT; 2148 2153 2149 2154 if (err_code == READ_GITFILE_ERR_STAT_FAILED) { 2150 2155 /* unpopulated as expected */ ··· 2166 2171 sub = submodule_from_path(the_repository, null_oid(), path); 2167 2172 if (!sub) 2168 2173 die(_("could not lookup name for submodule '%s'"), path); 2169 - connect_work_tree_and_git_dir(path, 2170 - git_path("modules/%s", sub->name), 0); 2174 + submodule_name_to_gitdir(&sub_gitdir, the_repository, sub->name); 2175 + connect_work_tree_and_git_dir(path, sub_gitdir.buf, 0); 2176 + strbuf_release(&sub_gitdir); 2171 2177 } else { 2172 2178 /* Is it already absorbed into the superprojects git dir? */ 2173 2179 char *real_sub_git_dir = real_pathdup(sub_git_dir, 1); ··· 2318 2324 goto cleanup; 2319 2325 } 2320 2326 strbuf_reset(buf); 2321 - strbuf_git_path(buf, "%s/%s", "modules", sub->name); 2327 + submodule_name_to_gitdir(buf, the_repository, sub->name); 2322 2328 } 2323 2329 2324 2330 cleanup: 2325 2331 return ret; 2326 2332 } 2333 + 2334 + void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r, 2335 + const char *submodule_name) 2336 + { 2337 + /* 2338 + * NEEDSWORK: The current way of mapping a submodule's name to 2339 + * its location in .git/modules/ has problems with some naming 2340 + * schemes. For example, if a submodule is named "foo" and 2341 + * another is named "foo/bar" (whether present in the same 2342 + * superproject commit or not - the problem will arise if both 2343 + * superproject commits have been checked out at any point in 2344 + * time), or if two submodule names only have different cases in 2345 + * a case-insensitive filesystem. 2346 + * 2347 + * There are several solutions, including encoding the path in 2348 + * some way, introducing a submodule.<name>.gitdir config in 2349 + * .git/config (not .gitmodules) that allows overriding what the 2350 + * gitdir of a submodule would be (and teach Git, upon noticing 2351 + * a clash, to automatically determine a non-clashing name and 2352 + * to write such a config), or introducing a 2353 + * submodule.<name>.gitdir config in .gitmodules that repo 2354 + * administrators can explicitly set. Nothing has been decided, 2355 + * so for now, just append the name at the end of the path. 2356 + */ 2357 + strbuf_repo_git_path(buf, r, "modules/"); 2358 + strbuf_addstr(buf, submodule_name); 2359 + }
+7
submodule.h
··· 133 133 int submodule_to_gitdir(struct strbuf *buf, const char *submodule); 134 134 135 135 /* 136 + * Given a submodule name, create a path to where the submodule's gitdir lives 137 + * inside of the provided repository's 'modules' directory. 138 + */ 139 + void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r, 140 + const char *submodule_name); 141 + 142 + /* 136 143 * Make sure that no submodule's git dir is nested in a sibling submodule's. 137 144 */ 138 145 int validate_submodule_git_dir(char *git_dir, const char *submodule_name);