git-submodule.shon commit Merge branch 'rs/tar-tests' into maint (afebd68)
   1#!/bin/sh
   2#
   3# git-submodule.sh: add, init, update or list git submodules
   4#
   5# Copyright (c) 2007 Lars Hjemli
   6
   7dashless=$(basename "$0" | sed -e 's/-/ /')
   8USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
   9   or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
  10   or: $dashless [--quiet] init [--] [<path>...]
  11   or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
  12   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
  13   or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
  14   or: $dashless [--quiet] foreach [--recursive] <command>
  15   or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
  16OPTIONS_SPEC=
  17. git-sh-setup
  18. git-sh-i18n
  19. git-parse-remote
  20require_work_tree
  21
  22command=
  23branch=
  24force=
  25reference=
  26cached=
  27recursive=
  28init=
  29files=
  30remote=
  31nofetch=
  32update=
  33prefix=
  34custom_name=
  35
  36# The function takes at most 2 arguments. The first argument is the
  37# URL that navigates to the submodule origin repo. When relative, this URL
  38# is relative to the superproject origin URL repo. The second up_path
  39# argument, if specified, is the relative path that navigates
  40# from the submodule working tree to the superproject working tree.
  41#
  42# The output of the function is the origin URL of the submodule.
  43#
  44# The output will either be an absolute URL or filesystem path (if the
  45# superproject origin URL is an absolute URL or filesystem path,
  46# respectively) or a relative file system path (if the superproject
  47# origin URL is a relative file system path).
  48#
  49# When the output is a relative file system path, the path is either
  50# relative to the submodule working tree, if up_path is specified, or to
  51# the superproject working tree otherwise.
  52resolve_relative_url ()
  53{
  54        remote=$(get_default_remote)
  55        remoteurl=$(git config "remote.$remote.url") ||
  56                remoteurl=$(pwd) # the repository is its own authoritative upstream
  57        url="$1"
  58        remoteurl=${remoteurl%/}
  59        sep=/
  60        up_path="$2"
  61
  62        case "$remoteurl" in
  63        *:*|/*)
  64                is_relative=
  65                ;;
  66        ./*|../*)
  67                is_relative=t
  68                ;;
  69        *)
  70                is_relative=t
  71                remoteurl="./$remoteurl"
  72                ;;
  73        esac
  74
  75        while test -n "$url"
  76        do
  77                case "$url" in
  78                ../*)
  79                        url="${url#../}"
  80                        case "$remoteurl" in
  81                        */*)
  82                                remoteurl="${remoteurl%/*}"
  83                                ;;
  84                        *:*)
  85                                remoteurl="${remoteurl%:*}"
  86                                sep=:
  87                                ;;
  88                        *)
  89                                if test -z "$is_relative" || test "." = "$remoteurl"
  90                                then
  91                                        die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
  92                                else
  93                                        remoteurl=.
  94                                fi
  95                                ;;
  96                        esac
  97                        ;;
  98                ./*)
  99                        url="${url#./}"
 100                        ;;
 101                *)
 102                        break;;
 103                esac
 104        done
 105        remoteurl="$remoteurl$sep${url%/}"
 106        echo "${is_relative:+${up_path}}${remoteurl#./}"
 107}
 108
 109#
 110# Get submodule info for registered submodules
 111# $@ = path to limit submodule list
 112#
 113module_list()
 114{
 115        (
 116                git ls-files -z --error-unmatch --stage -- "$@" ||
 117                echo "unmatched pathspec exists"
 118        ) |
 119        perl -e '
 120        my %unmerged = ();
 121        my ($null_sha1) = ("0" x 40);
 122        my @out = ();
 123        my $unmatched = 0;
 124        $/ = "\0";
 125        while (<STDIN>) {
 126                if (/^unmatched pathspec/) {
 127                        $unmatched = 1;
 128                        next;
 129                }
 130                chomp;
 131                my ($mode, $sha1, $stage, $path) =
 132                        /^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
 133                next unless $mode eq "160000";
 134                if ($stage ne "0") {
 135                        if (!$unmerged{$path}++) {
 136                                push @out, "$mode $null_sha1 U\t$path\n";
 137                        }
 138                        next;
 139                }
 140                push @out, "$_\n";
 141        }
 142        if ($unmatched) {
 143                print "#unmatched\n";
 144        } else {
 145                print for (@out);
 146        }
 147        '
 148}
 149
 150die_if_unmatched ()
 151{
 152        if test "$1" = "#unmatched"
 153        then
 154                exit 1
 155        fi
 156}
 157
 158#
 159# Print a submodule configuration setting
 160#
 161# $1 = submodule name
 162# $2 = option name
 163# $3 = default value
 164#
 165# Checks in the usual git-config places first (for overrides),
 166# otherwise it falls back on .gitmodules.  This allows you to
 167# distribute project-wide defaults in .gitmodules, while still
 168# customizing individual repositories if necessary.  If the option is
 169# not in .gitmodules either, print a default value.
 170#
 171get_submodule_config () {
 172        name="$1"
 173        option="$2"
 174        default="$3"
 175        value=$(git config submodule."$name"."$option")
 176        if test -z "$value"
 177        then
 178                value=$(git config -f .gitmodules submodule."$name"."$option")
 179        fi
 180        printf '%s' "${value:-$default}"
 181}
 182
 183
 184#
 185# Map submodule path to submodule name
 186#
 187# $1 = path
 188#
 189module_name()
 190{
 191        # Do we have "submodule.<something>.path = $1" defined in .gitmodules file?
 192        sm_path="$1"
 193        re=$(printf '%s\n' "$1" | sed -e 's/[].[^$\\*]/\\&/g')
 194        name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
 195                sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
 196        test -z "$name" &&
 197        die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$sm_path'")"
 198        echo "$name"
 199}
 200
 201#
 202# Clone a submodule
 203#
 204# Prior to calling, cmd_update checks that a possibly existing
 205# path is not a git repository.
 206# Likewise, cmd_add checks that path does not exist at all,
 207# since it is the location of a new submodule.
 208#
 209module_clone()
 210{
 211        sm_path=$1
 212        name=$2
 213        url=$3
 214        reference="$4"
 215        quiet=
 216        if test -n "$GIT_QUIET"
 217        then
 218                quiet=-q
 219        fi
 220
 221        gitdir=
 222        gitdir_base=
 223        base_name=$(dirname "$name")
 224
 225        gitdir=$(git rev-parse --git-dir)
 226        gitdir_base="$gitdir/modules/$base_name"
 227        gitdir="$gitdir/modules/$name"
 228
 229        if test -d "$gitdir"
 230        then
 231                mkdir -p "$sm_path"
 232                rm -f "$gitdir/index"
 233        else
 234                mkdir -p "$gitdir_base"
 235                (
 236                        clear_local_git_env
 237                        git clone $quiet -n ${reference:+"$reference"} \
 238                                --separate-git-dir "$gitdir" "$url" "$sm_path"
 239                ) ||
 240                die "$(eval_gettext "Clone of '\$url' into submodule path '\$sm_path' failed")"
 241        fi
 242
 243        # We already are at the root of the work tree but cd_to_toplevel will
 244        # resolve any symlinks that might be present in $PWD
 245        a=$(cd_to_toplevel && cd "$gitdir" && pwd)/
 246        b=$(cd_to_toplevel && cd "$sm_path" && pwd)/
 247        # normalize Windows-style absolute paths to POSIX-style absolute paths
 248        case $a in [a-zA-Z]:/*) a=/${a%%:*}${a#*:} ;; esac
 249        case $b in [a-zA-Z]:/*) b=/${b%%:*}${b#*:} ;; esac
 250        # Remove all common leading directories after a sanity check
 251        if test "${a#$b}" != "$a" || test "${b#$a}" != "$b"; then
 252                die "$(eval_gettext "Gitdir '\$a' is part of the submodule path '\$b' or vice versa")"
 253        fi
 254        while test "${a%%/*}" = "${b%%/*}"
 255        do
 256                a=${a#*/}
 257                b=${b#*/}
 258        done
 259        # Now chop off the trailing '/'s that were added in the beginning
 260        a=${a%/}
 261        b=${b%/}
 262
 263        # Turn each leading "*/" component into "../"
 264        rel=$(echo $b | sed -e 's|[^/][^/]*|..|g')
 265        echo "gitdir: $rel/$a" >"$sm_path/.git"
 266
 267        rel=$(echo $a | sed -e 's|[^/][^/]*|..|g')
 268        (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b")
 269}
 270
 271isnumber()
 272{
 273        n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
 274}
 275
 276#
 277# Add a new submodule to the working tree, .gitmodules and the index
 278#
 279# $@ = repo path
 280#
 281# optional branch is stored in global branch variable
 282#
 283cmd_add()
 284{
 285        # parse $args after "submodule ... add".
 286        while test $# -ne 0
 287        do
 288                case "$1" in
 289                -b | --branch)
 290                        case "$2" in '') usage ;; esac
 291                        branch=$2
 292                        shift
 293                        ;;
 294                -f | --force)
 295                        force=$1
 296                        ;;
 297                -q|--quiet)
 298                        GIT_QUIET=1
 299                        ;;
 300                --reference)
 301                        case "$2" in '') usage ;; esac
 302                        reference="--reference=$2"
 303                        shift
 304                        ;;
 305                --reference=*)
 306                        reference="$1"
 307                        ;;
 308                --name)
 309                        case "$2" in '') usage ;; esac
 310                        custom_name=$2
 311                        shift
 312                        ;;
 313                --)
 314                        shift
 315                        break
 316                        ;;
 317                -*)
 318                        usage
 319                        ;;
 320                *)
 321                        break
 322                        ;;
 323                esac
 324                shift
 325        done
 326
 327        repo=$1
 328        sm_path=$2
 329
 330        if test -z "$sm_path"; then
 331                sm_path=$(echo "$repo" |
 332                        sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
 333        fi
 334
 335        if test -z "$repo" -o -z "$sm_path"; then
 336                usage
 337        fi
 338
 339        # assure repo is absolute or relative to parent
 340        case "$repo" in
 341        ./*|../*)
 342                # dereference source url relative to parent's url
 343                realrepo=$(resolve_relative_url "$repo") || exit
 344                ;;
 345        *:*|/*)
 346                # absolute url
 347                realrepo=$repo
 348                ;;
 349        *)
 350                die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
 351        ;;
 352        esac
 353
 354        # normalize path:
 355        # multiple //; leading ./; /./; /../; trailing /
 356        sm_path=$(printf '%s/\n' "$sm_path" |
 357                sed -e '
 358                        s|//*|/|g
 359                        s|^\(\./\)*||
 360                        s|/\./|/|g
 361                        :start
 362                        s|\([^/]*\)/\.\./||
 363                        tstart
 364                        s|/*$||
 365                ')
 366        git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
 367        die "$(eval_gettext "'\$sm_path' already exists in the index")"
 368
 369        if test -z "$force" && ! git add --dry-run --ignore-missing "$sm_path" > /dev/null 2>&1
 370        then
 371                eval_gettextln "The following path is ignored by one of your .gitignore files:
 372\$sm_path
 373Use -f if you really want to add it." >&2
 374                exit 1
 375        fi
 376
 377        if test -n "$custom_name"
 378        then
 379                sm_name="$custom_name"
 380        else
 381                sm_name="$sm_path"
 382        fi
 383
 384        # perhaps the path exists and is already a git repo, else clone it
 385        if test -e "$sm_path"
 386        then
 387                if test -d "$sm_path"/.git -o -f "$sm_path"/.git
 388                then
 389                        eval_gettextln "Adding existing repo at '\$sm_path' to the index"
 390                else
 391                        die "$(eval_gettext "'\$sm_path' already exists and is not a valid git repo")"
 392                fi
 393
 394        else
 395                if test -d ".git/modules/$sm_name"
 396                then
 397                        if test -z "$force"
 398                        then
 399                                echo >&2 "$(eval_gettext "A git directory for '\$sm_name' is found locally with remote(s):")"
 400                                GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^,"  ", -e s,' (fetch)',, >&2
 401                                echo >&2 "$(eval_gettext "If you want to reuse this local git directory instead of cloning again from")"
 402                                echo >&2 "  $realrepo"
 403                                echo >&2 "$(eval_gettext "use the '--force' option. If the local git directory is not the correct repo")"
 404                                die "$(eval_gettext "or you are unsure what this means choose another name with the '--name' option.")"
 405                        else
 406                                echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")"
 407                        fi
 408                fi
 409                module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" || exit
 410                (
 411                        clear_local_git_env
 412                        cd "$sm_path" &&
 413                        # ash fails to wordsplit ${branch:+-b "$branch"...}
 414                        case "$branch" in
 415                        '') git checkout -f -q ;;
 416                        ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
 417                        esac
 418                ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
 419        fi
 420        git config submodule."$sm_name".url "$realrepo"
 421
 422        git add $force "$sm_path" ||
 423        die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
 424
 425        git config -f .gitmodules submodule."$sm_name".path "$sm_path" &&
 426        git config -f .gitmodules submodule."$sm_name".url "$repo" &&
 427        if test -n "$branch"
 428        then
 429                git config -f .gitmodules submodule."$sm_name".branch "$branch"
 430        fi &&
 431        git add --force .gitmodules ||
 432        die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
 433}
 434
 435#
 436# Execute an arbitrary command sequence in each checked out
 437# submodule
 438#
 439# $@ = command to execute
 440#
 441cmd_foreach()
 442{
 443        # parse $args after "submodule ... foreach".
 444        while test $# -ne 0
 445        do
 446                case "$1" in
 447                -q|--quiet)
 448                        GIT_QUIET=1
 449                        ;;
 450                --recursive)
 451                        recursive=1
 452                        ;;
 453                -*)
 454                        usage
 455                        ;;
 456                *)
 457                        break
 458                        ;;
 459                esac
 460                shift
 461        done
 462
 463        toplevel=$(pwd)
 464
 465        # dup stdin so that it can be restored when running the external
 466        # command in the subshell (and a recursive call to this function)
 467        exec 3<&0
 468
 469        module_list |
 470        while read mode sha1 stage sm_path
 471        do
 472                die_if_unmatched "$mode"
 473                if test -e "$sm_path"/.git
 474                then
 475                        say "$(eval_gettext "Entering '\$prefix\$sm_path'")"
 476                        name=$(module_name "$sm_path")
 477                        (
 478                                prefix="$prefix$sm_path/"
 479                                clear_local_git_env
 480                                # we make $path available to scripts ...
 481                                path=$sm_path
 482                                cd "$sm_path" &&
 483                                eval "$@" &&
 484                                if test -n "$recursive"
 485                                then
 486                                        cmd_foreach "--recursive" "$@"
 487                                fi
 488                        ) <&3 3<&- ||
 489                        die "$(eval_gettext "Stopping at '\$sm_path'; script returned non-zero status.")"
 490                fi
 491        done
 492}
 493
 494#
 495# Register submodules in .git/config
 496#
 497# $@ = requested paths (default to all)
 498#
 499cmd_init()
 500{
 501        # parse $args after "submodule ... init".
 502        while test $# -ne 0
 503        do
 504                case "$1" in
 505                -q|--quiet)
 506                        GIT_QUIET=1
 507                        ;;
 508                --)
 509                        shift
 510                        break
 511                        ;;
 512                -*)
 513                        usage
 514                        ;;
 515                *)
 516                        break
 517                        ;;
 518                esac
 519                shift
 520        done
 521
 522        module_list "$@" |
 523        while read mode sha1 stage sm_path
 524        do
 525                die_if_unmatched "$mode"
 526                name=$(module_name "$sm_path") || exit
 527
 528                # Copy url setting when it is not set yet
 529                if test -z "$(git config "submodule.$name.url")"
 530                then
 531                        url=$(git config -f .gitmodules submodule."$name".url)
 532                        test -z "$url" &&
 533                        die "$(eval_gettext "No url found for submodule path '\$sm_path' in .gitmodules")"
 534
 535                        # Possibly a url relative to parent
 536                        case "$url" in
 537                        ./*|../*)
 538                                url=$(resolve_relative_url "$url") || exit
 539                                ;;
 540                        esac
 541                        git config submodule."$name".url "$url" ||
 542                        die "$(eval_gettext "Failed to register url for submodule path '\$sm_path'")"
 543
 544                        say "$(eval_gettext "Submodule '\$name' (\$url) registered for path '\$sm_path'")"
 545                fi
 546
 547                # Copy "update" setting when it is not set yet
 548                upd="$(git config -f .gitmodules submodule."$name".update)"
 549                test -z "$upd" ||
 550                test -n "$(git config submodule."$name".update)" ||
 551                git config submodule."$name".update "$upd" ||
 552                die "$(eval_gettext "Failed to register update mode for submodule path '\$sm_path'")"
 553        done
 554}
 555
 556#
 557# Unregister submodules from .git/config and remove their work tree
 558#
 559# $@ = requested paths (use '.' to deinit all submodules)
 560#
 561cmd_deinit()
 562{
 563        # parse $args after "submodule ... deinit".
 564        while test $# -ne 0
 565        do
 566                case "$1" in
 567                -f|--force)
 568                        force=$1
 569                        ;;
 570                -q|--quiet)
 571                        GIT_QUIET=1
 572                        ;;
 573                --)
 574                        shift
 575                        break
 576                        ;;
 577                -*)
 578                        usage
 579                        ;;
 580                *)
 581                        break
 582                        ;;
 583                esac
 584                shift
 585        done
 586
 587        if test $# = 0
 588        then
 589                die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")"
 590        fi
 591
 592        module_list "$@" |
 593        while read mode sha1 stage sm_path
 594        do
 595                die_if_unmatched "$mode"
 596                name=$(module_name "$sm_path") || exit
 597
 598                # Remove the submodule work tree (unless the user already did it)
 599                if test -d "$sm_path"
 600                then
 601                        # Protect submodules containing a .git directory
 602                        if test -d "$sm_path/.git"
 603                        then
 604                                echo >&2 "$(eval_gettext "Submodule work tree '\$sm_path' contains a .git directory")"
 605                                die "$(eval_gettext "(use 'rm -rf' if you really want to remove it including all of its history)")"
 606                        fi
 607
 608                        if test -z "$force"
 609                        then
 610                                git rm -qn "$sm_path" ||
 611                                die "$(eval_gettext "Submodule work tree '\$sm_path' contains local modifications; use '-f' to discard them")"
 612                        fi
 613                        rm -rf "$sm_path" &&
 614                        say "$(eval_gettext "Cleared directory '\$sm_path'")" ||
 615                        say "$(eval_gettext "Could not remove submodule work tree '\$sm_path'")"
 616                fi
 617
 618                mkdir "$sm_path" || say "$(eval_gettext "Could not create empty submodule directory '\$sm_path'")"
 619
 620                # Remove the .git/config entries (unless the user already did it)
 621                if test -n "$(git config --get-regexp submodule."$name\.")"
 622                then
 623                        # Remove the whole section so we have a clean state when
 624                        # the user later decides to init this submodule again
 625                        url=$(git config submodule."$name".url)
 626                        git config --remove-section submodule."$name" 2>/dev/null &&
 627                        say "$(eval_gettext "Submodule '\$name' (\$url) unregistered for path '\$sm_path'")"
 628                fi
 629        done
 630}
 631
 632#
 633# Update each submodule path to correct revision, using clone and checkout as needed
 634#
 635# $@ = requested paths (default to all)
 636#
 637cmd_update()
 638{
 639        # parse $args after "submodule ... update".
 640        orig_flags=
 641        while test $# -ne 0
 642        do
 643                case "$1" in
 644                -q|--quiet)
 645                        GIT_QUIET=1
 646                        ;;
 647                -i|--init)
 648                        init=1
 649                        ;;
 650                --remote)
 651                        remote=1
 652                        ;;
 653                -N|--no-fetch)
 654                        nofetch=1
 655                        ;;
 656                -f|--force)
 657                        force=$1
 658                        ;;
 659                -r|--rebase)
 660                        update="rebase"
 661                        ;;
 662                --reference)
 663                        case "$2" in '') usage ;; esac
 664                        reference="--reference=$2"
 665                        orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 666                        shift
 667                        ;;
 668                --reference=*)
 669                        reference="$1"
 670                        ;;
 671                -m|--merge)
 672                        update="merge"
 673                        ;;
 674                --recursive)
 675                        recursive=1
 676                        ;;
 677                --checkout)
 678                        update="checkout"
 679                        ;;
 680                --)
 681                        shift
 682                        break
 683                        ;;
 684                -*)
 685                        usage
 686                        ;;
 687                *)
 688                        break
 689                        ;;
 690                esac
 691                orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 692                shift
 693        done
 694
 695        if test -n "$init"
 696        then
 697                cmd_init "--" "$@" || return
 698        fi
 699
 700        cloned_modules=
 701        module_list "$@" | {
 702        err=
 703        while read mode sha1 stage sm_path
 704        do
 705                die_if_unmatched "$mode"
 706                if test "$stage" = U
 707                then
 708                        echo >&2 "Skipping unmerged submodule $prefix$sm_path"
 709                        continue
 710                fi
 711                name=$(module_name "$sm_path") || exit
 712                url=$(git config submodule."$name".url)
 713                branch=$(get_submodule_config "$name" branch master)
 714                if ! test -z "$update"
 715                then
 716                        update_module=$update
 717                else
 718                        update_module=$(git config submodule."$name".update)
 719                fi
 720
 721                if test "$update_module" = "none"
 722                then
 723                        echo "Skipping submodule '$prefix$sm_path'"
 724                        continue
 725                fi
 726
 727                if test -z "$url"
 728                then
 729                        # Only mention uninitialized submodules when its
 730                        # path have been specified
 731                        test "$#" != "0" &&
 732                        say "$(eval_gettext "Submodule path '\$prefix\$sm_path' not initialized
 733Maybe you want to use 'update --init'?")"
 734                        continue
 735                fi
 736
 737                if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git
 738                then
 739                        module_clone "$sm_path" "$name" "$url" "$reference" || exit
 740                        cloned_modules="$cloned_modules;$name"
 741                        subsha1=
 742                else
 743                        subsha1=$(clear_local_git_env; cd "$sm_path" &&
 744                                git rev-parse --verify HEAD) ||
 745                        die "$(eval_gettext "Unable to find current revision in submodule path '\$prefix\$sm_path'")"
 746                fi
 747
 748                if test -n "$remote"
 749                then
 750                        if test -z "$nofetch"
 751                        then
 752                                # Fetch remote before determining tracking $sha1
 753                                (clear_local_git_env; cd "$sm_path" && git-fetch) ||
 754                                die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
 755                        fi
 756                        remote_name=$(clear_local_git_env; cd "$sm_path" && get_default_remote)
 757                        sha1=$(clear_local_git_env; cd "$sm_path" &&
 758                                git rev-parse --verify "${remote_name}/${branch}") ||
 759                        die "$(eval_gettext "Unable to find current ${remote_name}/${branch} revision in submodule path '\$sm_path'")"
 760                fi
 761
 762                if test "$subsha1" != "$sha1" -o -n "$force"
 763                then
 764                        subforce=$force
 765                        # If we don't already have a -f flag and the submodule has never been checked out
 766                        if test -z "$subsha1" -a -z "$force"
 767                        then
 768                                subforce="-f"
 769                        fi
 770
 771                        if test -z "$nofetch"
 772                        then
 773                                # Run fetch only if $sha1 isn't present or it
 774                                # is not reachable from a ref.
 775                                (clear_local_git_env; cd "$sm_path" &&
 776                                        ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
 777                                         test -z "$rev") || git-fetch)) ||
 778                                die "$(eval_gettext "Unable to fetch in submodule path '\$prefix\$sm_path'")"
 779                        fi
 780
 781                        # Is this something we just cloned?
 782                        case ";$cloned_modules;" in
 783                        *";$name;"*)
 784                                # then there is no local change to integrate
 785                                update_module= ;;
 786                        esac
 787
 788                        must_die_on_failure=
 789                        case "$update_module" in
 790                        rebase)
 791                                command="git rebase"
 792                                die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$prefix\$sm_path'")"
 793                                say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': rebased into '\$sha1'")"
 794                                must_die_on_failure=yes
 795                                ;;
 796                        merge)
 797                                command="git merge"
 798                                die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$prefix\$sm_path'")"
 799                                say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': merged in '\$sha1'")"
 800                                must_die_on_failure=yes
 801                                ;;
 802                        *)
 803                                command="git checkout $subforce -q"
 804                                die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$prefix\$sm_path'")"
 805                                say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': checked out '\$sha1'")"
 806                                ;;
 807                        esac
 808
 809                        if (clear_local_git_env; cd "$sm_path" && $command "$sha1")
 810                        then
 811                                say "$say_msg"
 812                        elif test -n "$must_die_on_failure"
 813                        then
 814                                die_with_status 2 "$die_msg"
 815                        else
 816                                err="${err};$die_msg"
 817                                continue
 818                        fi
 819                fi
 820
 821                if test -n "$recursive"
 822                then
 823                        (
 824                                prefix="$prefix$sm_path/"
 825                                clear_local_git_env
 826                                cd "$sm_path" &&
 827                                eval cmd_update "$orig_flags"
 828                        )
 829                        res=$?
 830                        if test $res -gt 0
 831                        then
 832                                die_msg="$(eval_gettext "Failed to recurse into submodule path '\$prefix\$sm_path'")"
 833                                if test $res -eq 1
 834                                then
 835                                        err="${err};$die_msg"
 836                                        continue
 837                                else
 838                                        die_with_status $res "$die_msg"
 839                                fi
 840                        fi
 841                fi
 842        done
 843
 844        if test -n "$err"
 845        then
 846                OIFS=$IFS
 847                IFS=';'
 848                for e in $err
 849                do
 850                        if test -n "$e"
 851                        then
 852                                echo >&2 "$e"
 853                        fi
 854                done
 855                IFS=$OIFS
 856                exit 1
 857        fi
 858        }
 859}
 860
 861set_name_rev () {
 862        revname=$( (
 863                clear_local_git_env
 864                cd "$1" && {
 865                        git describe "$2" 2>/dev/null ||
 866                        git describe --tags "$2" 2>/dev/null ||
 867                        git describe --contains "$2" 2>/dev/null ||
 868                        git describe --all --always "$2"
 869                }
 870        ) )
 871        test -z "$revname" || revname=" ($revname)"
 872}
 873#
 874# Show commit summary for submodules in index or working tree
 875#
 876# If '--cached' is given, show summary between index and given commit,
 877# or between working tree and given commit
 878#
 879# $@ = [commit (default 'HEAD'),] requested paths (default all)
 880#
 881cmd_summary() {
 882        summary_limit=-1
 883        for_status=
 884        diff_cmd=diff-index
 885
 886        # parse $args after "submodule ... summary".
 887        while test $# -ne 0
 888        do
 889                case "$1" in
 890                --cached)
 891                        cached="$1"
 892                        ;;
 893                --files)
 894                        files="$1"
 895                        ;;
 896                --for-status)
 897                        for_status="$1"
 898                        ;;
 899                -n|--summary-limit)
 900                        summary_limit="$2"
 901                        isnumber "$summary_limit" || usage
 902                        shift
 903                        ;;
 904                --summary-limit=*)
 905                        summary_limit="${1#--summary-limit=}"
 906                        isnumber "$summary_limit" || usage
 907                        ;;
 908                --)
 909                        shift
 910                        break
 911                        ;;
 912                -*)
 913                        usage
 914                        ;;
 915                *)
 916                        break
 917                        ;;
 918                esac
 919                shift
 920        done
 921
 922        test $summary_limit = 0 && return
 923
 924        if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
 925        then
 926                head=$rev
 927                test $# = 0 || shift
 928        elif test -z "$1" -o "$1" = "HEAD"
 929        then
 930                # before the first commit: compare with an empty tree
 931                head=$(git hash-object -w -t tree --stdin </dev/null)
 932                test -z "$1" || shift
 933        else
 934                head="HEAD"
 935        fi
 936
 937        if [ -n "$files" ]
 938        then
 939                test -n "$cached" &&
 940                die "$(gettext "The --cached option cannot be used with the --files option")"
 941                diff_cmd=diff-files
 942                head=
 943        fi
 944
 945        cd_to_toplevel
 946        # Get modified modules cared by user
 947        modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
 948                sane_egrep '^:([0-7]* )?160000' |
 949                while read mod_src mod_dst sha1_src sha1_dst status name
 950                do
 951                        # Always show modules deleted or type-changed (blob<->module)
 952                        test $status = D -o $status = T && echo "$name" && continue
 953                        # Also show added or modified modules which are checked out
 954                        GIT_DIR="$name/.git" git-rev-parse --git-dir >/dev/null 2>&1 &&
 955                        echo "$name"
 956                done
 957        )
 958
 959        test -z "$modules" && return
 960
 961        git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
 962        sane_egrep '^:([0-7]* )?160000' |
 963        cut -c2- |
 964        while read mod_src mod_dst sha1_src sha1_dst status name
 965        do
 966                if test -z "$cached" &&
 967                        test $sha1_dst = 0000000000000000000000000000000000000000
 968                then
 969                        case "$mod_dst" in
 970                        160000)
 971                                sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
 972                                ;;
 973                        100644 | 100755 | 120000)
 974                                sha1_dst=$(git hash-object $name)
 975                                ;;
 976                        000000)
 977                                ;; # removed
 978                        *)
 979                                # unexpected type
 980                                eval_gettextln "unexpected mode \$mod_dst" >&2
 981                                continue ;;
 982                        esac
 983                fi
 984                missing_src=
 985                missing_dst=
 986
 987                test $mod_src = 160000 &&
 988                ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_src^0 >/dev/null &&
 989                missing_src=t
 990
 991                test $mod_dst = 160000 &&
 992                ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_dst^0 >/dev/null &&
 993                missing_dst=t
 994
 995                total_commits=
 996                case "$missing_src,$missing_dst" in
 997                t,)
 998                        errmsg="$(eval_gettext "  Warn: \$name doesn't contain commit \$sha1_src")"
 999                        ;;
1000                ,t)
1001                        errmsg="$(eval_gettext "  Warn: \$name doesn't contain commit \$sha1_dst")"
1002                        ;;
1003                t,t)
1004                        errmsg="$(eval_gettext "  Warn: \$name doesn't contain commits \$sha1_src and \$sha1_dst")"
1005                        ;;
1006                *)
1007                        errmsg=
1008                        total_commits=$(
1009                        if test $mod_src = 160000 -a $mod_dst = 160000
1010                        then
1011                                range="$sha1_src...$sha1_dst"
1012                        elif test $mod_src = 160000
1013                        then
1014                                range=$sha1_src
1015                        else
1016                                range=$sha1_dst
1017                        fi
1018                        GIT_DIR="$name/.git" \
1019                        git rev-list --first-parent $range -- | wc -l
1020                        )
1021                        total_commits=" ($(($total_commits + 0)))"
1022                        ;;
1023                esac
1024
1025                sha1_abbr_src=$(echo $sha1_src | cut -c1-7)
1026                sha1_abbr_dst=$(echo $sha1_dst | cut -c1-7)
1027                if test $status = T
1028                then
1029                        blob="$(gettext "blob")"
1030                        submodule="$(gettext "submodule")"
1031                        if test $mod_dst = 160000
1032                        then
1033                                echo "* $name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
1034                        else
1035                                echo "* $name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
1036                        fi
1037                else
1038                        echo "* $name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
1039                fi
1040                if test -n "$errmsg"
1041                then
1042                        # Don't give error msg for modification whose dst is not submodule
1043                        # i.e. deleted or changed to blob
1044                        test $mod_dst = 160000 && echo "$errmsg"
1045                else
1046                        if test $mod_src = 160000 -a $mod_dst = 160000
1047                        then
1048                                limit=
1049                                test $summary_limit -gt 0 && limit="-$summary_limit"
1050                                GIT_DIR="$name/.git" \
1051                                git log $limit --pretty='format:  %m %s' \
1052                                --first-parent $sha1_src...$sha1_dst
1053                        elif test $mod_dst = 160000
1054                        then
1055                                GIT_DIR="$name/.git" \
1056                                git log --pretty='format:  > %s' -1 $sha1_dst
1057                        else
1058                                GIT_DIR="$name/.git" \
1059                                git log --pretty='format:  < %s' -1 $sha1_src
1060                        fi
1061                        echo
1062                fi
1063                echo
1064        done |
1065        if test -n "$for_status"; then
1066                if [ -n "$files" ]; then
1067                        gettextln "Submodules changed but not updated:" | git stripspace -c
1068                else
1069                        gettextln "Submodule changes to be committed:" | git stripspace -c
1070                fi
1071                printf "\n" | git stripspace -c
1072                git stripspace -c
1073        else
1074                cat
1075        fi
1076}
1077#
1078# List all submodules, prefixed with:
1079#  - submodule not initialized
1080#  + different revision checked out
1081#
1082# If --cached was specified the revision in the index will be printed
1083# instead of the currently checked out revision.
1084#
1085# $@ = requested paths (default to all)
1086#
1087cmd_status()
1088{
1089        # parse $args after "submodule ... status".
1090        while test $# -ne 0
1091        do
1092                case "$1" in
1093                -q|--quiet)
1094                        GIT_QUIET=1
1095                        ;;
1096                --cached)
1097                        cached=1
1098                        ;;
1099                --recursive)
1100                        recursive=1
1101                        ;;
1102                --)
1103                        shift
1104                        break
1105                        ;;
1106                -*)
1107                        usage
1108                        ;;
1109                *)
1110                        break
1111                        ;;
1112                esac
1113                shift
1114        done
1115
1116        module_list "$@" |
1117        while read mode sha1 stage sm_path
1118        do
1119                die_if_unmatched "$mode"
1120                name=$(module_name "$sm_path") || exit
1121                url=$(git config submodule."$name".url)
1122                displaypath="$prefix$sm_path"
1123                if test "$stage" = U
1124                then
1125                        say "U$sha1 $displaypath"
1126                        continue
1127                fi
1128                if test -z "$url" || ! test -d "$sm_path"/.git -o -f "$sm_path"/.git
1129                then
1130                        say "-$sha1 $displaypath"
1131                        continue;
1132                fi
1133                set_name_rev "$sm_path" "$sha1"
1134                if git diff-files --ignore-submodules=dirty --quiet -- "$sm_path"
1135                then
1136                        say " $sha1 $displaypath$revname"
1137                else
1138                        if test -z "$cached"
1139                        then
1140                                sha1=$(clear_local_git_env; cd "$sm_path" && git rev-parse --verify HEAD)
1141                                set_name_rev "$sm_path" "$sha1"
1142                        fi
1143                        say "+$sha1 $displaypath$revname"
1144                fi
1145
1146                if test -n "$recursive"
1147                then
1148                        (
1149                                prefix="$displaypath/"
1150                                clear_local_git_env
1151                                cd "$sm_path" &&
1152                                eval cmd_status
1153                        ) ||
1154                        die "$(eval_gettext "Failed to recurse into submodule path '\$sm_path'")"
1155                fi
1156        done
1157}
1158#
1159# Sync remote urls for submodules
1160# This makes the value for remote.$remote.url match the value
1161# specified in .gitmodules.
1162#
1163cmd_sync()
1164{
1165        while test $# -ne 0
1166        do
1167                case "$1" in
1168                -q|--quiet)
1169                        GIT_QUIET=1
1170                        shift
1171                        ;;
1172                --recursive)
1173                        recursive=1
1174                        shift
1175                        ;;
1176                --)
1177                        shift
1178                        break
1179                        ;;
1180                -*)
1181                        usage
1182                        ;;
1183                *)
1184                        break
1185                        ;;
1186                esac
1187        done
1188        cd_to_toplevel
1189        module_list "$@" |
1190        while read mode sha1 stage sm_path
1191        do
1192                die_if_unmatched "$mode"
1193                name=$(module_name "$sm_path")
1194                url=$(git config -f .gitmodules --get submodule."$name".url)
1195
1196                # Possibly a url relative to parent
1197                case "$url" in
1198                ./*|../*)
1199                        # rewrite foo/bar as ../.. to find path from
1200                        # submodule work tree to superproject work tree
1201                        up_path="$(echo "$sm_path" | sed "s/[^/][^/]*/../g")" &&
1202                        # guarantee a trailing /
1203                        up_path=${up_path%/}/ &&
1204                        # path from submodule work tree to submodule origin repo
1205                        sub_origin_url=$(resolve_relative_url "$url" "$up_path") &&
1206                        # path from superproject work tree to submodule origin repo
1207                        super_config_url=$(resolve_relative_url "$url") || exit
1208                        ;;
1209                *)
1210                        sub_origin_url="$url"
1211                        super_config_url="$url"
1212                        ;;
1213                esac
1214
1215                if git config "submodule.$name.url" >/dev/null 2>/dev/null
1216                then
1217                        say "$(eval_gettext "Synchronizing submodule url for '\$prefix\$sm_path'")"
1218                        git config submodule."$name".url "$super_config_url"
1219
1220                        if test -e "$sm_path"/.git
1221                        then
1222                        (
1223                                clear_local_git_env
1224                                cd "$sm_path"
1225                                remote=$(get_default_remote)
1226                                git config remote."$remote".url "$sub_origin_url"
1227
1228                                if test -n "$recursive"
1229                                then
1230                                        prefix="$prefix$sm_path/"
1231                                        eval cmd_sync
1232                                fi
1233                        )
1234                        fi
1235                fi
1236        done
1237}
1238
1239# This loop parses the command line arguments to find the
1240# subcommand name to dispatch.  Parsing of the subcommand specific
1241# options are primarily done by the subcommand implementations.
1242# Subcommand specific options such as --branch and --cached are
1243# parsed here as well, for backward compatibility.
1244
1245while test $# != 0 && test -z "$command"
1246do
1247        case "$1" in
1248        add | foreach | init | deinit | update | status | summary | sync)
1249                command=$1
1250                ;;
1251        -q|--quiet)
1252                GIT_QUIET=1
1253                ;;
1254        -b|--branch)
1255                case "$2" in
1256                '')
1257                        usage
1258                        ;;
1259                esac
1260                branch="$2"; shift
1261                ;;
1262        --cached)
1263                cached="$1"
1264                ;;
1265        --)
1266                break
1267                ;;
1268        -*)
1269                usage
1270                ;;
1271        *)
1272                break
1273                ;;
1274        esac
1275        shift
1276done
1277
1278# No command word defaults to "status"
1279if test -z "$command"
1280then
1281    if test $# = 0
1282    then
1283        command=status
1284    else
1285        usage
1286    fi
1287fi
1288
1289# "-b branch" is accepted only by "add"
1290if test -n "$branch" && test "$command" != add
1291then
1292        usage
1293fi
1294
1295# "--cached" is accepted only by "status" and "summary"
1296if test -n "$cached" && test "$command" != status -a "$command" != summary
1297then
1298        usage
1299fi
1300
1301"cmd_$command" "$@"