From: "W. Trevor King" <wking@xxxxxxxxxx> There are three branches that submodule folks usually care about: 1. The linked $sha1 in the superproject (set explicitly for every superproject commit, and thus for every superproject branch). 2. The remote-tracking submodule.<name>.branch that tracks a branch in upstream submodule.<name>.url repository. 3. The submodule's locally checked out branch, which we currently let the developer setup by hand, which is integrated with one of the other two branches by non-checkout update modes. Git is currently a bit weak on conveniently handling branch #3. "Just use what the developer has setup" works well for many basic workflows, but falls short for: * Cloning-updates, where we currently always setup a detached HEAD. This is easy to fix if you accept submodule.<name>.branch or the branch pointed to by the cloned repository's HEAD as a guess, but this conflates branch #2 and branch #3, which may confuse users. * Workflows where the preferred #3 branch depends on the superproject branch. For example, if the remote subproject has only a master branch, but the local superproject needs to develop several submodule feature branches simultaneously, you can have a situation like this: Superproject branch Submodule branch Subproject branch =================== ================ ================= master master master feature-1 feature-1 master feature-2 feature-2 master feature-3 feature-2 master In order to checkout the appropriate submodule branch for a given superproject branch, we need a way to specify the preferred submodule branch for a given superproject branch. This commit adds two helper functions: * get_current_branch, to determine which superproject branch you're on, and * get_local_branch, to determine the preferred submodule branch for that superproject branch. The lookup chain for the local-branch is: 1. superproject.<superproject-branch>.local-branch in the submodule's config (superproject/.git/modules/<submodule-name>/config). This is where the developer can store local per-superproject-branch overrides (e.g. if they wanted to use submodule branch feature-1 with superproject branch feature-3). 2. submodule.<submodule-name>.local-branch in the superproject's config. This is where the developer can store local cross-superproject-branch overrides (e.g. if they wanted to use submodule branch master for any superproject branch that didn't have a per-superproject-branch override). 3. submodule.<submodule-name>.local-branch in the superproject's .gitmodules file. Because the gitmodules file is stored in the superproject's versioned tree, it is automatically superproject-branch-specific. For example: $ git cat-file -p feature-1:.gitmodules ... [submodule "submod"] ... local-branch = feature-1 $ git cat-file -p feature-3:.gitmodules ... [submodule "submod"] ... local-branch = feature-2 this is where the project-wide defaults are setup and shared between developers. 4. The default local-branch is 'master'. The new get_local_branch function handles the first step in this chain. The next two steps are already covered by the existing get_submodule_config. --- git-submodule.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/git-submodule.sh b/git-submodule.sh index 2677f2e..56fc3f1 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -220,6 +220,39 @@ get_submodule_config () { printf '%s' "${value:-$default}" } +# +# Print a submodule's configured local branch name +# +# $1 = superproject branch +# $2 = default (from the superproject's .gitmodules) +# +# To be called from the submodule root directory. +# +get_local_branch () +{ + superproject_branch="$1" + default="${2:-master}" + if test -z "${superproject_branch}" + then + value="" + else + value=$(git config superproject."$superproject_branch".local-branch) + fi + printf '%s' "${value:-$default}" +} + +# +# Print the currently checked out branch of the current repository +# +# $1 = default +# +get_current_branch () +{ + default="$1" + branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || + branch="" + printf '%s' "${branch:-$default}" +} # # Map submodule path to submodule name -- 1.8.5.2.237.g01c62c6 -- 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