submodule update: add submodule.<name>.remote config option wtk/submodule.name.branch-v6
authorW. Trevor King <wking@tremily.us>
Sun, 2 Dec 2012 02:28:31 +0000 (21:28 -0500)
committerW. Trevor King <wking@tremily.us>
Sun, 2 Dec 2012 02:57:14 +0000 (21:57 -0500)
Don't force the user to clone from the tracked repository
(branch.<name>.remote) or `origin`.  By setting
submodule.<name>.remote in .gitmodules or the usual git config files,
you can easily point a submodule at a different remote when using
`submodule update --remote`.

The configured remote name is also used in `submodule sync` to
determine which remote.<name>.url is updated with the submodule's
origin URL.

Signed-off-by: W. Trevor King <wking@tremily.us>
Documentation/config.txt
Documentation/git-submodule.txt
git-submodule.sh
t/t7406-submodule-update.sh

index 6f4663c38cdb778819e463ca9b73eaf170f44db5..c54b9b4f881bfde84cf8dccab3e7a7343a0513e4 100644 (file)
@@ -1999,10 +1999,11 @@ submodule.<name>.update::
        by 'git submodule init'; edit them to override the
        URL and other values found in the `.gitmodules` file.  See
 
+submodule.<name>.remote::
 submodule.<name>.branch::
-       The remote branch name for a submodule, used by `git submodule
-       update --remote`.  Set this option to override the value found in
-       the `.gitmodules` file.  See linkgit:git-submodule[1] and
+       The remote repository and branch names for a submodule, used by `git
+       submodule update --remote`.  Set these options to override the value
+       found in the `.gitmodules` file.  See linkgit:git-submodule[1] and
        linkgit:gitmodules[5] for details.
 
 submodule.<name>.fetchRecurseSubmodules::
index 988bba934066a54809d47d9dd5ec6eeb6b455748..1d8d5f176605ecc7a5fbef51231b68d4d8c80066 100644 (file)
@@ -242,11 +242,11 @@ OPTIONS
        This option is only valid for the update command.  Instead of using
        the superproject's recorded SHA-1 to update the submodule, use the
        status of the submodule's remote tracking branch.  The remote used
-       is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
-       The remote branch used defaults to `master`, but the branch name may
-       be overridden by setting the `submodule.<name>.branch` option in
-       either `.gitmodules` or `.git/config` (with `.git/config` taking
-       precedence).
+       is branch's remote (`branch.<name>.remote`, defaulting to `origin`),
+       and the remote branch used defaults to `master`, but either may be
+       overridden by setting the `submodule.<name>.remote` or
+       `submodule.<name>.branch` option in `.gitmodules` or `.git/config`
+       (with `.git/config` taking precedence).
 +
 This works for any of the supported update procedures (`--checkout`,
 `--rebase`, etc.).  The only change is the source of the target SHA-1.
index 27b02fe4c35b26b43b2198432e7e963499034807..3e39e29a1c2d09fc5a67db129c23f7add99f5a09 100755 (executable)
@@ -179,6 +179,21 @@ get_submodule_config()
        printf '%s' "${value:-$default}"
 }
 
+#
+# Print the name of a submodule's configured remote
+#
+# $1 = submodule name
+#
+get_submodule_remote()
+{
+       name="$1"
+       remote=$(get_submodule_config "$name" remote)
+       if test -z "$remote"
+       then
+               remote=$(get_default_remote)
+       fi
+       printf '%s' "${remote}"
+}
 
 #
 # Map submodule path to submodule name
@@ -605,6 +620,7 @@ cmd_update()
                fi
                name=$(module_name "$sm_path") || exit
                url=$(git config submodule."$name".url)
+               remote_name=$(get_submodule_remote "$name")
                branch=$(get_submodule_config "$name" branch master)
                if ! test -z "$update"
                then
@@ -645,10 +661,9 @@ Maybe you want to use 'update --init'?")"
                        if test -z "$nofetch"
                        then
                                # Fetch remote before determining tracking $sha1
-                               (clear_local_git_env; cd "$sm_path" && git-fetch) ||
-                               die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
+                               (clear_local_git_env; cd "$sm_path" && git-fetch "$remote_name") ||
+                               die "$(eval_gettext "Unable to fetch '\$remote_name' in submodule path '\$sm_path'")"
                        fi
-                       remote_name=$(get_default_remote)
                        sha1=$(clear_local_git_env; cd "$sm_path" &&
                                git rev-parse --verify "${remote_name}/${branch}") ||
                        die "$(eval_gettext "Unable to find current ${remote_name}/${branch} revision in submodule path '\$sm_path'")"
@@ -669,8 +684,8 @@ Maybe you want to use 'update --init'?")"
                                # is not reachable from a ref.
                                (clear_local_git_env; cd "$sm_path" &&
                                        ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
-                                        test -z "$rev") || git-fetch)) ||
-                               die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
+                                        test -z "$rev") || git-fetch "$remote_name")) ||
+                               die "$(eval_gettext "Unable to fetch '\$remote_name' in submodule path '\$sm_path'")"
                        fi
 
                        # Is this something we just cloned?
@@ -1110,7 +1125,7 @@ cmd_sync()
                        (
                                clear_local_git_env
                                cd "$sm_path"
-                               remote=$(get_default_remote)
+                               remote=$(get_submodule_remote "$name")
                                git config remote."$remote".url "$sub_origin_url"
                        )
                        fi
index a567834971df87965a00b75ad5d964b3938734bf..86c85f8d61930b844649ee866bae55a777d73adc 100755 (executable)
@@ -149,6 +149,24 @@ test_expect_success 'submodule update --remote should fetch upstream changes' '
        )
 '
 
+test_expect_success 'local config should override .gitmodules remote' '
+       (cd submodule &&
+        echo line5-master >> file &&
+        git add file &&
+        test_tick &&
+        git commit -m "upstream line5-master"
+       ) &&
+       (cd super/submodule &&
+        git remote rename origin test-remote
+       ) &&
+       (cd super &&
+        git config submodule.submodule.remote test-remote &&
+        git submodule update --remote --force submodule &&
+        cd submodule &&
+        test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline)"
+       )
+'
+
 test_expect_success 'local config should override .gitmodules branch' '
        (cd submodule &&
         git checkout -b test-branch &&