X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-submodule.sh;h=2f47e065fe8b7ca856f4527d6a507a28f1b2a06b;hb=2cd72b0b290e40fb4d6a925ce26603503f01aa09;hp=97e4d9a1ef9478f54613144e74e9e12314230877;hpb=718258e256b74622aa55f5ee0cb9cff4cce6bf9f;p=git.git diff --git a/git-submodule.sh b/git-submodule.sh index 97e4d9a1e..2f47e065f 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -6,9 +6,10 @@ USAGE="[--quiet] [--cached] \ [add [-b branch] ]|[status|init|update [-i|--init]|summary [-n|--summary-limit ] []] \ -[--] [...]" +[--] [...]|[foreach ]|[sync [--] [...]]" OPTIONS_SPEC= . git-sh-setup +. git-parse-remote require_work_tree command= @@ -30,12 +31,11 @@ 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" + remoteurl=${remoteurl%/} while test -n "$url" do case "$url" in @@ -50,7 +50,16 @@ resolve_relative_url () break;; esac done - echo "$remoteurl/$url" + echo "$remoteurl/${url%/}" +} + +# +# Get submodule info for registered submodules +# $@ = path to limit submodule list +# +module_list() +{ + git ls-files --stage -- "$@" | grep '^160000 ' } # @@ -198,6 +207,26 @@ cmd_add() die "Failed to register submodule '$path'" } +# +# Execute an arbitrary command sequence in each checked out +# submodule +# +# $@ = command to execute +# +cmd_foreach() +{ + module_list | + 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 # @@ -226,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 @@ -284,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 @@ -384,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 @@ -395,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) @@ -409,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 @@ -435,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= @@ -554,7 +583,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 @@ -578,6 +607,58 @@ 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) + + # Possibly a url relative to parent + case "$url" in + ./*|../*) + url=$(resolve_relative_url "$url") || exit + ;; + esac + + 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 @@ -588,7 +669,7 @@ cmd_status() while test $# != 0 && test -z "$command" do case "$1" in - add | init | update | status | summary) + add | foreach | init | update | status | summary | sync) command=$1 ;; -q|--quiet)