Merge branch 'pt/am-foreign'
authorJunio C Hamano <gitster@pobox.com>
Mon, 3 Aug 2015 18:01:12 +0000 (11:01 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 3 Aug 2015 18:01:12 +0000 (11:01 -0700)
Various enhancements around "git am" reading patches generated by
foreign SCM.

* pt/am-foreign:
am: teach mercurial patch parser how to read from stdin
am: use gmtime() to parse mercurial patch date
t4150: test applying StGit series
am: teach StGit patch parser how to read from stdin
t4150: test applying StGit patch

1  2 
git-am.sh
t/t4150-am.sh
diff --combined git-am.sh
index 3af351ffaaf32af6431e7a0dd53ea619507c55bf,f35710cb502543f35b642fd8a49f0d2cc8beba62..3b770281232904132ac10620ded4a36d36a00be5
+++ b/git-am.sh
@@@ -69,8 -69,6 +69,8 @@@ the
        cmdline="$cmdline -3"
  fi
  
 +empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 +
  sq () {
        git rev-parse --sq-quote "$@"
  }
@@@ -87,7 -85,7 +87,7 @@@ safe_to_abort () 
                return 1
        fi
  
 -      if ! test -s "$dotest/abort-safety"
 +      if ! test -f "$dotest/abort-safety"
        then
                return 0
        fi
@@@ -179,8 -177,7 +179,8 @@@ It does not apply to blobs recorded in 
      then
            GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
      fi
 -    git-merge-recursive $orig_tree -- HEAD $his_tree || {
 +    our_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree)
 +    git-merge-recursive $orig_tree -- $our_tree $his_tree || {
            git rerere $allow_rerere_autoupdate
            die "$(gettext "Failed to merge in the changes.")"
      }
@@@ -300,6 -297,7 +300,7 @@@ split_patches () 
                ;;
        stgit)
                this=0
+               test 0 -eq "$#" && set -- -
                for stgit in "$@"
                do
                        this=$(expr "$this" + 1)
                                        print "Subject: ", $_ ;
                                        $subject = 1;
                                }
-                       ' < "$stgit" > "$dotest/$msgnum" || clean_abort
+                       ' -- "$stgit" >"$dotest/$msgnum" || clean_abort
                done
                echo "$this" > "$dotest/last"
                this=
                ;;
        hg)
                this=0
+               test 0 -eq "$#" && set -- -
                for hg in "$@"
                do
                        this=$(( $this + 1 ))
                                elsif (/^\# User /) { s/\# User/From:/ ; print ; }
                                elsif (/^\# Date /) {
                                        my ($hashsign, $str, $time, $tz) = split ;
-                                       $tz = sprintf "%+05d", (0-$tz)/36;
+                                       $tz_str = sprintf "%+05d", (0-$tz)/36;
                                        print "Date: " .
                                              strftime("%a, %d %b %Y %H:%M:%S ",
-                                                      localtime($time))
-                                             . "$tz\n";
+                                                      gmtime($time-$tz))
+                                             . "$tz_str\n";
                                } elsif (/^\# /) { next ; }
                                else {
                                        print "\n", $_ ;
                                        $subject = 1;
                                }
-                       ' <"$hg" >"$dotest/$msgnum" || clean_abort
+                       ' -- "$hg" >"$dotest/$msgnum" || clean_abort
                done
                echo "$this" >"$dotest/last"
                this=
@@@ -381,7 -380,6 +383,7 @@@ committer_date_is_author_date
  ignore_date=
  allow_rerere_autoupdate=
  gpg_sign_opt=
 +threeway=
  
  if test "$(git config --bool --get am.messageid)" = true
  then
@@@ -506,11 -504,10 +508,11 @@@ the
                ;;
        t,)
                git rerere clear
 -              git read-tree --reset -u HEAD HEAD
 -              orig_head=$(cat "$GIT_DIR/ORIG_HEAD")
 -              git reset HEAD
 -              git update-ref ORIG_HEAD $orig_head
 +              head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
 +              git read-tree --reset -u $head_tree $head_tree &&
 +              index_tree=$(git write-tree) &&
 +              git read-tree -m -u $index_tree $head_tree
 +              git read-tree $head_tree
                ;;
        ,t)
                if test -f "$dotest/rebasing"
                git rerere clear
                if safe_to_abort
                then
 -                      git read-tree --reset -u HEAD ORIG_HEAD
 -                      git reset ORIG_HEAD
 +                      head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
 +                      git read-tree --reset -u $head_tree $head_tree &&
 +                      index_tree=$(git write-tree) &&
 +                      orig_head=$(git rev-parse --verify -q ORIG_HEAD || echo $empty_tree) &&
 +                      git read-tree -m -u $index_tree $orig_head
 +                      if git rev-parse --verify -q ORIG_HEAD >/dev/null 2>&1
 +                      then
 +                              git reset ORIG_HEAD
 +                      else
 +                              git read-tree $empty_tree
 +                              curr_branch=$(git symbolic-ref HEAD 2>/dev/null) &&
 +                              git update-ref -d $curr_branch
 +                      fi
                fi
                rm -fr "$dotest"
                exit ;;
