Merge branch 'fg/submodule-keep-updating'
authorJunio C Hamano <gitster@pobox.com>
Wed, 13 Jul 2011 21:31:35 +0000 (14:31 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 13 Jul 2011 21:31:35 +0000 (14:31 -0700)
* fg/submodule-keep-updating:
git-submodule.sh: clarify the "should we die now" logic
submodule update: continue when a checkout fails
git-sh-setup: add die_with_status

Conflicts:
git-submodule.sh

1  2 
git-submodule.sh
t/t7406-submodule-update.sh
diff --combined git-submodule.sh
index c571d320d012067fe7c1d4c6248546d0679d0335,066d6b57160ab93f65bf5893cc8d355fbf237982..cfd5aa60491a88534aeacb7fe70141aa391675a9
@@@ -14,7 -14,6 +14,7 @@@ USAGE="[--quiet] add [-b branch] [-f|--
     or: $dashless [--quiet] sync [--] [<path>...]"
  OPTIONS_SPEC=
  . git-sh-setup
 +. git-sh-i18n
  . git-parse-remote
  require_work_tree
  
@@@ -35,7 -34,7 +35,7 @@@ 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=/
@@@ -53,7 -52,7 +53,7 @@@
                                sep=:
                                ;;
                        *)
 -                              die "cannot strip one component off url '$remoteurl'"
 +                              die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
                                ;;
                        esac
                        ;;
@@@ -105,7 -104,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"
  }
  
@@@ -129,7 -128,7 +129,7 @@@ module_clone(
        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 -201,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
                        '') git checkout -f -q ;;
                        ?*) 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 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'")"
  }
  
  #
@@@ -309,7 -305,7 +309,7 @@@ cmd_foreach(
        do
                if test -e "$path"/.git
                then
 -                      say "Entering '$prefix$path'"
 +                      say "$(eval_gettext "Entering '\$prefix\$path'")"
                        name=$(module_name "$path")
                        (
                                prefix="$prefix$path/"
                                        cmd_foreach "--recursive" "$@"
                                fi
                        ) ||
 -                      die "Stopping at '$path'; script returned non-zero status."
 +                      die "$(eval_gettext "Stopping at '\$path'; script returned non-zero status.")"
                fi
        done
  }
@@@ -364,7 -360,7 +364,7 @@@ cmd_init(
  
                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
                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'")"
  
                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'"
 +              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
  }
  
@@@ -448,7 -444,8 +448,8 @@@ cmd_update(
        fi
  
        cloned_modules=
-       module_list "$@" |
+       module_list "$@" | {
+       err=
        while read mode sha1 stage path
        do
                if test "$stage" = U
                        # 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
  
                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"
                                (clear_local_git_env; cd "$path" &&
                                        ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
                                         test -z "$rev") || git-fetch)) ||
 -                              die "Unable to fetch in submodule path '$path'"
 +                              die "$(eval_gettext "Unable to fetch in submodule path '\$path'")"
                        fi
  
                        # Is this something we just cloned?
                                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 $subforce -q"
 -                              action="checkout"
 -                              msg="checked out"
 +                              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 $die_msg
-                       say $say_msg
+                       if (clear_local_git_env; cd "$path" && $command "$sha1")
+                       then
 -                              say "Submodule path '$path': $msg '$sha1'"
++                              say "$say_msg"
+                       elif test -n "$must_die_on_failure"
+                       then
 -                              die_with_status 2 "Unable to $action '$sha1' in submodule path '$path'"
++                              die_with_status 2 "$die_msg"
+                       else
 -                              err="${err};Failed to $action in submodule path '$path'"
++                              err="${err};$die_msg"
+                               continue
+                       fi
                fi
  
                if test -n "$recursive"
                then
-                       (clear_local_git_env; cd "$path" && eval cmd_update "$orig_flags") ||
-                       die "$(eval_gettext "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};Failed to recurse into submodule path '$path'"
++                                      err="${err};$die_msg"
+                                       continue
+                               else
 -                                      die_with_status $res "Failed to recurse into submodule path '$path'"
