Merge branch 'wk/submodule-update-remote'

The beginning of 'integrate with the tip of the remote branch, not
the commit recorded in the superproject gitlink' support.

* wk/submodule-update-remote:
  submodule add: If --branch is given, record it in .gitmodules
  submodule update: add --remote for submodule's upstream changes
  submodule: add get_submodule_config helper funtion
This commit is contained in:
Junio C Hamano
2013-01-05 23:42:11 -08:00
6 changed files with 117 additions and 2 deletions

View File

@ -2007,6 +2007,12 @@ submodule.<name>.update::
URL and other values found in the `.gitmodules` file. See URL and other values found in the `.gitmodules` file. See
linkgit:git-submodule[1] and linkgit:gitmodules[5] for details. linkgit:git-submodule[1] and linkgit:gitmodules[5] for details.
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
linkgit:gitmodules[5] for details.
submodule.<name>.fetchRecurseSubmodules:: submodule.<name>.fetchRecurseSubmodules::
This option can be used to control recursive fetching of this This option can be used to control recursive fetching of this
submodule. It can be overridden by using the --[no-]recurse-submodules submodule. It can be overridden by using the --[no-]recurse-submodules

View File

@ -13,7 +13,7 @@ SYNOPSIS
[--reference <repository>] [--] <repository> [<path>] [--reference <repository>] [--] <repository> [<path>]
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
'git submodule' [--quiet] init [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...]
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] [--rebase]
[--reference <repository>] [--merge] [--recursive] [--] [<path>...] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
[commit] [--] [<path>...] [commit] [--] [<path>...]
@ -208,6 +208,8 @@ OPTIONS
-b:: -b::
--branch:: --branch::
Branch of repository to add as submodule. Branch of repository to add as submodule.
The name of the branch is recorded as `submodule.<path>.branch` in
`.gitmodules` for `update --remote`.
-f:: -f::
--force:: --force::
@ -236,6 +238,27 @@ OPTIONS
(the default). This limit only applies to modified submodules. The (the default). This limit only applies to modified submodules. The
size is always limited to 1 for added/deleted/typechanged submodules. size is always limited to 1 for added/deleted/typechanged submodules.
--remote::
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).
+
This works for any of the supported update procedures (`--checkout`,
`--rebase`, etc.). The only change is the source of the target SHA-1.
For example, `submodule update --remote --merge` will merge upstream
submodule changes into the submodules, while `submodule update
--merge` will merge superproject gitlink changes into the submodules.
+
In order to ensure a current tracking branch state, `update --remote`
fetches the submodule's remote repository before calculating the
SHA-1. If you don't want to fetch, you should use `submodule update
--remote --no-fetch`.
-N:: -N::
--no-fetch:: --no-fetch::
This option is only valid for the update command. This option is only valid for the update command.

View File

@ -49,6 +49,11 @@ submodule.<name>.update::
This config option is overridden if 'git submodule update' is given This config option is overridden if 'git submodule update' is given
the '--merge', '--rebase' or '--checkout' options. the '--merge', '--rebase' or '--checkout' options.
submodule.<name>.branch::
A remote branch name for tracking updates in the upstream submodule.
If the option is not specified, it defaults to 'master'. See the
`--remote` documentation in linkgit:git-submodule[1] for details.
submodule.<name>.fetchRecurseSubmodules:: submodule.<name>.fetchRecurseSubmodules::
This option can be used to control recursive fetching of this This option can be used to control recursive fetching of this
submodule. If this option is also present in the submodules entry in submodule. If this option is also present in the submodules entry in

View File

@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>] USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...] or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
or: $dashless [--quiet] init [--] [<path>...] or: $dashless [--quiet] init [--] [<path>...]
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...] or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
or: $dashless [--quiet] foreach [--recursive] <command> or: $dashless [--quiet] foreach [--recursive] <command>
or: $dashless [--quiet] sync [--recursive] [--] [<path>...]" or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
@ -26,6 +26,7 @@ cached=
recursive= recursive=
init= init=
files= files=
remote=
nofetch= nofetch=
update= update=
prefix= prefix=
@ -152,6 +153,32 @@ die_if_unmatched ()
fi fi
} }
#
# Print a submodule configuration setting
#
# $1 = submodule name
# $2 = option name
# $3 = default value
#
# Checks in the usual git-config places first (for overrides),
# otherwise it falls back on .gitmodules. This allows you to
# distribute project-wide defaults in .gitmodules, while still
# customizing individual repositories if necessary. If the option is
# not in .gitmodules either, print a default value.
#
get_submodule_config () {
name="$1"
option="$2"
default="$3"
value=$(git config submodule."$name"."$option")
if test -z "$value"
then
value=$(git config -f .gitmodules submodule."$name"."$option")
fi
printf '%s' "${value:-$default}"
}
# #
# Map submodule path to submodule name # Map submodule path to submodule name
# #
@ -390,6 +417,10 @@ Use -f if you really want to add it." >&2
git config -f .gitmodules submodule."$sm_name".path "$sm_path" && git config -f .gitmodules submodule."$sm_name".path "$sm_path" &&
git config -f .gitmodules submodule."$sm_name".url "$repo" && git config -f .gitmodules submodule."$sm_name".url "$repo" &&
if test -n "$branch"
then
git config -f .gitmodules submodule."$sm_name".branch "$branch"
fi &&
git add --force .gitmodules || git add --force .gitmodules ||
die "$(eval_gettext "Failed to register submodule '\$sm_path'")" die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
} }
@ -533,6 +564,9 @@ cmd_update()
-i|--init) -i|--init)
init=1 init=1
;; ;;
--remote)
remote=1
;;
-N|--no-fetch) -N|--no-fetch)
nofetch=1 nofetch=1
;; ;;
@ -593,6 +627,7 @@ cmd_update()
fi fi
name=$(module_name "$sm_path") || exit name=$(module_name "$sm_path") || exit
url=$(git config submodule."$name".url) url=$(git config submodule."$name".url)
branch=$(get_submodule_config "$name" branch master)
if ! test -z "$update" if ! test -z "$update"
then then
update_module=$update update_module=$update
@ -627,6 +662,20 @@ Maybe you want to use 'update --init'?")"
die "$(eval_gettext "Unable to find current revision in submodule path '\$sm_path'")" die "$(eval_gettext "Unable to find current revision in submodule path '\$sm_path'")"
fi fi
if test -n "$remote"
then
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'")"
fi
remote_name=$(clear_local_git_env; cd "$sm_path" && 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'")"
fi
if test "$subsha1" != "$sha1" -o -n "$force" if test "$subsha1" != "$sha1" -o -n "$force"
then then
subforce=$force subforce=$force

View File

@ -133,6 +133,7 @@ test_expect_success 'submodule add --branch' '
( (
cd addtest && cd addtest &&
git submodule add -b initial "$submodurl" submod-branch && git submodule add -b initial "$submodurl" submod-branch &&
test "initial" = "$(git config -f .gitmodules submodule.submod-branch.branch)" &&
git submodule init git submodule init
) && ) &&

View File

@ -135,6 +135,37 @@ test_expect_success 'submodule update --force forcibly checks out submodules' '
) )
' '
test_expect_success 'submodule update --remote should fetch upstream changes' '
(cd submodule &&
echo line4 >> file &&
git add file &&
test_tick &&
git commit -m "upstream line4"
) &&
(cd super &&
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 &&
echo line5 >> file &&
git add file &&
test_tick &&
git commit -m "upstream line5" &&
git checkout master
) &&
(cd super &&
git config submodule.submodule.branch test-branch &&
git submodule update --remote --force submodule &&
cd submodule &&
test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline test-branch)"
)
'
test_expect_success 'submodule update --rebase staying on master' ' test_expect_success 'submodule update --rebase staying on master' '
(cd super/submodule && (cd super/submodule &&
git checkout master git checkout master