@@@ -843,10 -829,10 +845,10 @@@ To restore the original branch and sto
                continue
        fi
  
 -      if test -x "$GIT_DIR"/hooks/applypatch-msg
 +      hook="$(git rev-parse --git-path hooks/applypatch-msg)"
 +      if test -x "$hook"
        then
 -              "$GIT_DIR"/hooks/applypatch-msg "$dotest/final-commit" ||
 -              stop_here $this
 +              "$hook" "$dotest/final-commit" || stop_here $this
        fi
  
        if test -f "$dotest/final-commit"
@@@ -920,10 -906,9 +922,10 @@@ did you forget to use 'git add'?
                stop_here_user_resolve $this
        fi
  
 -      if test -x "$GIT_DIR"/hooks/pre-applypatch
 +      hook="$(git rev-parse --git-path hooks/pre-applypatch)"
 +      if test -x "$hook"
        then
 -              "$GIT_DIR"/hooks/pre-applypatch || stop_here $this
 +              "$hook" || stop_here $this
        fi
  
        tree=$(git write-tree) &&
                echo "$(cat "$dotest/original-commit") $commit" >> "$dotest/rewritten"
        fi
  
 -      if test -x "$GIT_DIR"/hooks/post-applypatch
 -      then
 -              "$GIT_DIR"/hooks/post-applypatch
 -      fi
 +      hook="$(git rev-parse --git-path hooks/post-applypatch)"
 +      test -x "$hook" && "$hook"
  
        go_next
  done
  
  if test -s "$dotest"/rewritten; then
      git notes copy --for-rewrite=rebase < "$dotest"/rewritten
 -    if test -x "$GIT_DIR"/hooks/post-rewrite; then
 -      "$GIT_DIR"/hooks/post-rewrite rebase < "$dotest"/rewritten
 +    hook="$(git rev-parse --git-path hooks/post-rewrite)"
 +    if test -x "$hook"; then
 +      "$hook" rebase < "$dotest"/rewritten
      fi
  fi
  
diff --combined t/t4150-am.sh
index 6ced98cfb4a71553d66a828118a585e0f7fc84c7,3ebafd9234170f01f422bf063a7fee6b9e5b5dee..3320fa6315e84031fff646a061ef7ed6467e411c
@@@ -104,6 -104,38 +104,38 @@@ test_expect_success setup 
                echo "X-Fake-Field: Line Three" &&
                git format-patch --stdout first | sed -e "1d"
        } > patch1-ws.eml &&
+       {
+               sed -ne "1p" msg &&
+               echo &&
+               echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
+               echo "Date: $GIT_AUTHOR_DATE" &&
+               echo &&
+               sed -e "1,2d" msg &&
+               echo &&
+               echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
+               echo "---" &&
+               git diff-tree --no-commit-id --stat -p second
+       } >patch1-stgit.eml &&
+       mkdir stgit-series &&
+       cp patch1-stgit.eml stgit-series/patch &&
+       {
+               echo "# This series applies on GIT commit $(git rev-parse first)" &&
+               echo "patch"
+       } >stgit-series/series &&
+       {
+               echo "# HG changeset patch" &&
+               echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
+               echo "# Date $test_tick 25200" &&
+               echo "#      $(git show --pretty="%aD" -s second)" &&
+               echo "# Node ID $_z40" &&
+               echo "# Parent  $_z40" &&
+               cat msg &&
+               echo &&
+               echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
+               echo &&
+               git diff-tree --no-commit-id -p second
+       } >patch1-hg.eml &&
  
        sed -n -e "3,\$p" msg >file &&
        git add file &&