++                                      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 () {
@@@ -620,7 -654,7 +659,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|^# $|#|'
@@@ -838,7 -867,7 +877,7 @@@ cmd_status(
                                cd "$path" &&
                                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
  }
@@@ -882,7 -911,7 +921,7 @@@ cmd_sync(
                        ;;
                esac
  
 -              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
index 60e33bed28820a272c4f2b28ac39f50394a7a18a,807f761147123d40e5e4564b7217ecd6fa232f8d..c679f36a4daeab3f114c9cf0c84c93549d28c680
@@@ -90,7 -90,7 +90,7 @@@ test_expect_success 'submodule update d
        (cd super &&
          git submodule update > ../actual 2> ../actual.err
        ) &&
 -      test_cmp expected actual &&
 +      test_i18ncmp expected actual &&
        ! test -s actual.err
  '
  
@@@ -298,4 -298,148 +298,148 @@@ test_expect_success 'submodule update i
        )
  '
  
+ test_expect_success 'submodule update continues after checkout error' '
+       (cd super &&
+        git reset --hard HEAD &&
+        git submodule add ../submodule submodule2 &&
+        git submodule init &&
+        git commit -am "new_submodule" &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../expect
+        ) &&
+        (cd submodule &&
+         test_commit "update_submodule" file
+        ) &&
+        (cd submodule2 &&
+         test_commit "update_submodule2" file
+        ) &&
+        git add submodule &&
+        git add submodule2 &&
+        git commit -m "two_new_submodule_commits" &&
+        (cd submodule &&
+         echo "" > file
+        ) &&
+        git checkout HEAD^ &&
+        test_must_fail git submodule update &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../actual
+        ) &&
+        test_cmp expect actual
+       )
+ '
+ test_expect_success 'submodule update continues after recursive checkout error' '
+       (cd super &&
+        git reset --hard HEAD &&
+        git checkout master &&
+        git submodule update &&
+        (cd submodule &&
+         git submodule add ../submodule subsubmodule &&
+         git submodule init &&
+         git commit -m "new_subsubmodule"
+        ) &&
+        git add submodule &&
+        git commit -m "update_submodule" &&
+        (cd submodule &&
+         (cd subsubmodule &&
+          test_commit "update_subsubmodule" file
+         ) &&
+         git add subsubmodule &&
+         test_commit "update_submodule_again" file &&
+         (cd subsubmodule &&
+          test_commit "update_subsubmodule_again" file
+         ) &&
+         test_commit "update_submodule_again_again" file
+        ) &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../expect &&
+         test_commit "update_submodule2_again" file
+        ) &&
+        git add submodule &&
+        git add submodule2 &&
+        git commit -m "new_commits" &&
+        git checkout HEAD^ &&
+        (cd submodule &&
+         git checkout HEAD^ &&
+         (cd subsubmodule &&
+          echo "" > file
+         )
+        ) &&
+        test_must_fail git submodule update --recursive &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../actual
+        ) &&
+        test_cmp expect actual
+       )
+ '
+ test_expect_success 'submodule update exit immediately in case of merge conflict' '
+       (cd super &&
+        git checkout master &&
+        git reset --hard HEAD &&
+        (cd submodule &&
+         (cd subsubmodule &&
+          git reset --hard HEAD
+         )
+        ) &&
+        git submodule update --recursive &&
+        (cd submodule &&
+         test_commit "update_submodule_2" file
+        ) &&
+        (cd submodule2 &&
+         test_commit "update_submodule2_2" file
+        ) &&
+        git add submodule &&
+        git add submodule2 &&
+        git commit -m "two_new_submodule_commits" &&
+        (cd submodule &&
+         git checkout master &&
+         test_commit "conflict" file &&
+         echo "conflict" > file
+        ) &&
+        git checkout HEAD^ &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../expect
+        ) &&
+        git config submodule.submodule.update merge &&
+        test_must_fail git submodule update &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../actual
+        ) &&
+        test_cmp expect actual
+       )
+ '
+ test_expect_success 'submodule update exit immediately after recursive rebase error' '
+       (cd super &&
+        git checkout master &&
+        git reset --hard HEAD &&
+        (cd submodule &&
+         git reset --hard HEAD &&
+         git submodule update --recursive
+        ) &&
+        (cd submodule &&
+         test_commit "update_submodule_3" file
+        ) &&
+        (cd submodule2 &&
+         test_commit "update_submodule2_3" file
+        ) &&
+        git add submodule &&
+        git add submodule2 &&
+        git commit -m "two_new_submodule_commits" &&
+        (cd submodule &&
+         git checkout master &&
+         test_commit "conflict2" file &&
+         echo "conflict" > file
+        ) &&
+        git checkout HEAD^ &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../expect
+        ) &&
+        git config submodule.submodule.update rebase &&
+        test_must_fail git submodule update &&
+        (cd submodule2 &&
+         git rev-parse --max-count=1 HEAD > ../actual
+        ) &&
+        test_cmp expect actual
+       )
+ '
  test_done