Merge branch 'jc/submodule-sync-no-auto-vivify'
authorJunio C Hamano <gitster@pobox.com>
Tue, 19 Jul 2011 16:45:37 +0000 (09:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 Jul 2011 16:45:37 +0000 (09:45 -0700)
* jc/submodule-sync-no-auto-vivify:
submodule add: always initialize .git/config entry
submodule sync: do not auto-vivify uninteresting submodule

Conflicts:
git-submodule.sh

1  2 
Documentation/git-submodule.txt
git-submodule.sh
t/t7403-submodule-sync.sh
index 12af4de5e1e156d01c5953b1023867b9d29ba848,710633f9656606b2a1fc3b61cd59e69c43404f05..acb9002fe432c6849bd894567d2272bfbe8efdbc
@@@ -101,10 -101,9 +101,10 @@@ status:
        currently checked out commit for each submodule, along with the
        submodule path and the output of 'git describe' for the
        SHA-1. Each SHA-1 will be prefixed with `-` if the submodule is not
 -      initialized and `+` if the currently checked out submodule commit
 +      initialized, `+` 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'.
 +      repository and `U` if the submodule has merge conflicts.
 +      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.
@@@ -167,12 -166,14 +167,14 @@@ commit for each submodule
  
  sync::
        Synchronizes submodules' remote URL configuration setting
-       to the value specified in .gitmodules.  This is useful when
+       to the value specified in .gitmodules. It will only affect those
+       submodules which already have an url entry in .git/config (that is the
+       case when they are initialized or freshly added). 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.
 +"git submodule sync \-- A" synchronizes submodule "A" only.
  
  OPTIONS
  -------
  
  -f::
  --force::
 -      This option is only valid for the add command.
 -      Allow adding an otherwise ignored submodule path.
 +      This option is only valid for add and update commands.
 +      When running add, allow adding an otherwise ignored submodule path.
 +      When running update, throw away local changes in submodules when
 +      switching to a different commit.
  
  --cached::
        This option is only valid for status and summary commands.  These
@@@ -260,6 -259,11 +262,6 @@@ This file should be formatted in the sa
  to each submodule url is "submodule.$name.url".  See linkgit:gitmodules[5]
  for details.
  
 -
 -AUTHOR
 -------
 -Written by Lars Hjemli <hjemli@gmail.com>
 -
  GIT
  ---
  Part of the linkgit:git[1] suite
diff --combined git-submodule.sh
index 87c9452c8a8ae179ffb7e7958ba95688e95bd0e9,ec6178ee996ed72143fbcea88516b6b7e489a720..3daa0c834cad1ed402376adf535c73e1c06172e4
@@@ -8,13 -8,12 +8,13 @@@ dashless=$(basename "$0" | sed -e 's/-
  USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
     or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
     or: $dashless [--quiet] init [--] [<path>...]
 -   or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
 +   or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
     or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
     or: $dashless [--quiet] foreach [--recursive] <command>
     or: $dashless [--quiet] sync [--] [<path>...]"
  OPTIONS_SPEC=
  . git-sh-setup
 +. git-sh-i18n
  . git-parse-remote
  require_work_tree
  
@@@ -35,27 -34,15 +35,27 @@@ resolve_relative_url (
  {
        remote=$(get_default_remote)
        remoteurl=$(git config "remote.$remote.url") ||
 -              die "remote ($remote) does not have a url defined in .git/config"
 +              die "$(eval_gettext "remote (\$remote) does not have a url defined in .git/config")"
        url="$1"
        remoteurl=${remoteurl%/}
 +      sep=/
        while test -n "$url"
        do
                case "$url" in
                ../*)
                        url="${url#../}"
 -                      remoteurl="${remoteurl%/*}"
 +                      case "$remoteurl" in
 +                      */*)
 +                              remoteurl="${remoteurl%/*}"
 +                              ;;
 +                      *:*)
 +                              remoteurl="${remoteurl%:*}"
 +                              sep=:
 +                              ;;
 +                      *)
 +                              die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
 +                              ;;
 +                      esac
                        ;;
                ./*)
                        url="${url#./}"
@@@ -64,7 -51,7 +64,7 @@@
                        break;;
                esac
        done
 -      echo "$remoteurl/${url%/}"
 +      echo "$remoteurl$sep${url%/}"
  }
  
  #
  #
  module_list()
  {
 -      git ls-files --error-unmatch --stage -- "$@" | sane_grep '^160000 '
 +      git ls-files --error-unmatch --stage -- "$@" |
 +      perl -e '
 +      my %unmerged = ();
 +      my ($null_sha1) = ("0" x 40);
 +      while (<STDIN>) {
 +              chomp;
 +              my ($mode, $sha1, $stage, $path) =
 +                      /^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
 +              next unless $mode eq "160000";
 +              if ($stage ne "0") {
 +                      if (!$unmerged{$path}++) {
 +                              print "$mode $null_sha1 U\t$path\n";
 +                      }
 +                      next;
 +              }
 +              print "$_\n";
 +      }
 +      '
  }
  
  #
@@@ -105,7 -75,7 +105,7 @@@ module_name(
        name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
                sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
         test -z "$name" &&
 -       die "No submodule mapping found in .gitmodules for path '$path'"
 +       die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$path'")"
         echo "$name"
  }
  
@@@ -123,13 -93,27 +123,13 @@@ module_clone(
        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
 -      # action) and try to remove it.
 -      # Note: if $path is a symlink to a directory the test will
 -      # succeed but the rmdir will fail. We might want to fix this.
 -      if test -d "$path"
 -      then
 -              rmdir "$path" 2>/dev/null ||
 -              die "Directory '$path' exists, but is neither empty nor a git repository"
 -      fi
 -
 -      test -e "$path" &&
 -      die "A file already exist at path '$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"
 +      die "$(eval_gettext "Clone of '\$url' into submodule path '\$path' failed")"
  }
  
  #
@@@ -202,7 -186,7 +202,7 @@@ cmd_add(
                realrepo=$repo
                ;;
        *)
 -              die "repo URL: '$repo' must be absolute or begin with ./|../"
 +              die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
        ;;
        esac
  
                        s|/*$||
                ')
        git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
 -      die "'$path' already exists in the index"
 +      die "$(eval_gettext "'\$path' already exists in the index")"
  
        if test -z "$force" && ! git add --dry-run --ignore-missing "$path" > /dev/null 2>&1
        then
 -              echo >&2 "The following path is ignored by one of your .gitignore files:" &&
 -              echo >&2 $path &&
 -              echo >&2 "Use -f if you really want to add it."
 +              (
 +                      eval_gettext "The following path is ignored by one of your .gitignore files:
 +\$path
 +Use -f if you really want to add it." &&
 +                      echo
 +              ) >&2
                exit 1
        fi
  
        then
                if test -d "$path"/.git -o -f "$path"/.git
                then
 -                      echo "Adding existing repo at '$path' to the index"
 +                      eval_gettext "Adding existing repo at '\$path' to the index"; echo
                else
 -                      die "'$path' already exists and is not a valid git repo"
 +                      die "$(eval_gettext "'\$path' already exists and is not a valid git repo")"
                fi
  
                case "$repo" in
                        url="$repo"
                        ;;
                esac
-               git config submodule."$path".url "$url"
        else
  
                module_clone "$path" "$realrepo" "$reference" || exit
                        # ash fails to wordsplit ${branch:+-b "$branch"...}
                        case "$branch" in
                        '') git checkout -f -q ;;
 -                      ?*) git checkout -f -q -b "$branch" "origin/$branch" ;;
 +                      ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
                        esac
 -              ) || die "Unable to checkout submodule '$path'"
 +              ) || die "$(eval_gettext "Unable to checkout submodule '\$path'")"
        fi
+       git config submodule."$path".url "$url"
  
        git add $force "$path" ||
 -      die "Failed to add submodule '$path'"
 +      die "$(eval_gettext "Failed to add submodule '\$path'")"
  
        git config -f .gitmodules submodule."$path".path "$path" &&
        git config -f .gitmodules submodule."$path".url "$repo" &&
        git add --force .gitmodules ||
 -      die "Failed to register submodule '$path'"
 +      die "$(eval_gettext "Failed to register submodule '\$path'")"
  }
  
  #
@@@ -304,16 -285,12 +304,16 @@@ cmd_foreach(
  
        toplevel=$(pwd)
  
 +      # dup stdin so that it can be restored when running the external
 +      # command in the subshell (and a recursive call to this function)
 +      exec 3<&0
 +
        module_list |
        while read mode sha1 stage path
        do
                if test -e "$path"/.git
                then
 -                      say "Entering '$prefix$path'"
 +                      say "$(eval_gettext "Entering '\$prefix\$path'")"
                        name=$(module_name "$path")
                        (
                                prefix="$prefix$path/"
                                then
                                        cmd_foreach "--recursive" "$@"
                                fi
 -                      ) ||
 -                      die "Stopping at '$path'; script returned non-zero status."
 +                      ) <&3 3<&- ||
 +                      die "$(eval_gettext "Stopping at '\$path'; script returned non-zero status.")"
                fi
        done
  }
@@@ -363,29 -340,30 +363,30 @@@ cmd_init(
        do
                # Skip already registered paths
                name=$(module_name "$path") || exit
-               url=$(git config submodule."$name".url)
-               test -z "$url" || continue
-               url=$(git config -f .gitmodules submodule."$name".url)
-               test -z "$url" &&
-               die "$(eval_gettext "No url found for submodule path '\$path' in .gitmodules")"
-               # Possibly a url relative to parent
-               case "$url" in
-               ./*|../*)
-                       url=$(resolve_relative_url "$url") || exit
-                       ;;
-               esac
-               git config submodule."$name".url "$url" ||
-               die "$(eval_gettext "Failed to register url for submodule path '\$path'")"
+               if test -z "$(git config "submodule.$name.url")"
+               then
+                       url=$(git config -f .gitmodules submodule."$name".url)
+                       test -z "$url" &&
 -                      die "No url found for submodule path '$path' in .gitmodules"
++                      die "$(eval_gettext "No url found for submodule path '\$path' in .gitmodules")"
+                       # Possibly a url relative to parent
+                       case "$url" in
+                       ./*|../*)
+                               url=$(resolve_relative_url "$url") || exit
+                               ;;
+                       esac
+                       git config submodule."$name".url "$url" ||
 -                      die "Failed to register url for submodule path '$path'"
++                      die "$(eval_gettext "Failed to register url for submodule path '\$path'")"
+               fi
  
+               # Copy "update" setting when it is not set yet
                upd="$(git config -f .gitmodules submodule."$name".update)"
                test -z "$upd" ||
+               test -n "$(git config submodule."$name".update)" ||
                git config submodule."$name".update "$upd" ||
 -              die "Failed to register update mode for submodule path '$path'"
 +              die "$(eval_gettext "Failed to register update mode for submodule path '\$path'")"
  
 -              say "Submodule '$name' ($url) registered for path '$path'"
 +              say "$(eval_gettext "Submodule '\$name' (\$url) registered for path '\$path'")"
        done
  }
  
  cmd_update()
  {
        # parse $args after "submodule ... update".
 -      orig_args="$@"
 +      orig_flags=
        while test $# -ne 0
        do
                case "$1" in
                -q|--quiet)
 -                      shift
                        GIT_QUIET=1
                        ;;
                -i|--init)
                        init=1
 -                      shift
                        ;;
                -N|--no-fetch)
 -                      shift
                        nofetch=1
                        ;;
 +              -f|--force)
 +                      force=$1
 +                      ;;
                -r|--rebase)
 -                      shift
                        update="rebase"
                        ;;
                --reference)
                        case "$2" in '') usage ;; esac
                        reference="--reference=$2"
 -                      shift 2
 +                      orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 +                      shift
                        ;;
                --reference=*)
                        reference="$1"
 -                      shift
                        ;;
                -m|--merge)
 -                      shift
                        update="merge"
                        ;;
                --recursive)
 -                      shift
                        recursive=1
                        ;;
                --)
                        break
                        ;;
                esac
 +              orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 +              shift
        done
  
        if test -n "$init"
                cmd_init "--" "$@" || return
        fi
  
 -      module_list "$@" |
 +      cloned_modules=
 +      module_list "$@" | {
 +      err=
        while read mode sha1 stage path
        do
 +              if test "$stage" = U
 +              then
 +                      echo >&2 "Skipping unmerged submodule $path"
 +                      continue
 +              fi
                name=$(module_name "$path") || exit
                url=$(git config submodule."$name".url)
                update_module=$(git config submodule."$name".update)
                        # Only mention uninitialized submodules when its
                        # path have been specified
                        test "$#" != "0" &&
 -                      say "Submodule path '$path' not initialized" &&
 -                      say "Maybe you want to use 'update --init'?"
 +                      say "$(eval_gettext "Submodule path '\$path' not initialized
 +Maybe you want to use 'update --init'?")"
                        continue
                fi
  
                if ! test -d "$path"/.git -o -f "$path"/.git
                then
                        module_clone "$path" "$url" "$reference"|| exit
 +                      cloned_modules="$cloned_modules;$name"
                        subsha1=
                else
                        subsha1=$(clear_local_git_env; cd "$path" &&
                                git rev-parse --verify HEAD) ||
 -                      die "Unable to find current revision in submodule path '$path'"
 +                      die "$(eval_gettext "Unable to find current revision in submodule path '\$path'")"
                fi
  
                if ! test -z "$update"
  
                if test "$subsha1" != "$sha1"
                then
 -                      force=
 -                      if test -z "$subsha1"
 +                      subforce=$force
 +                      # If we don't already have a -f flag and the submodule has never been checked out
 +                      if test -z "$subsha1" -a -z "$force"
                        then
 -                              force="-f"
 +                              subforce="-f"
                        fi
  
                        if test -z "$nofetch"
                        then
 +                              # Run fetch only if $sha1 isn't present or it
 +                              # is not reachable from a ref.
                                (clear_local_git_env; cd "$path" &&
 -                                      git-fetch) ||
 -                              die "Unable to fetch in submodule path '$path'"
 +                                      ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
 +                                       test -z "$rev") || git-fetch)) ||
 +                              die "$(eval_gettext "Unable to fetch in submodule path '\$path'")"
                        fi
  
 +                      # Is this something we just cloned?
 +                      case ";$cloned_modules;" in
 +                      *";$name;"*)
 +                              # then there is no local change to integrate
 +                              update_module= ;;
 +                      esac
 +
 +                      must_die_on_failure=
                        case "$update_module" in
                        rebase)
                                command="git rebase"
 -                              action="rebase"
 -                              msg="rebased onto"
 +                              die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$path'")"
 +                              say_msg="$(eval_gettext "Submodule path '\$path': rebased into '\$sha1'")"
 +                              must_die_on_failure=yes
                                ;;
                        merge)
                                command="git merge"
 -                              action="merge"
 -                              msg="merged in"
 +                              die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$path'")"
 +                              say_msg="$(eval_gettext "Submodule path '\$path': merged in '\$sha1'")"
 +                              must_die_on_failure=yes
                                ;;
                        *)
 -                              command="git checkout $force -q"
 -                              action="checkout"
 -                              msg="checked out"
 +                              command="git checkout $subforce -q"
 +                              die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$path'")"
 +                              say_msg="$(eval_gettext "Submodule path '\$path': checked out '\$sha1'")"
                                ;;
                        esac
  
 -                      (clear_local_git_env; cd "$path" && $command "$sha1") ||
 -                      die "Unable to $action '$sha1' in submodule path '$path'"
 -                      say "Submodule path '$path': $msg '$sha1'"
 +                      if (clear_local_git_env; cd "$path" && $command "$sha1")
 +                      then
 +                              say "$say_msg"
 +                      elif test -n "$must_die_on_failure"
 +                      then
 +                              die_with_status 2 "$die_msg"
 +                      else
 +                              err="${err};$die_msg"
 +                              continue
 +                      fi
                fi
  
                if test -n "$recursive"
                then
 -                      (clear_local_git_env; cd "$path" && cmd_update $orig_args) ||
 -                      die "Failed to recurse into submodule path '$path'"
 +                      (clear_local_git_env; cd "$path" && eval cmd_update "$orig_flags")
 +                      res=$?
 +                      if test $res -gt 0
 +                      then
 +                              die_msg="$(eval_gettext "Failed to recurse into submodule path '\$path'")"
 +                              if test $res -eq 1
 +                              then
 +                                      err="${err};$die_msg"
 +                                      continue
 +                              else
 +                                      die_with_status $res "$die_msg"
 +                              fi
 +                      fi
                fi
        done
 +
 +      if test -n "$err"
 +      then
 +              OIFS=$IFS
 +              IFS=';'
 +              for e in $err
 +              do
 +                      if test -n "$e"
 +                      then
 +                              echo >&2 "$e"
 +                      fi
 +              done
 +              IFS=$OIFS
 +              exit 1
 +      fi
 +      }
  }
  
  set_name_rev () {
@@@ -663,7 -586,7 +664,7 @@@ cmd_summary() 
        if [ -n "$files" ]
        then
                test -n "$cached" &&
 -              die "--cached cannot be used with --files"
 +              die "$(gettext -- "--cached cannot be used with --files")"
                diff_cmd=diff-files
                head=
        fi
                                ;; # removed
                        *)
                                # unexpected type
 -                              echo >&2 "unexpected mode $mod_dst"
 +                              (
 +                                      eval_gettext "unexpected mode \$mod_dst" &&
 +                                      echo
 +                              ) >&2
                                continue ;;
                        esac
                fi
                total_commits=
                case "$missing_src,$missing_dst" in
                t,)
 -                      errmsg="  Warn: $name doesn't contain commit $sha1_src"
 +                      errmsg="$(eval_gettext "  Warn: \$name doesn't contain commit \$sha1_src")"
                        ;;
                ,t)
 -                      errmsg="  Warn: $name doesn't contain commit $sha1_dst"
 +                      errmsg="$(eval_gettext "  Warn: \$name doesn't contain commit \$sha1_dst")"
                        ;;
                t,t)
 -                      errmsg="  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
 +                      errmsg="$(eval_gettext "  Warn: \$name doesn't contain commits \$sha1_src and \$sha1_dst")"
                        ;;
                *)
                        errmsg=
                sha1_abbr_dst=$(echo $sha1_dst | cut -c1-7)
                if test $status = T
                then
 +                      blob="$(gettext "blob")"
 +                      submodule="$(gettext "submodule")"
                        if test $mod_dst = 160000
                        then
 -                              echo "* $name $sha1_abbr_src(blob)->$sha1_abbr_dst(submodule)$total_commits:"
 +                              echo "* $name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
                        else
 -                              echo "* $name $sha1_abbr_src(submodule)->$sha1_abbr_dst(blob)$total_commits:"
 +                              echo "* $name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
                        fi
                else
                        echo "* $name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
        done |
        if test -n "$for_status"; then
                if [ -n "$files" ]; then
 -                      echo "# Submodules changed but not updated:"
 +                      gettext "# Submodules changed but not updated:"; echo
                else
 -                      echo "# Submodule changes to be committed:"
 +                      gettext "# Submodule changes to be committed:"; echo
                fi
                echo "#"
                sed -e 's|^|# |' -e 's|^# $|#|'
  cmd_status()
  {
        # parse $args after "submodule ... status".
 -      orig_args="$@"
 +      orig_flags=
        while test $# -ne 0
        do
                case "$1" in
                        break
                        ;;
                esac
 +              orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
                shift
        done
  
                name=$(module_name "$path") || exit
                url=$(git config submodule."$name".url)
                displaypath="$prefix$path"
 +              if test "$stage" = U
 +              then
 +                      say "U$sha1 $displaypath"
 +                      continue
 +              fi
                if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git
                then
                        say "-$sha1 $displaypath"
                                prefix="$displaypath/"
                                clear_local_git_env
                                cd "$path" &&
 -                              cmd_status $orig_args
 +                              eval cmd_status "$orig_args"
                        ) ||
 -                      die "Failed to recurse into submodule path '$path'"
 +                      die "$(eval_gettext "Failed to recurse into submodule path '\$path'")"
                fi
        done
  }
@@@ -925,17 -837,20 +926,20 @@@ cmd_sync(
                        ;;
                esac
  
-               say "$(eval_gettext "Synchronizing submodule url for '\$name'")"
-               git config submodule."$name".url "$url"
-               if test -e "$path"/.git
+               if git config "submodule.$name.url" >/dev/null 2>/dev/null
                then
-               (
-                       clear_local_git_env
-                       cd "$path"
-                       remote=$(get_default_remote)
-                       git config remote."$remote".url "$url"
-               )
 -                      say "Synchronizing submodule url for '$name'"
++                      say "$(eval_gettext "Synchronizing submodule url for '\$name'")"
+                       git config submodule."$name".url "$url"
+                       if test -e "$path"/.git
+                       then
+                       (
+                               clear_local_git_env
+                               cd "$path"
+                               remote=$(get_default_remote)
+                               git config remote."$remote".url "$url"
+                       )
+                       fi
                fi
        done
  }
index d600583cef8aa4a19d98ffa63b2cc4f76f698c9e,fb21b876838c47683bb2c4e8c79db85e2c0412e5..95ffe349a769a84d2eec850d376f11bdfcf2b56f
@@@ -25,7 -25,8 +25,8 @@@ test_expect_success setup 
        git clone super super-clone &&
        (cd super-clone && git submodule update --init) &&
        git clone super empty-clone &&
-       (cd empty-clone && git submodule init)
+       (cd empty-clone && git submodule init) &&
+       git clone super top-only-clone
  '
  
  test_expect_success 'change submodule' '
@@@ -52,7 -53,7 +53,7 @@@ test_expect_success 'change submodule u
  
  test_expect_success '"git submodule sync" should update submodule URLs' '
        (cd super-clone &&
 -       git pull &&
 +       git pull --no-recurse-submodules &&
         git submodule sync
        ) &&
        test -d "$(git config -f super-clone/submodule/.git/config \
@@@ -66,7 -67,7 +67,7 @@@
        )
  '
  
- test_expect_success '"git submodule sync" should update submodule URLs if not yet cloned' '
+ test_expect_success '"git submodule sync" should update known submodule URLs' '
        (cd empty-clone &&
         git pull &&
         git submodule sync &&
        )
  '
  
+ test_expect_success '"git submodule sync" should not vivify uninteresting submodule' '
+       (cd top-only-clone &&
+        git pull &&
+        git submodule sync &&
+        test -z "$(git config submodule.submodule.url)" &&
+        git submodule sync submodule &&
+        test -z "$(git config submodule.submodule.url)"
+       )
+ '
  test_done