From 19a31f9c1a6b18abd8a7f20d616516afca36a6a3 Mon Sep 17 00:00:00 2001 From: Mark Levedahl Date: Sun, 10 Aug 2008 19:10:04 -0400 Subject: git-submodule - Add 'foreach' subcommand submodule foreach will execute the list of commands in each currently checked out submodule directory. The list of commands is arbitrary as long as it is acceptable to sh. The variables '$path' and '$sha1' are availble to the command-list, defining the submodule path relative to the superproject and the submodules's commitID as recorded in the superproject (this may be different than HEAD in the submodule). This utility is inspired by a number of threads on the mailing list looking for ways to better integrate submodules in a tree and work with them as a unit. This could include fetching a new branch in each from a given source, or possibly checking out a given named branch in each. Currently, there is no consensus as to what additional commands should be implemented in the porcelain, requiring all users whose needs exceed that of git-submodule to do their own scripting. The foreach command is intended to support such scripting, and in particular does no error checking and produces no output, thus allowing end users complete control over any information printed out and over what constitutes an error. The processing does terminate if the command-list returns an error, but processing can easily be forced for all submodules be terminating the list with ';true'. Signed-off-by: Mark Levedahl Signed-off-by: Junio C Hamano --- git-submodule.sh | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index b40f876a2c..2d57d60458 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -6,7 +6,7 @@ USAGE="[--quiet] [--cached] \ [add [-b branch] ]|[status|init|update [-i|--init]|summary [-n|--summary-limit ] []] \ -[--] [...]" +[--] [...]|[foreach ]" OPTIONS_SPEC= . git-sh-setup require_work_tree @@ -198,6 +198,26 @@ cmd_add() die "Failed to register submodule '$path'" } +# +# Execute an arbitrary command sequence in each checked out +# submodule +# +# $@ = command to execute +# +cmd_foreach() +{ + git ls-files --stage | grep '^160000 ' | + while read mode sha1 stage path + do + if test -e "$path"/.git + then + say "Entering '$path'" + (cd "$path" && eval "$@") || + die "Stopping at '$path'; script returned non-zero status." + fi + done +} + # # Register submodules in .git/config # @@ -583,7 +603,7 @@ cmd_status() while test $# != 0 && test -z "$command" do case "$1" in - add | init | update | status | summary) + add | foreach | init | update | status | summary) command=$1 ;; -q|--quiet) -- cgit v1.3 From 7c695619868d0b867c87b0bb83303e058e010ac5 Mon Sep 17 00:00:00 2001 From: Mark Levedahl Date: Tue, 19 Aug 2008 22:18:23 -0400 Subject: git-submodule.sh - Remove trailing / from URL if found git clone does not complain if a trailing '/' is included in the origin URL, but doing so causes resolution of a submodule's URL relative to the superproject to fail. Regardless of whether git is changed to remove the trailing / before recording the URL, we should avoid this issue in submodule as existing repositories can have this problem. Signed-off-by: Mark Levedahl Signed-off-by: Junio C Hamano --- git-submodule.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index b40f876a2c..e4c31fb7db 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -35,7 +35,7 @@ resolve_relative_url () remote="${remote:-origin}" remoteurl=$(git config "remote.$remote.url") || die "remote ($remote) does not have a url defined in .git/config" - url="$1" + url="${1%/}" while test -n "$url" do case "$url" in -- cgit v1.3 From 99b120af7081ea9eb03a5f2a605d2bab771cf634 Mon Sep 17 00:00:00 2001 From: Mark Levedahl Date: Thu, 21 Aug 2008 19:54:01 -0400 Subject: git-submodule.sh - Remove trailing / from URL if found git clone does not complain if a trailing '/' is included in the origin URL, but doing so causes resolution of a submodule's URL relative to the superproject to fail. Trailing /'s are likely when cloning locally using tab-completion, so the slash may appear in either superproject or submodule URL. So, ignore the trailing slash if it already exists in the superproject's URL, and don't record one for the submodule (which could itself have submodules...). The problem I'm trying to fix is that a number of folks have superprojects checked out where the recorded origin URL has a trailing /, and a submodule has its origin in a directory sitting right next to the superproject on the server. Thus, we have: superproject url = server:/public/super submodoule url = server:/public/sub1 However, in the checked out superproject's .git/config [remote "origin"] url = server:/public/super/ and for similar reasons, the submodule has its URL recorded in .gitmodules as [submodule "sub"] path = submodule1 url = ../sub1/ resolve_relative_url gets the submodule's recorded url as $1, which the caller retrieved from .gitmodules, and retrieves the superprojects origin from .git/config. So in this case resolve_relative_url has that: url = ../sub1/ remoteurl = server:/public/super/ So, without any patch, resolve_relative_url computes the submodule's URL as: server:/public/super/sub1/ rather than server:/public/sub1 In summary, it is essential that resolve_relative_url strip the trailing / from the superproject's url before starting, and beneficial if it assures that the result does not contain a trailing / as the submodule may itself also be a superproject. Signed-off-by: Mark Levedahl Signed-off-by: Junio C Hamano --- git-submodule.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index e4c31fb7db..46d75aba31 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -35,7 +35,8 @@ resolve_relative_url () remote="${remote:-origin}" remoteurl=$(git config "remote.$remote.url") || die "remote ($remote) does not have a url defined in .git/config" - url="${1%/}" + url="$1" + remoteurl=${remoteurl%/} while test -n "$url" do case "$url" in @@ -50,7 +51,7 @@ resolve_relative_url () break;; esac done - echo "$remoteurl/$url" + echo "$remoteurl/${url%/}" } # -- cgit v1.3 From a7b3269c4b9acde052d75b6dc54c8f869b77eb44 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Fri, 22 Aug 2008 00:30:50 -0700 Subject: git-submodule: replace duplicated code with a module_list function Several call sites in git-submodule.sh used the same idiom for getting submodule information: git ls-files --stage -- "$@" | grep '^160000 ' This patch removes this duplication by introducing a module_list function. Signed-off-by: David Aguilar Signed-off-by: Junio C Hamano --- git-submodule.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 2d57d60458..2a3a197d10 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -53,6 +53,15 @@ resolve_relative_url () echo "$remoteurl/$url" } +# +# Get submodule info for registered submodules +# $@ = path to limit submodule list +# +module_list() +{ + git ls-files --stage -- "$@" | grep '^160000 ' +} + # # Map submodule path to submodule name # @@ -206,7 +215,7 @@ cmd_add() # cmd_foreach() { - git ls-files --stage | grep '^160000 ' | + module_list | while read mode sha1 stage path do if test -e "$path"/.git @@ -246,7 +255,7 @@ cmd_init() shift done - git ls-files --stage -- "$@" | grep '^160000 ' | + module_list "$@" | while read mode sha1 stage path do # Skip already registered paths @@ -304,7 +313,7 @@ cmd_update() esac done - git ls-files --stage -- "$@" | grep '^160000 ' | + module_list "$@" | while read mode sha1 stage path do name=$(module_name "$path") || exit @@ -569,7 +578,7 @@ cmd_status() shift done - git ls-files --stage -- "$@" | grep '^160000 ' | + module_list "$@" | while read mode sha1 stage path do name=$(module_name "$path") || exit -- cgit v1.3 From 98fcf840af443a0a93b9a6cd1fada5af826383f3 Mon Sep 17 00:00:00 2001 From: Mark Levedahl Date: Sun, 24 Aug 2008 14:46:10 -0400 Subject: git-submodule - Use "get_default_remote" from git-parse-remote Resolve_relative_url was using its own code for this function, but this is duplication with the best result that this continues to work. Replace with the common function provided by git-parse-remote. Signed-off-by: Mark Levedahl Signed-off-by: Junio C Hamano --- git-submodule.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 2a3a197d10..59fe7b335c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -9,6 +9,7 @@ USAGE="[--quiet] [--cached] \ [--] [...]|[foreach ]" OPTIONS_SPEC= . git-sh-setup +. git-parse-remote require_work_tree command= @@ -30,9 +31,7 @@ say() # Resolve relative url by appending to parent's url resolve_relative_url () { - branch="$(git symbolic-ref HEAD 2>/dev/null)" - remote="$(git config branch.${branch#refs/heads/}.remote)" - remote="${remote:-origin}" + remote=$(get_default_remote) remoteurl=$(git config "remote.$remote.url") || die "remote ($remote) does not have a url defined in .git/config" url="$1" -- cgit v1.3 From 2327f61ecc4e9fbb6dd9fffdec0b043aeaca908f Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sun, 24 Aug 2008 12:43:37 -0700 Subject: git-submodule: add "sync" command When a submodule's URL changes upstream, existing submodules will be out of sync since their remote."$origin".url will still be set to the old value. This adds a "git submodule sync" command that reads submodules' URLs from .gitmodules and updates them accordingly. Signed-off-by: David Aguilar Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 9 ++++++++ git-submodule.sh | 48 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index abbd5b72de..babaa9bc46 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -15,6 +15,7 @@ SYNOPSIS 'git submodule' [--quiet] update [--init] [--] [...] 'git submodule' [--quiet] summary [--summary-limit ] [commit] [--] [...] 'git submodule' [--quiet] foreach +'git submodule' [--quiet] sync [--] [...] DESCRIPTION @@ -139,6 +140,14 @@ foreach:: As an example, "git submodule foreach 'echo $path `git rev-parse HEAD`' will show the path and currently checked out commit for each submodule. +sync:: + Synchronizes submodules' remote URL configuration setting + to the value specified in .gitmodules. This is useful when + submodule URLs change upstream and you need to update your local + repositories accordingly. ++ +"git submodule sync" synchronizes all submodules while +"git submodule sync -- A" synchronizes submodule "A" only. OPTIONS ------- diff --git a/git-submodule.sh b/git-submodule.sh index 59fe7b335c..4a95035d85 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -6,7 +6,7 @@ USAGE="[--quiet] [--cached] \ [add [-b branch] ]|[status|init|update [-i|--init]|summary [-n|--summary-limit ] []] \ -[--] [...]|[foreach ]" +[--] [...]|[foreach ]|[sync [--] [...]]" OPTIONS_SPEC= . git-sh-setup . git-parse-remote @@ -601,6 +601,50 @@ cmd_status() fi done } +# +# Sync remote urls for submodules +# This makes the value for remote.$remote.url match the value +# specified in .gitmodules. +# +cmd_sync() +{ + while test $# -ne 0 + do + case "$1" in + -q|--quiet) + quiet=1 + shift + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac + done + cd_to_toplevel + module_list "$@" | + while read mode sha1 stage path + do + name=$(module_name "$path") + url=$(git config -f .gitmodules --get submodule."$name".url) + if test -e "$path"/.git + then + ( + unset GIT_DIR + cd "$path" + remote=$(get_default_remote) + say "Synchronizing submodule url for '$name'" + git config remote."$remote".url "$url" + ) + fi + done +} # This loop parses the command line arguments to find the # subcommand name to dispatch. Parsing of the subcommand specific @@ -611,7 +655,7 @@ cmd_status() while test $# != 0 && test -z "$command" do case "$1" in - add | foreach | init | update | status | summary) + add | foreach | init | update | status | summary | sync) command=$1 ;; -q|--quiet) -- cgit v1.3 From baede9f803ff7becab815481b004bc983d0422c7 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Mon, 22 Sep 2008 18:08:31 +0200 Subject: Fix submodule sync with relative submodule URLs Signed-off-by: Johan Herland Signed-off-by: Shawn O. Pearce --- git-submodule.sh | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 1c39b593a6..92be0feb58 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -634,6 +634,14 @@ cmd_sync() do name=$(module_name "$path") url=$(git config -f .gitmodules --get submodule."$name".url) + + # Possibly a url relative to parent + case "$url" in + ./*|../*) + url=$(resolve_relative_url "$url") || exit + ;; + esac + if test -e "$path"/.git then ( -- cgit v1.3 From b9b378a001d35a64a30a652a45f8084ee2be6cdf Mon Sep 17 00:00:00 2001 From: Ping Yin Date: Fri, 26 Sep 2008 23:33:23 +0800 Subject: git-submodule: Fix "Unable to checkout" for the initial 'update' Since commit 55218("checkout: do not lose staged removal"), in cmd_add/cmd_update, "git checkout " following "git clone -n" may fail if is different from HEAD. So Use "git checkout -f " to fix this. Signed-off-by: Ping Yin Signed-off-by: Shawn O. Pearce --- git-submodule.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index b40f876a2c..5888735e4f 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -185,7 +185,7 @@ cmd_add() else module_clone "$path" "$realrepo" || exit - (unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) || + (unset GIT_DIR; cd "$path" && git checkout -f -q ${branch:+-b "$branch" "origin/$branch"}) || die "Unable to checkout submodule '$path'" fi @@ -311,8 +311,13 @@ cmd_update() if test "$subsha1" != "$sha1" then + force= + if test -z "$subsha1" + then + force="-f" + fi (unset GIT_DIR; cd "$path" && git-fetch && - git-checkout -q "$sha1") || + git-checkout $force -q "$sha1") || die "Unable to checkout '$sha1' in submodule path '$path'" say "Submodule path '$path': checked out '$sha1'" -- cgit v1.3 From 759ad19e772a79a2a5ae6b7377d57eb21d29e6a0 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 22 Oct 2008 15:22:53 -0400 Subject: submodule: fix some non-portable grep invocations Not all greps support "-e", but in this case we can easily convert it to a single extended regex. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-submodule.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 65178ae8e3..b63e5c3087 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -424,7 +424,7 @@ cmd_summary() { cd_to_toplevel # Get modified modules cared by user modules=$(git diff-index $cached --raw $head -- "$@" | - grep -e '^:160000' -e '^:[0-7]* 160000' | + egrep '^:([0-7]* )?160000' | while read mod_src mod_dst sha1_src sha1_dst status name do # Always show modules deleted or type-changed (blob<->module) @@ -438,7 +438,7 @@ cmd_summary() { test -z "$modules" && return git diff-index $cached --raw $head -- $modules | - grep -e '^:160000' -e '^:[0-7]* 160000' | + egrep '^:([0-7]* )?160000' | cut -c2- | while read mod_src mod_dst sha1_src sha1_dst status name do -- cgit v1.3 From 989206f535dcd0f43356ad38e1d54cb833d96fc2 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 11 Nov 2008 22:09:16 +0100 Subject: git-submodule: Avoid printing a spurious message. Fix 'git submodule update' to avoid printing a spurious "Maybe you want to use 'update --init'?" once for every uninitialized submodule it encounters. Signed-off-by: Alexandre Julliard Signed-off-by: Junio C Hamano --- git-submodule.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 5888735e4f..97e4d9a1ef 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -294,7 +294,7 @@ cmd_update() # Only mention uninitialized submodules when its # path have been specified test "$#" != "0" && - say "Submodule path '$path' not initialized" + say "Submodule path '$path' not initialized" && say "Maybe you want to use 'update --init'?" continue fi -- cgit v1.3 From 30353a40f7ca2f09e61013609f4847461b4544b7 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 3 Dec 2008 14:26:52 +0100 Subject: submodule: use git rev-parse -q Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-submodule.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 220d94ec0c..2f47e065fe 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -413,7 +413,7 @@ cmd_summary() { test $summary_limit = 0 && return - if rev=$(git rev-parse --verify "$1^0" 2>/dev/null) + if rev=$(git rev-parse -q --verify "$1^0") then head=$rev shift @@ -464,11 +464,11 @@ cmd_summary() { missing_dst= test $mod_src = 160000 && - ! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_src^0 >/dev/null 2>&1 && + ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_src^0 >/dev/null && missing_src=t test $mod_dst = 160000 && - ! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_dst^0 >/dev/null 2>&1 && + ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_dst^0 >/dev/null && missing_dst=t total_commits= -- cgit v1.3 From 31ca3ac30fe3c2583881a74ef346911c8fba478f Mon Sep 17 00:00:00 2001 From: Fabian Franz Date: Thu, 5 Feb 2009 20:18:32 -0200 Subject: submodule: add --no-fetch parameter to update command git submodule update --no-fetch makes it possible to use git submodule update in complete offline mode by not fetching new revisions. This does make sense in the following setup: * There is an unstable and a stable branch in the super/master repository. * The submodules might be at different revisions in the branches. * You are at some place without internet connection ;) With this patch it is now possible to change branches and update the submodules to be at the recorded revision without online access. Another advantage is that with -N the update operation is faster, because fetch is checking for new updates even if there was no fetch/pull on the super/master repository since the last update. Signed-off-by: Fabian Franz Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 7 ++++++- git-submodule.sh | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 2f207fbbda..3b8df44673 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -12,7 +12,7 @@ SYNOPSIS 'git submodule' [--quiet] add [-b branch] [--] 'git submodule' [--quiet] status [--cached] [--] [...] 'git submodule' [--quiet] init [--] [...] -'git submodule' [--quiet] update [--init] [--] [...] +'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--] [...] 'git submodule' [--quiet] summary [--summary-limit ] [commit] [--] [...] 'git submodule' [--quiet] foreach 'git submodule' [--quiet] sync [--] [...] @@ -172,6 +172,11 @@ OPTIONS (the default). This limit only applies to modified submodules. The size is always limited to 1 for added/deleted/typechanged submodules. +-N:: +--no-fetch:: + This option is only valid for the update command. + Don't fetch new objects from the remote site. + ...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths. diff --git a/git-submodule.sh b/git-submodule.sh index 2f47e065fe..af8d10ca83 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -5,7 +5,7 @@ # Copyright (c) 2007 Lars Hjemli USAGE="[--quiet] [--cached] \ -[add [-b branch] ]|[status|init|update [-i|--init]|summary [-n|--summary-limit ] []] \ +[add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit ] []] \ [--] [...]|[foreach ]|[sync [--] [...]]" OPTIONS_SPEC= . git-sh-setup @@ -16,6 +16,7 @@ command= branch= quiet= cached= +nofetch= # # print stuff on stdout unless -q was specified @@ -300,6 +301,10 @@ cmd_update() shift cmd_init "$@" || return ;; + -N|--no-fetch) + shift + nofetch=1 + ;; --) shift break @@ -345,8 +350,16 @@ cmd_update() then force="-f" fi - (unset GIT_DIR; cd "$path" && git-fetch && - git-checkout $force -q "$sha1") || + + if test -z "$nofetch" + then + (unset GIT_DIR; cd "$path" && + git-fetch) || + die "Unable to fetch in submodule path '$path'" + fi + + (unset GIT_DIR; cd "$path" && + git-checkout $force -q "$sha1") || die "Unable to checkout '$sha1' in submodule path '$path'" say "Submodule path '$path': checked out '$sha1'" -- cgit v1.3 From 496917b721adae11e596cd44b13cb8a49c388de7 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 7 Feb 2009 14:43:15 +0100 Subject: submodule: warn about non-submodules Earlier, when you called git submodule some/bogus/path Git would silently ignore the path, without warning the user about the likely mistake. Now it does. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-submodule.sh | 2 +- t/t7400-submodule-basic.sh | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 2f47e065fe..6cc2d334c0 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -59,7 +59,7 @@ resolve_relative_url () # module_list() { - git ls-files --stage -- "$@" | grep '^160000 ' + git ls-files --error-unmatch --stage -- "$@" | grep '^160000 ' } # diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index a74f24c0db..b8cb2df667 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -240,4 +240,11 @@ test_expect_success 'ls-files gracefully handles trailing slash' ' ' +test_expect_success 'submodule warns' ' + + git submodule no-such-submodule 2> output.err && + grep "^error: .*no-such-submodule" output.err + +' + test_done -- cgit v1.3 From db75ada559dd4de99fedd1fc4f62a9273f032dd3 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Tue, 3 Mar 2009 16:08:21 +0100 Subject: git submodule: Fix adding of submodules at paths with ./, .. and // Make 'git submodule add' normalize the submodule path in the same way as 'git ls-files' does, so that 'git submodule init' looks up the information in .gitmodules with the same key under which 'git submodule add' stores it. This fixes 4 known breakages. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- git-submodule.sh | 15 ++++++++++++--- t/t7400-submodule-basic.sh | 8 ++++---- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 2f47e065fe..68d6afd15c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -166,9 +166,18 @@ cmd_add() ;; esac - # strip trailing slashes from path - path=$(echo "$path" | sed -e 's|/*$||') - + # normalize path: + # multiple //; leading ./; /./; /../; trailing / + path=$(printf '%s/\n' "$path" | + sed -e ' + s|//*|/|g + s|^\(\./\)*|| + s|/\./|/|g + :start + s|\([^/]*\)/\.\./|| + tstart + s|/*$|| + ') git ls-files --error-unmatch "$path" > /dev/null 2>&1 && die "'$path' already exists in the index" diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 132d0b9963..21c19a28cf 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -64,7 +64,7 @@ test_expect_success 'submodule add' ' ) ' -test_expect_failure 'submodule add with ./ in path' ' +test_expect_success 'submodule add with ./ in path' ' ( cd addtest && git submodule add "$submodurl" ././dotsubmod/./frotz/./ && @@ -72,7 +72,7 @@ test_expect_failure 'submodule add with ./ in path' ' ) ' -test_expect_failure 'submodule add with // in path' ' +test_expect_success 'submodule add with // in path' ' ( cd addtest && git submodule add "$submodurl" slashslashsubmod///frotz// && @@ -80,7 +80,7 @@ test_expect_failure 'submodule add with // in path' ' ) ' -test_expect_failure 'submodule add with /.. in path' ' +test_expect_success 'submodule add with /.. in path' ' ( cd addtest && git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. && @@ -88,7 +88,7 @@ test_expect_failure 'submodule add with /.. in path' ' ) ' -test_expect_failure 'submodule add with ./, /.. and // in path' ' +test_expect_success 'submodule add with ./, /.. and // in path' ' ( cd addtest && git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. && -- cgit v1.3 From 835a3eea3e18695e29b1d4c3adca37d1caaa16ef Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Tue, 31 Mar 2009 17:50:12 +0200 Subject: git submodule: fix usage line Actually, you have to set the -b option after the add command. Signed-off-by: Julien Danjou Signed-off-by: Junio C Hamano --- git-submodule.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 0a27232b90..7c2e060ae7 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -5,7 +5,7 @@ # Copyright (c) 2007 Lars Hjemli USAGE="[--quiet] [--cached] \ -[add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit ] []] \ +[add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit ] []] \ [--] [...]|[foreach ]|[sync [--] [...]]" OPTIONS_SPEC= . git-sh-setup -- cgit v1.3 From ea10b60c910e4a23483f47f17becc5e58f07ebe9 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Sat, 18 Apr 2009 20:42:07 -0700 Subject: Work around ash "alternate value" expansion bug Ash (used as /bin/sh on many distros) has a shell expansion bug for the form ${var:+word word}. The result is a single argument "word word". Work around by using ${var:+word} ${var:+word} or equivalent. Signed-off-by: Ben Jackson Signed-off-by: Junio C Hamano --- git-am.sh | 2 +- git-submodule.sh | 11 +++++++++-- t/t7400-submodule-basic.sh | 10 ++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-am.sh b/git-am.sh index 774383fb68..6d1848b6cc 100755 --- a/git-am.sh +++ b/git-am.sh @@ -571,7 +571,7 @@ do GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" export GIT_COMMITTER_DATE fi && - git commit-tree $tree ${parent:+-p $parent} <"$dotest/final-commit" + git commit-tree $tree ${parent:+-p} $parent <"$dotest/final-commit" ) && git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent || stop_here $this diff --git a/git-submodule.sh b/git-submodule.sh index 7c2e060ae7..8e234a4028 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -204,8 +204,15 @@ cmd_add() else module_clone "$path" "$realrepo" || exit - (unset GIT_DIR; cd "$path" && git checkout -f -q ${branch:+-b "$branch" "origin/$branch"}) || - die "Unable to checkout submodule '$path'" + ( + unset GIT_DIR + cd "$path" && + # ash fails to wordsplit ${branch:+-b "$branch"...} + case "$branch" in + '') git checkout -f -q ;; + ?*) git checkout -f -q -b "$branch" "origin/$branch" ;; + esac + ) || die "Unable to checkout submodule '$path'" fi git add "$path" || diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index af690ec6c1..0f2ccc6cf0 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -64,6 +64,16 @@ test_expect_success 'submodule add' ' ) ' +test_expect_success 'submodule add --branch' ' + ( + cd addtest && + git submodule add -b initial "$submodurl" submod-branch && + git submodule init && + cd submod-branch && + git branch | grep initial + ) +' + test_expect_success 'submodule add with ./ in path' ' ( cd addtest && -- cgit v1.3 From ca2cedba70e9356a1a20b0e39acd07ab92fee80e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 24 Apr 2009 09:06:38 +1000 Subject: git-submodule: add support for --rebase. 'git submodule update --rebase' rebases your local branch on top of what would have been checked out to a detached HEAD otherwise. In some cases, detaching the HEAD when updating a submodule complicates the workflow to commit to this submodule (checkout master, rebase, then commit). For submodules that require frequent updates but infrequent (if any) commits, a rebase can be executed directly by the git-submodule command, ensuring that the submodules stay on their respective branches. git-config key: submodule.$name.rebase (bool) Signed-off-by: Peter Hutterer Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 14 +++- Documentation/gitmodules.txt | 3 + git-submodule.sh | 33 ++++++++-- t/t7406-submodule-update.sh | 140 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 6 deletions(-) create mode 100755 t/t7406-submodule-update.sh (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 3b8df44673..0286409744 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -12,7 +12,7 @@ SYNOPSIS 'git submodule' [--quiet] add [-b branch] [--] 'git submodule' [--quiet] status [--cached] [--] [...] 'git submodule' [--quiet] init [--] [...] -'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--] [...] +'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--] [...] 'git submodule' [--quiet] summary [--summary-limit ] [commit] [--] [...] 'git submodule' [--quiet] foreach 'git submodule' [--quiet] sync [--] [...] @@ -113,7 +113,8 @@ init:: update:: Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. - This will make the submodules HEAD be detached. + This will make the submodules HEAD be detached unless '--rebase' is + specified or the key `submodule.$name.rebase` is set to `true`. + If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the @@ -177,6 +178,15 @@ OPTIONS This option is only valid for the update command. Don't fetch new objects from the remote site. +--rebase:: + This option is only valid for the update command. + Rebase the current branch onto the commit recorded in the + superproject. If this option is given, the submodule's HEAD will not + be detached. If a a merge failure prevents this process, you will have + to resolve these failures with linkgit:git-rebase[1]. + If the key `submodule.$name.rebase` is set to `true`, this option is + implicit. + ...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths. diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index d1a17e2625..7c22c40949 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -30,6 +30,9 @@ submodule..path:: submodule..url:: Defines an url from where the submodule repository can be cloned. +submodule..rebase:: + Defines that the submodule should be rebased by default. + EXAMPLES -------- diff --git a/git-submodule.sh b/git-submodule.sh index 8e234a4028..3176226ac7 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -17,6 +17,7 @@ branch= quiet= cached= nofetch= +rebase= # # print stuff on stdout unless -q was specified @@ -294,6 +295,11 @@ cmd_init() git config submodule."$name".url "$url" || die "Failed to register url for submodule path '$path'" + test true != "$(git config -f .gitmodules --bool \ + submodule."$name".rebase)" || + git config submodule."$name".rebase true || + die "Failed to register submodule path '$path' as rebasing" + say "Submodule '$name' ($url) registered for path '$path'" done } @@ -321,6 +327,10 @@ cmd_update() shift nofetch=1 ;; + -r|--rebase) + shift + rebase=true + ;; --) shift break @@ -339,6 +349,7 @@ cmd_update() do name=$(module_name "$path") || exit url=$(git config submodule."$name".url) + rebase_module=$(git config --bool submodule."$name".rebase) if test -z "$url" then # Only mention uninitialized submodules when its @@ -359,6 +370,11 @@ cmd_update() die "Unable to find current revision in submodule path '$path'" fi + if test true = "$rebase" + then + rebase_module=true + fi + if test "$subsha1" != "$sha1" then force= @@ -374,11 +390,20 @@ cmd_update() die "Unable to fetch in submodule path '$path'" fi - (unset GIT_DIR; cd "$path" && - git-checkout $force -q "$sha1") || - die "Unable to checkout '$sha1' in submodule path '$path'" + if test true = "$rebase_module" + then + command="git-rebase" + action="rebase" + msg="rebased onto" + else + command="git-checkout $force -q" + action="checkout" + msg="checked out" + fi - say "Submodule path '$path': checked out '$sha1'" + (unset GIT_DIR; cd "$path" && $command "$sha1") || + die "Unable to $action '$sha1' in submodule path '$path'" + say "Submodule path '$path': $msg '$sha1'" fi done } diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh new file mode 100755 index 0000000000..3442c05d2a --- /dev/null +++ b/t/t7406-submodule-update.sh @@ -0,0 +1,140 @@ +#!/bin/sh +# +# Copyright (c) 2009 Red Hat, Inc. +# + +test_description='Test updating submodules + +This test verifies that "git submodule update" detaches the HEAD of the +submodule and "git submodule update --rebase" does not detach the HEAD. +' + +. ./test-lib.sh + + +compare_head() +{ + sha_master=`git-rev-list --max-count=1 master` + sha_head=`git-rev-list --max-count=1 HEAD` + + test "$sha_master" = "$sha_head" +} + + +test_expect_success 'setup a submodule tree' ' + echo file > file && + git add file && + test_tick && + git commit -m upstream + git clone . super && + git clone super submodule && + (cd super && + git submodule add ../submodule submodule && + test_tick && + git commit -m "submodule" && + git submodule init submodule + ) && + (cd submodule && + echo "line2" > file && + git add file && + git commit -m "Commit 2" + ) && + (cd super && + (cd submodule && + git pull --rebase origin + ) && + git add submodule && + git commit -m "submodule update" + ) +' + +test_expect_success 'submodule update detaching the HEAD ' ' + (cd super/submodule && + git reset --hard HEAD~1 + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update submodule && + cd submodule && + ! compare_head + ) +' + +test_expect_success 'submodule update --rebase staying on master' ' + (cd super/submodule && + git checkout master + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update --rebase submodule && + cd submodule && + compare_head + ) +' + +test_expect_success 'submodule update - rebase true in .git/config' ' + (cd super && + git config submodule.submodule.rebase true + ) && + (cd super/submodule && + git reset --hard HEAD~1 + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update submodule && + cd submodule && + compare_head + ) +' + +test_expect_success 'submodule update - rebase false in .git/config but --rebase given' ' + (cd super && + git config submodule.submodule.rebase false + ) && + (cd super/submodule && + git reset --hard HEAD~1 + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update --rebase submodule && + cd submodule && + compare_head + ) +' + +test_expect_success 'submodule update - rebase false in .git/config' ' + (cd super && + git config submodule.submodule.rebase false + ) && + (cd super/submodule && + git reset --hard HEAD^ + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update submodule && + cd submodule && + ! compare_head + ) +' + +test_expect_success 'submodule init picks up rebase' ' + (cd super && + git config submodule.rebasing.url git://non-existing/git && + git config submodule.rebasing.path does-not-matter && + git config submodule.rebasing.rebase true && + git submodule init rebasing && + test true = $(git config --bool submodule.rebasing.rebase) + ) +' + +test_done -- cgit v1.3 From d92a39590d1126e195f1bbccf182a2cdb79218e7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 4 May 2009 22:30:01 +0300 Subject: Add --reference option to git submodule. This adds --reference option to git submodule add and git submodule update commands, which is passed to git clone. Signed-off-by: Michael S. Tsirkin Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 14 ++++++- git-submodule.sh | 38 +++++++++++++++++-- t/t7406-submodule-reference.sh | 81 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 6 deletions(-) create mode 100755 t/t7406-submodule-reference.sh (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 3b8df44673..14256c695b 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -9,10 +9,12 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- [verse] -'git submodule' [--quiet] add [-b branch] [--] +'git submodule' [--quiet] add [-b branch] + [--reference ] [--] 'git submodule' [--quiet] status [--cached] [--] [...] 'git submodule' [--quiet] init [--] [...] -'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--] [...] +'git submodule' [--quiet] update [--init] [-N|--no-fetch] + [--reference ] [--] [...] 'git submodule' [--quiet] summary [--summary-limit ] [commit] [--] [...] 'git submodule' [--quiet] foreach 'git submodule' [--quiet] sync [--] [...] @@ -177,6 +179,14 @@ OPTIONS This option is only valid for the update command. Don't fetch new objects from the remote site. +--reference :: + This option is only valid for add and update commands. These + commands sometimes need to clone a remote repository. In this case, + this option will be passed to the linkgit:git-clone[1] command. ++ +*NOTE*: Do *not* use this option unless you have read the note +for linkgit:git-clone[1]'s --reference and --shared options carefully. + ...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths. diff --git a/git-submodule.sh b/git-submodule.sh index 8e234a4028..ab1ed02a66 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -15,6 +15,7 @@ require_work_tree command= branch= quiet= +reference= cached= nofetch= @@ -91,6 +92,7 @@ module_clone() { path=$1 url=$2 + reference="$3" # If there already is a directory at the submodule path, # expect it to be empty (since that is the default checkout @@ -106,7 +108,12 @@ module_clone() test -e "$path" && die "A file already exist at path '$path'" - git-clone -n "$url" "$path" || + if test -n "$reference" + then + git-clone "$reference" -n "$url" "$path" + else + git-clone -n "$url" "$path" + fi || die "Clone of '$url' into submodule path '$path' failed" } @@ -131,6 +138,15 @@ cmd_add() -q|--quiet) quiet=1 ;; + --reference) + case "$2" in '') usage ;; esac + reference="--reference=$2" + shift + ;; + --reference=*) + reference="$1" + shift + ;; --) shift break @@ -203,7 +219,7 @@ cmd_add() git config submodule."$path".url "$url" else - module_clone "$path" "$realrepo" || exit + module_clone "$path" "$realrepo" "$reference" || exit ( unset GIT_DIR cd "$path" && @@ -314,13 +330,22 @@ cmd_update() quiet=1 ;; -i|--init) + init=1 shift - cmd_init "$@" || return ;; -N|--no-fetch) shift nofetch=1 ;; + --reference) + case "$2" in '') usage ;; esac + reference="--reference=$2" + shift 2 + ;; + --reference=*) + reference="$1" + shift + ;; --) shift break @@ -334,6 +359,11 @@ cmd_update() esac done + if test -n "$init" + then + cmd_init "--" "$@" || return + fi + module_list "$@" | while read mode sha1 stage path do @@ -351,7 +381,7 @@ cmd_update() if ! test -d "$path"/.git -o -f "$path"/.git then - module_clone "$path" "$url" || exit + module_clone "$path" "$url" "$reference"|| exit subsha1= else subsha1=$(unset GIT_DIR; cd "$path" && diff --git a/t/t7406-submodule-reference.sh b/t/t7406-submodule-reference.sh new file mode 100755 index 0000000000..cc16d3f05d --- /dev/null +++ b/t/t7406-submodule-reference.sh @@ -0,0 +1,81 @@ +#!/bin/sh +# +# Copyright (c) 2009, Red Hat Inc, Author: Michael S. Tsirkin (mst@redhat.com) +# + +test_description='test clone --reference' +. ./test-lib.sh + +base_dir=`pwd` + +U=$base_dir/UPLOAD_LOG + +test_expect_success 'preparing first repository' \ +'test_create_repo A && cd A && +echo first > file1 && +git add file1 && +git commit -m A-initial' + +cd "$base_dir" + +test_expect_success 'preparing second repository' \ +'git clone A B && cd B && +echo second > file2 && +git add file2 && +git commit -m B-addition && +git repack -a -d && +git prune' + +cd "$base_dir" + +test_expect_success 'preparing supermodule' \ +'test_create_repo super && cd super && +echo file > file && +git add file && +git commit -m B-super-initial' + +cd "$base_dir" + +test_expect_success 'submodule add --reference' \ +'cd super && git submodule add --reference ../B "file://$base_dir/A" sub && +git commit -m B-super-added' + +cd "$base_dir" + +test_expect_success 'after add: existence of info/alternates' \ +'test `wc -l expected && +git count-objects > current && +diff expected current' + +cd "$base_dir" + +test_expect_success 'cloning supermodule' \ +'git clone super super-clone' + +cd "$base_dir" + +test_expect_success 'update with reference' \ +'cd super-clone && git submodule update --init --reference ../B' + +cd "$base_dir" + +test_expect_success 'after update: existence of info/alternates' \ +'test `wc -l expected && +git count-objects > current && +diff expected current' + +cd "$base_dir" + +test_done -- cgit v1.3 From 329484256e0fe42676e93669122e7a5a007ef4ed Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Wed, 3 Jun 2009 08:27:06 +0200 Subject: Rename submodule..rebase to submodule..update The addition of "submodule..rebase" demonstrates the usefulness of alternatives to the default behaviour of "git submodule update". However, by naming the config variable "submodule..rebase", and making it a boolean choice, we are artificially constraining future git versions that may want to add _more_ alternatives than just "rebase". Therefore, while "submodule..rebase" is not yet in a stable git release, future-proof it, by changing it from submodule..rebase = true/false to submodule..update = rebase/checkout where "checkout" specifies the default behaviour of "git submodule update" (checking out the new commit to a detached HEAD), and "rebase" specifies the --rebase behaviour (where the current local branch in the submodule is rebase onto the new commit). Thus .update == checkout is equivalent to .rebase == false, and .update == rebase is equivalent to .rebase == true. Finally, leaving .update unset is equivalent to leaving .rebase unset. In future git versions, other alternatives to "git submodule update" behaviour can be included by adding them to the list of allowable values for the submodule..update variable. Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 4 ++-- Documentation/gitmodules.txt | 10 ++++++++-- git-submodule.sh | 32 +++++++++++++++++--------------- t/t7406-submodule-update.sh | 16 ++++++++-------- 4 files changed, 35 insertions(+), 27 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 0286409744..f993469dc6 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -114,7 +114,7 @@ update:: Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. This will make the submodules HEAD be detached unless '--rebase' is - specified or the key `submodule.$name.rebase` is set to `true`. + specified or the key `submodule.$name.update` is set to `rebase`. + If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the @@ -184,7 +184,7 @@ OPTIONS superproject. If this option is given, the submodule's HEAD will not be detached. If a a merge failure prevents this process, you will have to resolve these failures with linkgit:git-rebase[1]. - If the key `submodule.$name.rebase` is set to `true`, this option is + If the key `submodule.$name.update` is set to `rebase`, this option is implicit. ...:: diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index 7c22c40949..1b67f0a9f1 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -30,8 +30,14 @@ submodule..path:: submodule..url:: Defines an url from where the submodule repository can be cloned. -submodule..rebase:: - Defines that the submodule should be rebased by default. +submodule..update:: + Defines what to do when the submodule is updated by the superproject. + If 'checkout' (the default), the new commit specified in the + superproject will be checked out in the submodule on a detached HEAD. + If 'rebase', the current branch of the submodule will be rebased onto + the commit specified in the superproject. + This config option is overridden if 'git submodule update' is given + the '--rebase' option. EXAMPLES diff --git a/git-submodule.sh b/git-submodule.sh index 3176226ac7..f384c6b2b4 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -17,7 +17,7 @@ branch= quiet= cached= nofetch= -rebase= +update= # # print stuff on stdout unless -q was specified @@ -295,10 +295,10 @@ cmd_init() git config submodule."$name".url "$url" || die "Failed to register url for submodule path '$path'" - test true != "$(git config -f .gitmodules --bool \ - submodule."$name".rebase)" || - git config submodule."$name".rebase true || - die "Failed to register submodule path '$path' as rebasing" + upd="$(git config -f .gitmodules submodule."$name".update)" + test -z "$upd" || + git config submodule."$name".update "$upd" || + die "Failed to register update mode for submodule path '$path'" say "Submodule '$name' ($url) registered for path '$path'" done @@ -329,7 +329,7 @@ cmd_update() ;; -r|--rebase) shift - rebase=true + update="rebase" ;; --) shift @@ -349,7 +349,7 @@ cmd_update() do name=$(module_name "$path") || exit url=$(git config submodule."$name".url) - rebase_module=$(git config --bool submodule."$name".rebase) + update_module=$(git config submodule."$name".update) if test -z "$url" then # Only mention uninitialized submodules when its @@ -370,9 +370,9 @@ cmd_update() die "Unable to find current revision in submodule path '$path'" fi - if test true = "$rebase" + if ! test -z "$update" then - rebase_module=true + update_module=$update fi if test "$subsha1" != "$sha1" @@ -390,16 +390,18 @@ cmd_update() die "Unable to fetch in submodule path '$path'" fi - if test true = "$rebase_module" - then - command="git-rebase" + case "$update_module" in + rebase) + command="git rebase" action="rebase" msg="rebased onto" - else - command="git-checkout $force -q" + ;; + *) + command="git checkout $force -q" action="checkout" msg="checked out" - fi + ;; + esac (unset GIT_DIR; cd "$path" && $command "$sha1") || die "Unable to $action '$sha1' in submodule path '$path'" diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 3442c05d2a..0773fe405b 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -76,9 +76,9 @@ test_expect_success 'submodule update --rebase staying on master' ' ) ' -test_expect_success 'submodule update - rebase true in .git/config' ' +test_expect_success 'submodule update - rebase in .git/config' ' (cd super && - git config submodule.submodule.rebase true + git config submodule.submodule.update rebase ) && (cd super/submodule && git reset --hard HEAD~1 @@ -93,9 +93,9 @@ test_expect_success 'submodule update - rebase true in .git/config' ' ) ' -test_expect_success 'submodule update - rebase false in .git/config but --rebase given' ' +test_expect_success 'submodule update - checkout in .git/config but --rebase given' ' (cd super && - git config submodule.submodule.rebase false + git config submodule.submodule.update checkout ) && (cd super/submodule && git reset --hard HEAD~1 @@ -110,9 +110,9 @@ test_expect_success 'submodule update - rebase false in .git/config but --rebase ) ' -test_expect_success 'submodule update - rebase false in .git/config' ' +test_expect_success 'submodule update - checkout in .git/config' ' (cd super && - git config submodule.submodule.rebase false + git config submodule.submodule.update checkout ) && (cd super/submodule && git reset --hard HEAD^ @@ -131,9 +131,9 @@ test_expect_success 'submodule init picks up rebase' ' (cd super && git config submodule.rebasing.url git://non-existing/git && git config submodule.rebasing.path does-not-matter && - git config submodule.rebasing.rebase true && + git config submodule.rebasing.update rebase && git submodule init rebasing && - test true = $(git config --bool submodule.rebasing.rebase) + test "rebase" = $(git config submodule.rebasing.update) ) ' -- cgit v1.3 From 42b491786260eb17d97ea9fb1c4b70075bca9523 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Wed, 3 Jun 2009 00:59:12 +0200 Subject: git-submodule: add support for --merge. 'git submodule update --merge' merges the commit referenced by the superproject into your local branch, instead of checking it out on a detached HEAD. As evidenced by the addition of "git submodule update --rebase", it is useful to provide alternatives to the default 'checkout' behaviour of "git submodule update". One such alternative is, when updating a submodule to a new commit, to merge that commit into the current local branch in that submodule. This is useful in workflows where you want to update your submodule from its upstream, but you cannot use --rebase, because you have downstream people working on top of your submodule branch, and you don't want to disrupt their work. Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 15 +++++++++-- Documentation/gitmodules.txt | 6 +++-- git-submodule.sh | 11 +++++++- t/t7406-submodule-update.sh | 60 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 86 insertions(+), 6 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index f993469dc6..2289d11f0e 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -113,8 +113,9 @@ init:: update:: Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. - This will make the submodules HEAD be detached unless '--rebase' is - specified or the key `submodule.$name.update` is set to `rebase`. + This will make the submodules HEAD be detached unless '--rebase' or + '--merge' is specified or the key `submodule.$name.update` is set to + `rebase` or `merge`. + If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the @@ -187,6 +188,16 @@ OPTIONS If the key `submodule.$name.update` is set to `rebase`, this option is implicit. +--merge:: + This option is only valid for the update command. + Merge the commit recorded in the superproject into the current branch + of the submodule. If this option is given, the submodule's HEAD will + not be detached. If a merge failure prevents this process, you will + have to resolve the resulting conflicts within the submodule with the + usual conflict resolution tools. + If the key `submodule.$name.update` is set to `merge`, this option is + implicit. + ...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths. diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index 1b67f0a9f1..5daf750d19 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -35,9 +35,11 @@ submodule..update:: If 'checkout' (the default), the new commit specified in the superproject will be checked out in the submodule on a detached HEAD. If 'rebase', the current branch of the submodule will be rebased onto - the commit specified in the superproject. + the commit specified in the superproject. If 'merge', the commit + specified in the superproject will be merged into the current branch + in the submodule. This config option is overridden if 'git submodule update' is given - the '--rebase' option. + the '--merge' or '--rebase' options. EXAMPLES diff --git a/git-submodule.sh b/git-submodule.sh index f384c6b2b4..3aff37970a 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -5,7 +5,7 @@ # Copyright (c) 2007 Lars Hjemli USAGE="[--quiet] [--cached] \ -[add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit ] []] \ +[add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch] [--rebase|--merge]|summary [-n|--summary-limit ] []] \ [--] [...]|[foreach ]|[sync [--] [...]]" OPTIONS_SPEC= . git-sh-setup @@ -331,6 +331,10 @@ cmd_update() shift update="rebase" ;; + -m|--merge) + shift + update="merge" + ;; --) shift break @@ -396,6 +400,11 @@ cmd_update() action="rebase" msg="rebased onto" ;; + merge) + command="git merge" + action="merge" + msg="merged in" + ;; *) command="git checkout $force -q" action="checkout" diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 0773fe405b..2d33d9efec 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -6,7 +6,7 @@ test_description='Test updating submodules This test verifies that "git submodule update" detaches the HEAD of the -submodule and "git submodule update --rebase" does not detach the HEAD. +submodule and "git submodule update --rebase/--merge" does not detach the HEAD. ' . ./test-lib.sh @@ -76,6 +76,20 @@ test_expect_success 'submodule update --rebase staying on master' ' ) ' +test_expect_success 'submodule update --merge staying on master' ' + (cd super/submodule && + git reset --hard HEAD~1 + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update --merge submodule && + cd submodule && + compare_head + ) +' + test_expect_success 'submodule update - rebase in .git/config' ' (cd super && git config submodule.submodule.update rebase @@ -110,6 +124,40 @@ test_expect_success 'submodule update - checkout in .git/config but --rebase giv ) ' +test_expect_success 'submodule update - merge in .git/config' ' + (cd super && + git config submodule.submodule.update merge + ) && + (cd super/submodule && + git reset --hard HEAD~1 + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update submodule && + cd submodule && + compare_head + ) +' + +test_expect_success 'submodule update - checkout in .git/config but --merge given' ' + (cd super && + git config submodule.submodule.update checkout + ) && + (cd super/submodule && + git reset --hard HEAD~1 + ) && + (cd super && + (cd submodule && + compare_head + ) && + git submodule update --merge submodule && + cd submodule && + compare_head + ) +' + test_expect_success 'submodule update - checkout in .git/config' ' (cd super && git config submodule.submodule.update checkout @@ -137,4 +185,14 @@ test_expect_success 'submodule init picks up rebase' ' ) ' +test_expect_success 'submodule init picks up merge' ' + (cd super && + git config submodule.merging.url git://non-existing/git && + git config submodule.merging.path does-not-matter && + git config submodule.merging.update merge && + git submodule init merging && + test "merge" = $(git config submodule.merging.update) + ) +' + test_done -- cgit v1.3 From 2e6a30ef8fbaedc5f2ee199d36f7256bb0cfdf1e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 16 Jun 2009 15:33:00 -0700 Subject: submodule, repack: migrate to git-sh-setup's say() Now that there is say() in git-sh-setup, these scripts don't need to use their own. Migrate them over by setting GIT_QUIET and removing their custom say() functions. Signed-off-by: Stephen Boyd Signed-off-by: Junio C Hamano --- git-repack.sh | 12 +++++------- git-submodule.sh | 24 ++++++------------------ 2 files changed, 11 insertions(+), 25 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-repack.sh b/git-repack.sh index 0868734723..1bf239499c 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -24,7 +24,7 @@ SUBDIRECTORY_OK='Yes' . git-sh-setup no_update_info= all_into_one= remove_redundant= unpack_unreachable= -local= quiet= no_reuse= extra= +local= no_reuse= extra= while test $# != 0 do case "$1" in @@ -33,7 +33,7 @@ do -A) all_into_one=t unpack_unreachable=--unpack-unreachable ;; -d) remove_redundant=t ;; - -q) quiet=-q ;; + -q) GIT_QUIET=t ;; -f) no_reuse=--no-reuse-object ;; -l) local=--local ;; --max-pack-size|--window|--window-memory|--depth) @@ -80,13 +80,11 @@ case ",$all_into_one," in ;; esac -args="$args $local $quiet $no_reuse$extra" +args="$args $local ${GIT_QUIET:+-q} $no_reuse$extra" names=$(git pack-objects --honor-pack-keep --non-empty --all --reflog $args Date: Thu, 13 Aug 2009 21:32:50 +0200 Subject: git submodule summary: add --files option git submodule summary is providing similar functionality for submodules as git diff-index does for a git project (including the meaning of --cached). But the analogon to git diff-files is missing, so add a --files option to summarize the differences between the index of the super project and the last commit checked out in the working tree of the submodule. Signed-off-by: Jens Lehmann Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 13 +++++++++++-- git-submodule.sh | 19 ++++++++++++++++--- t/t7401-submodule-summary.sh | 22 ++++++++++++++++++++++ 3 files changed, 49 insertions(+), 5 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 7dd73ae14e..145802a936 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -15,7 +15,7 @@ SYNOPSIS 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--] [...] -'git submodule' [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] +'git submodule' [--quiet] summary [--cached|--files] [--summary-limit ] [commit] [--] [...] 'git submodule' [--quiet] foreach 'git submodule' [--quiet] sync [--] [...] @@ -127,7 +127,11 @@ summary:: Show commit summary between the given commit (defaults to HEAD) and working tree/index. For a submodule in question, a series of commits in the submodule between the given super project commit and the - index or working tree (switched by --cached) are shown. + index or working tree (switched by --cached) are shown. If the option + --files is given, show the series of commits in the submodule between + the index of super project the and the working tree of the submodule + (this option doesn't allow to use the --cached option or to provide an + explicit commit). foreach:: Evaluates an arbitrary shell command in each checked out submodule. @@ -169,6 +173,11 @@ OPTIONS commands typically use the commit found in the submodule HEAD, but with this option, the commit stored in the index is used instead. +--files:: + This option is only valid for the summary command. This command + compares the commit in the index with that in the submodule HEAD + when this option is used. + -n:: --summary-limit:: This option is only valid for the summary command. diff --git a/git-submodule.sh b/git-submodule.sh index ebed711da4..9bdd6ea3d0 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -4,7 +4,7 @@ # # Copyright (c) 2007 Lars Hjemli -USAGE="[--quiet] [--cached] \ +USAGE="[--quiet] [--cached|--files] \ [add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch] [--rebase|--merge]|summary [-n|--summary-limit ] []] \ [--] [...]|[foreach ]|[sync [--] [...]]" OPTIONS_SPEC= @@ -16,6 +16,7 @@ command= branch= reference= cached= +files= nofetch= update= @@ -460,6 +461,7 @@ set_name_rev () { cmd_summary() { summary_limit=-1 for_status= + diff_cmd=diff-index # parse $args after "submodule ... summary". while test $# -ne 0 @@ -468,6 +470,9 @@ cmd_summary() { --cached) cached="$1" ;; + --files) + files="$1" + ;; --for-status) for_status="$1" ;; @@ -504,9 +509,17 @@ cmd_summary() { head=HEAD fi + if [ -n "$files" ] + then + test -n "$cached" && + die "--cached cannot be used with --files" + diff_cmd=diff-files + head= + fi + cd_to_toplevel # Get modified modules cared by user - modules=$(git diff-index $cached --raw $head -- "$@" | + modules=$(git $diff_cmd $cached --raw $head -- "$@" | egrep '^:([0-7]* )?160000' | while read mod_src mod_dst sha1_src sha1_dst status name do @@ -520,7 +533,7 @@ cmd_summary() { test -z "$modules" && return - git diff-index $cached --raw $head -- $modules | + git $diff_cmd $cached --raw $head -- $modules | egrep '^:([0-7]* )?160000' | cut -c2- | while read mod_src mod_dst sha1_src sha1_dst status name diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 61498293b9..6cc16c39fe 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -56,6 +56,15 @@ test_expect_success 'modified submodule(forward)' " EOF " +test_expect_success 'modified submodule(forward), --files' " + git submodule summary --files >actual && + diff actual - <<-EOF +* sm1 $head1...$head2 (1): + > Add foo3 + +EOF +" + commit_file sm1 && cd sm1 && git reset --hard HEAD~2 >/dev/null && @@ -114,6 +123,15 @@ test_expect_success 'typechanged submodule(submodule->blob), --cached' " EOF " +test_expect_success 'typechanged submodule(submodule->blob), --files' " + git submodule summary --files >actual && + diff actual - <<-EOF +* sm1 $head5(blob)->$head4(submodule) (3): + > Add foo5 + +EOF +" + rm -rf sm1 && git checkout-index sm1 test_expect_success 'typechanged submodule(submodule->blob)' " @@ -205,4 +223,8 @@ test_expect_success '--for-status' " EOF " +test_expect_success 'fail when using --files together with --cached' " + test_must_fail git submodule summary --files --cached +" + test_done -- cgit v1.3 From 1e7f2aad7dd9b0b5ec8bbae2e3015915687e2cd2 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Sun, 16 Aug 2009 03:10:08 +0200 Subject: git submodule foreach: Provide access to submodule name, as '$name' The argument to 'git submodule foreach' already has access to the variables '$path' (the path to the submodule, relative to the superproject) and '$sha1' (the submodule commit recorded by the superproject). This patch adds another variable -- '$name' -- which contains the name of the submodule, as recorded in the superproject's .gitmodules file. Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 3 ++- git-submodule.sh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 7dd73ae14e..97c32fe264 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -131,7 +131,8 @@ summary:: foreach:: Evaluates an arbitrary shell command in each checked out submodule. - The command has access to the variables $path and $sha1: + The command has access to the variables $name, $path and $sha1: + $name is the name of the relevant submodule section in .gitmodules, $path is the name of the submodule directory relative to the superproject, and $sha1 is the commit as recorded in the superproject. Any submodules defined in the superproject but not checked out are diff --git a/git-submodule.sh b/git-submodule.sh index ebed711da4..d8ecdb91fe 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -243,6 +243,7 @@ cmd_foreach() if test -e "$path"/.git then say "Entering '$path'" + name=$(module_name "$path") (cd "$path" && eval "$@") || die "Stopping at '$path'; script returned non-zero status." fi -- cgit v1.3 From 1d5bec8b9cee65b1f98a118ba79120ea686252e3 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Wed, 19 Aug 2009 03:45:19 +0200 Subject: git submodule: Cleanup usage string and add option parsing to cmd_foreach() Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- git-submodule.sh | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index d8ecdb91fe..f48f682ab6 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -4,9 +4,14 @@ # # Copyright (c) 2007 Lars Hjemli -USAGE="[--quiet] [--cached] \ -[add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch] [--rebase|--merge]|summary [-n|--summary-limit ] []] \ -[--] [...]|[foreach ]|[sync [--] [...]]" +dashless=$(basename "$0" | sed -e 's/-/ /') +USAGE="[--quiet] add [-b branch] [--reference ] [--] + or: $dashless [--quiet] status [--cached] [--] [...] + or: $dashless [--quiet] init [--] [...] + or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--] [...] + or: $dashless [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] + or: $dashless [--quiet] foreach + or: $dashless [--quiet] sync [--] [...]" OPTIONS_SPEC= . git-sh-setup . git-parse-remote @@ -237,6 +242,23 @@ cmd_add() # cmd_foreach() { + # parse $args after "submodule ... foreach". + while test $# -ne 0 + do + case "$1" in + -q|--quiet) + GIT_QUIET=1 + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift + done + module_list | while read mode sha1 stage path do -- cgit v1.3 From 15fc56a853648c60697df691c5cd8a11ad718611 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Wed, 19 Aug 2009 03:45:22 +0200 Subject: git submodule foreach: Add --recursive to recurse into nested submodules In very large and hierarchically structured projects, one may encounter nested submodules. In these situations, it is valuable to not only operate on all the submodules in the current repo (which is what is currently done by 'git submodule foreach'), but also to operate on all submodules at all levels (i.e. recursing into nested submodules as well). This patch teaches the new --recursive option to the 'git submodule foreach' command. The patch also includes documentation and selftests. Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 10 ++++- git-submodule.sh | 19 ++++++-- t/t7407-submodule-foreach.sh | 99 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 4 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 97c32fe264..326136a85b 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -16,7 +16,7 @@ SYNOPSIS 'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--] [...] 'git submodule' [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] -'git submodule' [--quiet] foreach +'git submodule' [--quiet] foreach [--recursive] 'git submodule' [--quiet] sync [--] [...] @@ -138,6 +138,8 @@ foreach:: Any submodules defined in the superproject but not checked out are ignored by this command. Unless given --quiet, foreach prints the name of each submodule before evaluating the command. + If --recursive is given, submodules are traversed recursively (i.e. + the given shell command is evaluated in nested submodules as well). A non-zero return from the command in any submodule causes the processing to terminate. This can be overridden by adding '|| :' to the end of the command. @@ -210,6 +212,12 @@ OPTIONS *NOTE*: Do *not* use this option unless you have read the note for linkgit:git-clone[1]'s --reference and --shared options carefully. +--recursive:: + This option is only valid for the foreach command. + Traverse submodules recursively. The operation is performed not + only in the submodules of the current repo, but also + in any nested submodules inside those submodules (and so on). + ...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths. diff --git a/git-submodule.sh b/git-submodule.sh index f48f682ab6..c501b7eafa 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -10,7 +10,7 @@ USAGE="[--quiet] add [-b branch] [--reference ] [--]