@@@ -187,6 -219,56 +219,56 @@@ test_expect_success 'am applies patch e
        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
  '
  
+ test_expect_success 'am applies stgit patch' '
+       rm -fr .git/rebase-apply &&
+       git checkout -f first &&
+       git am patch1-stgit.eml &&
+       test_path_is_missing .git/rebase-apply &&
+       git diff --exit-code second &&
+       test_cmp_rev second HEAD &&
+       test_cmp_rev second^ HEAD^
+ '
+ test_expect_success 'am --patch-format=stgit applies stgit patch' '
+       rm -fr .git/rebase-apply &&
+       git checkout -f first &&
+       git am --patch-format=stgit <patch1-stgit.eml &&
+       test_path_is_missing .git/rebase-apply &&
+       git diff --exit-code second &&
+       test_cmp_rev second HEAD &&
+       test_cmp_rev second^ HEAD^
+ '
+ test_expect_success 'am applies stgit series' '
+       rm -fr .git/rebase-apply &&
+       git checkout -f first &&
+       git am stgit-series/series &&
+       test_path_is_missing .git/rebase-apply &&
+       git diff --exit-code second &&
+       test_cmp_rev second HEAD &&
+       test_cmp_rev second^ HEAD^
+ '
+ test_expect_success 'am applies hg patch' '
+       rm -fr .git/rebase-apply &&
+       git checkout -f first &&
+       git am patch1-hg.eml &&
+       test_path_is_missing .git/rebase-apply &&
+       git diff --exit-code second &&
+       test_cmp_rev second HEAD &&
+       test_cmp_rev second^ HEAD^
+ '
+ test_expect_success 'am --patch-format=hg applies hg patch' '
+       rm -fr .git/rebase-apply &&
+       git checkout -f first &&
+       git am --patch-format=hg <patch1-hg.eml &&
+       test_path_is_missing .git/rebase-apply &&
+       git diff --exit-code second &&
+       test_cmp_rev second HEAD &&
+       test_cmp_rev second^ HEAD^
+ '
  test_expect_success 'setup: new author and committer' '
        GIT_AUTHOR_NAME="Another Thor" &&
        GIT_AUTHOR_EMAIL="a.thor@example.com" &&
@@@ -274,21 -356,15 +356,21 @@@ test_expect_success 'am --keep-non-patc
        grep "^\[foo\] third" actual
  '
  
 -test_expect_success 'am -3 falls back to 3-way merge' '
 +test_expect_success 'setup am -3' '
        rm -fr .git/rebase-apply &&
        git reset --hard &&
 -      git checkout -b lorem2 master2 &&
 +      git checkout -b base3way master2 &&
        sed -n -e "3,\$p" msg >file &&
        head -n 9 msg >>file &&
        git add file &&
        test_tick &&
 -      git commit -m "copied stuff" &&
 +      git commit -m "copied stuff"
 +'
 +
 +test_expect_success 'am -3 falls back to 3-way merge' '
 +      rm -fr .git/rebase-apply &&
 +      git reset --hard &&
 +      git checkout -b lorem2 base3way &&
        git am -3 lorem-move.patch &&
        test_path_is_missing .git/rebase-apply &&
        git diff --exit-code lorem
  test_expect_success 'am -3 -p0 can read --no-prefix patch' '
        rm -fr .git/rebase-apply &&
        git reset --hard &&
 -      git checkout -b lorem3 master2 &&
 -      sed -n -e "3,\$p" msg >file &&
 -      head -n 9 msg >>file &&
 -      git add file &&
 -      test_tick &&
 -      git commit -m "copied stuff" &&
 +      git checkout -b lorem3 base3way &&
        git am -3 -p0 lorem-zero.patch &&
        test_path_is_missing .git/rebase-apply &&
        git diff --exit-code lorem
@@@ -339,7 -420,12 +421,7 @@@ test_expect_success 'am -3 can rename 
  test_expect_success 'am -3 -q is quiet' '
        rm -fr .git/rebase-apply &&
        git checkout -f lorem2 &&
 -      git reset master2 --hard &&
 -      sed -n -e "3,\$p" msg >file &&
 -      head -n 9 msg >>file &&
 -      git add file &&
 -      test_tick &&
 -      git commit -m "copied stuff" &&
 +      git reset base3way --hard &&
        git am -3 -q lorem-move.patch >output.out 2>&1 &&
        ! test -s output.out
  '