...] or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--] [...] or: $dashless [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] - or: $dashless [--quiet] foreach + or: $dashless [--quiet] foreach [--recursive] or: $dashless [--quiet] sync [--] [...]" OPTIONS_SPEC= . git-sh-setup @@ -23,6 +23,7 @@ reference= cached= nofetch= update= +prefix= # Resolve relative url by appending to parent's url resolve_relative_url () @@ -249,6 +250,9 @@ cmd_foreach() -q|--quiet) GIT_QUIET=1 ;; + --recursive) + recursive=1 + ;; -*) usage ;; @@ -264,9 +268,18 @@ cmd_foreach() do if test -e "$path"/.git then - say "Entering '$path'" + say "Entering '$prefix$path'" name=$(module_name "$path") - (cd "$path" && eval "$@") || + ( + prefix="$prefix$path/" + unset GIT_DIR + cd "$path" && + eval "$@" && + if test -n "$recursive" + then + cmd_foreach "--recursive" "$@" + fi + ) || die "Stopping at '$path'; script returned non-zero status." fi done diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 991aa80c8a..be122c7f8c 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -76,4 +76,103 @@ test_expect_success 'test basic "submodule foreach" usage' ' test_cmp expect actual ' +test_expect_success 'setup nested submodules' ' + git clone submodule nested1 && + git clone submodule nested2 && + git clone submodule nested3 && + ( + cd nested3 && + git submodule add ../submodule submodule && + test_tick && + git commit -m "submodule" && + git submodule init submodule + ) && + ( + cd nested2 && + git submodule add ../nested3 nested3 && + test_tick && + git commit -m "nested3" && + git submodule init nested3 + ) && + ( + cd nested1 && + git submodule add ../nested2 nested2 && + test_tick && + git commit -m "nested2" && + git submodule init nested2 + ) && + ( + cd super && + git submodule add ../nested1 nested1 && + test_tick && + git commit -m "nested1" && + git submodule init nested1 + ) +' + +test_expect_success 'use "submodule foreach" to checkout 2nd level submodule' ' + git clone super clone2 && + ( + cd clone2 && + test ! -d sub1/.git && + test ! -d sub2/.git && + test ! -d sub3/.git && + test ! -d nested1/.git && + git submodule update --init && + test -d sub1/.git && + test -d sub2/.git && + test -d sub3/.git && + test -d nested1/.git && + test ! -d nested1/nested2/.git && + git submodule foreach "git submodule update --init" && + test -d nested1/nested2/.git && + test ! -d nested1/nested2/nested3/.git + ) +' + +test_expect_success 'use "foreach --recursive" to checkout all submodules' ' + ( + cd clone2 && + git submodule foreach --recursive "git submodule update --init" && + test -d nested1/nested2/nested3/.git && + test -d nested1/nested2/nested3/submodule/.git + ) +' + +cat > expect < ../actual + ) && + test_cmp expect actual +' + +cat > expect < ../actual + ) && + test_cmp expect actual +' + test_done -- cgit v1.3 From b13fd5c1a2bd450cdf7b853e0c4861f361882a18 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Wed, 19 Aug 2009 03:45:23 +0200 Subject: git submodule update: Introduce --recursive to update nested submodules In very large and hierarchically structured projects, one may encounter nested submodules. In these situations, it is valuable to not only update the submodules in the current repo (which is what is currently done by 'git submodule update'), but also to operate on all submodules at all levels (i.e. recursing into nested submodules as well). This patch teaches the new --recursive option to the 'git submodule update' command. The patch also includes documentation and selftests. Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 7 +++++-- git-submodule.sh | 13 ++++++++++++- t/t7407-submodule-foreach.sh | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 326136a85b..55bbc4f930 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -14,7 +14,7 @@ SYNOPSIS 'git submodule' [--quiet] status [--cached] [--] [...] 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] - [--reference ] [--merge] [--] [...] + [--reference ] [--merge] [--recursive] [--] [...] 'git submodule' [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] 'git submodule' [--quiet] foreach [--recursive] 'git submodule' [--quiet] sync [--] [...] @@ -122,6 +122,9 @@ update:: If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the submodule with the --init option. ++ +If '--recursive' is specified, this command will recurse into the +registered submodules, and update any nested submodules within. summary:: Show commit summary between the given commit (defaults to HEAD) and @@ -213,7 +216,7 @@ OPTIONS for linkgit:git-clone[1]'s --reference and --shared options carefully. --recursive:: - This option is only valid for the foreach command. + This option is only valid for foreach and update commands. Traverse submodules recursively. The operation is performed not only in the submodules of the current repo, but also in any nested submodules inside those submodules (and so on). diff --git a/git-submodule.sh b/git-submodule.sh index c501b7eafa..d8b98ff88f 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /') USAGE="[--quiet] add [-b branch] [--reference ] [--] or: $dashless [--quiet] status [--cached] [--] [...] or: $dashless [--quiet] init [--] [...] - or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--] [...] + or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] or: $dashless [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] or: $dashless [--quiet] foreach [--recursive] or: $dashless [--quiet] sync [--] [...]" @@ -352,6 +352,7 @@ cmd_init() cmd_update() { # parse $args after "submodule ... update". + orig_args="$@" while test $# -ne 0 do case "$1" in @@ -384,6 +385,10 @@ cmd_update() shift update="merge" ;; + --recursive) + shift + recursive=1 + ;; --) shift break @@ -470,6 +475,12 @@ cmd_update() die "Unable to $action '$sha1' in submodule path '$path'" say "Submodule path '$path': $msg '$sha1'" fi + + if test -n "$recursive" + then + (unset GIT_DIR; cd "$path" && cmd_update $orig_args) || + die "Failed to recurse into submodule path '$path'" + fi done } diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index be122c7f8c..9122bfef35 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -175,4 +175,23 @@ test_expect_success 'test "foreach --quiet --recursive"' ' test_cmp expect actual ' +test_expect_success 'use "update --recursive" to checkout all submodules' ' + git clone super clone3 && + ( + cd clone3 && + test ! -d sub1/.git && + test ! -d sub2/.git && + test ! -d sub3/.git && + test ! -d nested1/.git && + git submodule update --init --recursive && + test -d sub1/.git && + test -d sub2/.git && + test -d sub3/.git && + test -d nested1/.git && + test -d nested1/nested2/.git && + test -d nested1/nested2/nested3/.git && + test -d nested1/nested2/nested3/submodule/.git + ) +' + test_done -- cgit v1.3 From 64b19ffeddda499e7380b38b43a3dee579734905 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Wed, 19 Aug 2009 03:45:24 +0200 Subject: git submodule status: Add --recursive to recurse into nested submodules In very large and hierarchically structured projects, one may encounter nested submodules. In these situations, it is valuable to not only show status for all the submodules in the current repo (which is what is currently done by 'git submodule status'), but also to show status for all submodules at all levels (i.e. recursing into nested submodules as well). This patch teaches the new --recursive option to the 'git submodule status' command. The patch also includes documentation and selftests. Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 7 +++++-- git-submodule.sh | 24 ++++++++++++++++++++---- t/t7407-submodule-foreach.sh | 26 ++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 55bbc4f930..b81c830c28 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -11,7 +11,7 @@ SYNOPSIS [verse] 'git submodule' [--quiet] add [-b branch] [--reference ] [--] -'git submodule' [--quiet] status [--cached] [--] [...] +'git submodule' [--quiet] status [--cached] [--recursive] [--] [...] 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] @@ -100,6 +100,9 @@ status:: initialized and `+` if the currently checked out submodule commit does not match the SHA-1 found in the index of the containing repository. This command is the default command for 'git-submodule'. ++ +If '--recursive' is specified, this command will recurse into nested +submodules, and show their status as well. init:: Initialize the submodules, i.e. register each submodule name @@ -216,7 +219,7 @@ OPTIONS for linkgit:git-clone[1]'s --reference and --shared options carefully. --recursive:: - This option is only valid for foreach and update commands. + This option is only valid for foreach, update and status commands. Traverse submodules recursively. The operation is performed not only in the submodules of the current repo, but also in any nested submodules inside those submodules (and so on). diff --git a/git-submodule.sh b/git-submodule.sh index d8b98ff88f..446bbc0a10 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -6,7 +6,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /') USAGE="[--quiet] add [-b branch] [--reference ] [--] - or: $dashless [--quiet] status [--cached] [--] [...] + or: $dashless [--quiet] status [--cached] [--recursive] [--] [...] or: $dashless [--quiet] init [--] [...] or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] or: $dashless [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] @@ -690,6 +690,7 @@ cmd_summary() { cmd_status() { # parse $args after "submodule ... status". + orig_args="$@" while test $# -ne 0 do case "$1" in @@ -699,6 +700,9 @@ cmd_status() --cached) cached=1 ;; + --recursive) + recursive=1 + ;; --) shift break @@ -718,22 +722,34 @@ cmd_status() do name=$(module_name "$path") || exit url=$(git config submodule."$name".url) + displaypath="$prefix$path" if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git then - say "-$sha1 $path" + say "-$sha1 $displaypath" continue; fi set_name_rev "$path" "$sha1" if git diff-files --quiet -- "$path" then - say " $sha1 $path$revname" + say " $sha1 $displaypath$revname" else if test -z "$cached" then sha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD) set_name_rev "$path" "$sha1" fi - say "+$sha1 $path$revname" + say "+$sha1 $displaypath$revname" + fi + + if test -n "$recursive" + then + ( + prefix="$displaypath/" + unset GIT_DIR + cd "$path" && + cmd_status $orig_args + ) || + die "Failed to recurse into submodule path '$path'" fi done } diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 9122bfef35..de1730d638 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -194,4 +194,30 @@ test_expect_success 'use "update --recursive" to checkout all submodules' ' ) ' +nested1sha1=$(cd clone3/nested1 && git rev-parse HEAD) +nested2sha1=$(cd clone3/nested1/nested2 && git rev-parse HEAD) +nested3sha1=$(cd clone3/nested1/nested2/nested3 && git rev-parse HEAD) +submodulesha1=$(cd clone3/nested1/nested2/nested3/submodule && git rev-parse HEAD) +sub1sha1=$(cd clone3/sub1 && git rev-parse HEAD) +sub2sha1=$(cd clone3/sub2 && git rev-parse HEAD) +sub3sha1=$(cd clone3/sub3 && git rev-parse HEAD) + +cat > expect < ../actual + ) && + test_cmp expect actual +' + test_done -- cgit v1.3 From 1414e5788b85787a712a30977b388200f1bc04da Mon Sep 17 00:00:00 2001 From: Jens Lehmann Date: Tue, 22 Sep 2009 17:10:12 +0200 Subject: git submodule add: make the parameter optional When is not given, use the "humanish" part of the source repository instead. Signed-off-by: Jens Lehmann Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 8 ++++++-- git-submodule.sh | 7 ++++++- t/t7400-submodule-basic.sh | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 5ccdd18c89..4ef70c42eb 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git submodule' [--quiet] add [-b branch] - [--reference ] [--] + [--reference ] [--] [] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [...] 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] @@ -69,7 +69,11 @@ add:: to the changeset to be committed next to the current project: the current project is termed the "superproject". + -This requires two arguments: and . +This requires at least one argument: . The optional +argument is the relative location for the cloned submodule +to exist in the superproject. If is not given, the +"humanish" part of the source repository is used ("repo" for +"/path/to/repo.git" and "foo" for "host.xz:foo/.git"). + is the URL of the new submodule's origin repository. This may be either an absolute URL, or (if it begins with ./ diff --git a/git-submodule.sh b/git-submodule.sh index bfbd36b6f4..0c617eb40d 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -5,7 +5,7 @@ # Copyright (c) 2007 Lars Hjemli dashless=$(basename "$0" | sed -e 's/-/ /') -USAGE="[--quiet] add [-b branch] [--reference ] [--] +USAGE="[--quiet] add [-b branch] [--reference ] [--] [] or: $dashless [--quiet] status [--cached] [--recursive] [--] [...] or: $dashless [--quiet] init [--] [...] or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] @@ -160,6 +160,11 @@ cmd_add() repo=$1 path=$2 + if test -z "$path"; then + path=$(echo "$repo" | + sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g') + fi + if test -z "$repo" -o -z "$path"; then usage fi diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 0f2ccc6cf0..a0cc99ab9f 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -306,4 +306,20 @@ test_expect_success 'submodule warns' ' ' +test_expect_success 'add submodules without specifying an explicit path' ' + mkdir repo && + cd repo && + git init && + echo r >r && + git add r && + git commit -m "repo commit 1" && + cd .. && + git clone --bare repo/ bare.git && + cd addtest && + git submodule add "$submodurl/repo" && + git config -f .gitmodules submodule.repo.path repo && + git submodule add "$submodurl/bare.git" && + git config -f .gitmodules submodule.bare.path bare +' + test_done -- cgit v1.3 From 0484682ef326db0d3b99e71f6ca4551d0f5a4609 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Tue, 29 Sep 2009 07:42:25 +0200 Subject: typo fix: Directory `...' exist, ...: s/exist/exists/ Signed-off-by: Jim Meyering Signed-off-by: Shawn O. Pearce --- git-submodule.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index bfbd36b6f4..0462e529d9 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -98,7 +98,7 @@ module_clone() if test -d "$path" then rmdir "$path" 2>/dev/null || - die "Directory '$path' exist, but is neither empty nor a git repository" + die "Directory '$path' exists, but is neither empty nor a git repository" fi test -e "$path" && -- cgit v1.3 From e1622bfcbad680225ad5c337e4778df88389227e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 23 Nov 2009 15:56:32 -0800 Subject: Protect scripted Porcelains from GREP_OPTIONS insanity If the user has exported the GREP_OPTIONS environment variable, the output from "grep" and "egrep" in scripted Porcelains may be different from what they expect. For example, we may want to count number of matching lines, by "grep" piped to "wc -l", and GREP_OPTIONS=-C3 will break such use. The approach taken by this change to address this issue is to protect only our own use of grep/egrep. Because we do not unset it at the beginning of our scripts, hook scripts run from the scripted Porcelains are exposed to the same insanity this environment variable causes when grep/egrep is used to implement logic (e.g. "grep | wc -l"), and it is entirely up to the hook scripts to protect themselves. On the other hand, applypatch-msg hook may want to show offending words in the proposed commit log message using grep to the end user, and the user might want to set GREP_OPTIONS=--color to paint the match more visibly. The approach to protect only our own use without unsetting the environment variable globally will allow this use case. Signed-off-by: Junio C Hamano --- git-am.sh | 4 ++-- git-bisect.sh | 4 ++-- git-filter-branch.sh | 2 +- git-instaweb.sh | 8 ++++---- git-rebase--interactive.sh | 10 +++++----- git-rebase.sh | 2 +- git-sh-setup.sh | 8 ++++++++ git-submodule.sh | 6 +++--- 8 files changed, 26 insertions(+), 18 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-am.sh b/git-am.sh index c132f50da5..b49f26a49c 100755 --- a/git-am.sh +++ b/git-am.sh @@ -205,7 +205,7 @@ check_patch_format () { # and see if it looks like that they all begin with the # header field names... sed -n -e '/^$/q' -e '/^[ ]/d' -e p "$1" | - LC_ALL=C egrep -v '^[!-9;-~]+:' >/dev/null || + sane_egrep -v '^[!-9;-~]+:' >/dev/null || patch_format=mbox fi } < "$1" || clean_abort @@ -554,7 +554,7 @@ do stop_here $this # skip pine's internal folder data - grep '^Author: Mail System Internal Data$' \ + sane_grep '^Author: Mail System Internal Data$' \ <"$dotest"/info >/dev/null && go_next && continue diff --git a/git-bisect.sh b/git-bisect.sh index 6f6f03966f..0c422d5fb5 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -393,7 +393,7 @@ bisect_run () { cat "$GIT_DIR/BISECT_RUN" - if grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \ + if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \ > /dev/null; then echo >&2 "bisect run cannot continue any more" exit $res @@ -405,7 +405,7 @@ bisect_run () { exit $res fi - if grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then + if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then echo "bisect run success" exit 0; fi diff --git a/git-filter-branch.sh b/git-filter-branch.sh index a480d6fc70..8ef1bde710 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -457,7 +457,7 @@ if [ "$filter_tag_name" ]; then git mktag) || die "Could not create new tag object for $ref" if git cat-file tag "$ref" | \ - grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1 + sane_grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1 then warn "gpg signature stripped from tag object $sha1t" fi diff --git a/git-instaweb.sh b/git-instaweb.sh index d96eddbe56..84805c61e5 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -41,7 +41,7 @@ resolve_full_httpd () { case "$httpd" in *apache2*|*lighttpd*) # ensure that the apache2/lighttpd command ends with "-f" - if ! echo "$httpd" | grep -- '-f *$' >/dev/null 2>&1 + if ! echo "$httpd" | sane_grep -- '-f *$' >/dev/null 2>&1 then httpd="$httpd -f" fi @@ -297,8 +297,8 @@ EOF # check to see if Dennis Stosberg's mod_perl compatibility patch # (<20060621130708.Gcbc6e5c@leonov.stosberg.net>) has been applied - if test -f "$module_path/mod_perl.so" && grep 'MOD_PERL' \ - "$GIT_DIR/gitweb/gitweb.cgi" >/dev/null + if test -f "$module_path/mod_perl.so" && + sane_grep 'MOD_PERL' "$GIT_DIR/gitweb/gitweb.cgi" >/dev/null then # favor mod_perl if available cat >> "$conf" </dev/null 2>&1 || \ + $list_mods | sane_grep 'mod_cgi\.c' >/dev/null 2>&1 || \ echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf" cat >> "$conf" <> "$DONE" sed -e 1d < "$TODO" >> "$TODO".new mv -f "$TODO".new "$TODO" - count=$(grep -c '^[^#]' < "$DONE") - total=$(($count+$(grep -c '^[^#]' < "$TODO"))) + count=$(sane_grep -c '^[^#]' < "$DONE") + total=$(($count+$(sane_grep -c '^[^#]' < "$TODO"))) if test "$last_count" != "$count" then last_count=$count @@ -147,7 +147,7 @@ die_abort () { } has_action () { - grep '^[^#]' "$1" >/dev/null + sane_grep '^[^#]' "$1" >/dev/null } pick_one () { @@ -731,7 +731,7 @@ first and then run 'git rebase --continue' again." git rev-list $REVISIONS | while read rev do - if test -f "$REWRITTEN"/$rev -a "$(grep "$rev" "$DOTEST"/not-cherry-picks)" = "" + if test -f "$REWRITTEN"/$rev -a "$(sane_grep "$rev" "$DOTEST"/not-cherry-picks)" = "" then # Use -f2 because if rev-list is telling us this commit is # not worthwhile, we don't want to track its multiple heads, @@ -739,7 +739,7 @@ first and then run 'git rebase --continue' again." # be rebasing on top of it git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$DROPPED"/$rev short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev) - grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO" + sane_grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO" rm "$REWRITTEN"/$rev fi done diff --git a/git-rebase.sh b/git-rebase.sh index 6ec155cf03..0ec435558f 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -467,7 +467,7 @@ orig_head=$branch mb=$(git merge-base "$onto" "$branch") if test "$upstream" = "$onto" && test "$mb" = "$onto" && # linear history? - ! (git rev-list --parents "$onto".."$branch" | grep " .* ") > /dev/null + ! (git rev-list --parents "$onto".."$branch" | sane_grep " .* ") > /dev/null then if test -z "$force_rebase" then diff --git a/git-sh-setup.sh b/git-sh-setup.sh index c41c2f7439..aa07cc3d18 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -114,6 +114,14 @@ git_editor() { eval "${GIT_EDITOR:=vi}" '"$@"' } +sane_grep () { + GREP_OPTIONS= LC_ALL=C grep "$@" +} + +sane_egrep () { + GREP_OPTIONS= LC_ALL=C egrep "$@" +} + is_bare_repository () { git rev-parse --is-bare-repository } diff --git a/git-submodule.sh b/git-submodule.sh index 0462e529d9..b7ccd12d72 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -57,7 +57,7 @@ resolve_relative_url () # module_list() { - git ls-files --error-unmatch --stage -- "$@" | grep '^160000 ' + git ls-files --error-unmatch --stage -- "$@" | sane_grep '^160000 ' } # @@ -567,7 +567,7 @@ cmd_summary() { cd_to_toplevel # Get modified modules cared by user modules=$(git $diff_cmd $cached --raw $head -- "$@" | - egrep '^:([0-7]* )?160000' | + sane_egrep '^:([0-7]* )?160000' | while read mod_src mod_dst sha1_src sha1_dst status name do # Always show modules deleted or type-changed (blob<->module) @@ -581,7 +581,7 @@ cmd_summary() { test -z "$modules" && return git $diff_cmd $cached --raw $head -- $modules | - egrep '^:([0-7]* )?160000' | + sane_egrep '^:([0-7]* )?160000' | cut -c2- | while read mod_src mod_dst sha1_src sha1_dst status name do -- cgit v1.3 From f17a5d34948363087db94a1cb2c3c715c1ada2d8 Mon Sep 17 00:00:00 2001 From: Jens Lehmann Date: Sun, 17 Jan 2010 20:42:31 +0100 Subject: git status: Show uncommitted submodule changes too when enabled When the configuration variable status.submodulesummary is not 0 or false, "git status" shows the submodule summary of the staged submodule commits. But it did not show the summary of those commits not yet staged in the supermodule, making it hard to see what will not be committed. The output of "submodule summary --for-status" has been changed from "# Modified submodules:" to "# Submodule changes to be committed:" for the already staged changes. "# Submodules changed but not updated:" has been added for changes that will not be committed. This is much clearer and consistent with the output for regular files. Signed-off-by: Jens Lehmann Signed-off-by: Junio C Hamano --- git-submodule.sh | 6 +++++- t/t7401-submodule-summary.sh | 2 +- t/t7508-status.sh | 4 ++-- wt-status.c | 12 +++++++----- 4 files changed, 15 insertions(+), 9 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 77d223292c..664f21721c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -688,7 +688,11 @@ cmd_summary() { echo done | if test -n "$for_status"; then - echo "# Modified submodules:" + if [ -n "$files" ]; then + echo "# Submodules changed but not updated:" + else + echo "# Submodule changes to be committed:" + fi echo "#" sed -e 's|^|# |' -e 's|^# $|#|' else diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 6cc16c39fe..d3c039f724 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -213,7 +213,7 @@ EOF test_expect_success '--for-status' " git submodule summary --for-status HEAD^ >actual && test_cmp actual - <expect < Add foo @@ -672,7 +672,7 @@ cat >expect < Add foo diff --git a/wt-status.c b/wt-status.c index 5d56988016..deaac93d17 100644 --- a/wt-status.c +++ b/wt-status.c @@ -459,7 +459,7 @@ static void wt_status_print_changed(struct wt_status *s) wt_status_print_trailer(s); } -static void wt_status_print_submodule_summary(struct wt_status *s) +static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitted) { struct child_process sm_summary; char summary_limit[64]; @@ -468,11 +468,11 @@ static void wt_status_print_submodule_summary(struct wt_status *s) const char *argv[] = { "submodule", "summary", - "--cached", + uncommitted ? "--files" : "--cached", "--for-status", "--summary-limit", summary_limit, - s->amend ? "HEAD^" : "HEAD", + uncommitted ? NULL : (s->amend ? "HEAD^" : "HEAD"), NULL }; @@ -580,8 +580,10 @@ void wt_status_print(struct wt_status *s) wt_status_print_updated(s); wt_status_print_unmerged(s); wt_status_print_changed(s); - if (s->submodule_summary) - wt_status_print_submodule_summary(s); + if (s->submodule_summary) { + wt_status_print_submodule_summary(s, 0); /* staged */ + wt_status_print_submodule_summary(s, 1); /* unstaged */ + } if (s->show_untracked_files) wt_status_print_untracked(s); else if (s->commitable) -- cgit v1.3