Merge branch 'tr/maint-mailinfo'
authorJunio C Hamano <gitster@pobox.com>
Sun, 29 Jan 2012 21:18:53 +0000 (13:18 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 29 Jan 2012 21:18:53 +0000 (13:18 -0800)
* tr/maint-mailinfo:
mailinfo: with -b, keep space after [foo]
am: learn passing -b to mailinfo

Conflicts:
git-am.sh

1  2 
Documentation/git-am.txt
git-am.sh
t/t4150-am.sh
diff --combined Documentation/git-am.txt
index 887466d7777bb3cedce976b55d446f0f7803c423,123f7c9e4ab2c16e9cc0024e29ed7e1b3fcb96ea..ee6cca2e1333eb26b0913eb5c4eaf9f38e5855d9
@@@ -13,8 -13,7 +13,8 @@@ SYNOPSI
         [--3way] [--interactive] [--committer-date-is-author-date]
         [--ignore-date] [--ignore-space-change | --ignore-whitespace]
         [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
 -       [--reject] [-q | --quiet] [--scissors | --no-scissors]
 +       [--exclude=<path>] [--reject] [-q | --quiet]
 +       [--scissors | --no-scissors]
         [(<mbox> | <Maildir>)...]
  'git am' (--continue | --skip | --abort)
  
@@@ -40,6 -39,9 +40,9 @@@ OPTION
  --keep::
        Pass `-k` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]).
  
+ --keep-non-patch::
+       Pass `-b` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]).
  --keep-cr::
  --no-keep-cr::
        With `--keep-cr`, call 'git mailsplit' (see linkgit:git-mailsplit[1])
@@@ -88,7 -90,6 +91,7 @@@ default.   You can use `--no-utf8` to o
  -C<n>::
  -p<n>::
  --directory=<dir>::
 +--exclude=<path>::
  --reject::
        These flags are passed to the 'git apply' (see linkgit:git-apply[1])
        program that applies
diff --combined git-am.sh
index 1c13b1399185506dd11750fe7e8c1b989a0f3d0c,8b755d93ba53e133e1bb4114b0736b5dd6f93793..64d8e2a64ddd2e6162e7a8fd93ab4294de3f161e
+++ b/git-am.sh
@@@ -15,6 -15,7 +15,7 @@@ q,quiet         be quie
  s,signoff       add a Signed-off-by line to the commit message
  u,utf8          recode into utf8 (default)
  k,keep          pass -k flag to git-mailinfo
+ keep-non-patch  pass -b flag to git-mailinfo
  keep-cr         pass --keep-cr flag to git-mailsplit for mbox format
  no-keep-cr      do not pass --keep-cr flag to git-mailsplit independent of am.keepcr
  c,scissors      strip everything before a scissors line
@@@ -22,7 -23,6 +23,7 @@@ whitespace=     pass it through git-app
  ignore-space-change pass it through git-apply
  ignore-whitespace pass it through git-apply
  directory=      pass it through git-apply
 +exclude=        pass it through git-apply
  C=              pass it through git-apply
  p=              pass it through git-apply
  patch-format=   format the patch(es) are in
@@@ -38,14 -38,13 +39,14 @@@ rerere-autoupdate update the index wit
  rebasing*       (internal use for git-rebase)"
  
  . git-sh-setup
 +. git-sh-i18n
  prefix=$(git rev-parse --show-prefix)
  set_reflog_action am
  require_work_tree
  cd_to_toplevel
  
  git var GIT_COMMITTER_IDENT >/dev/null ||
 -      die "You need to set your committer info first"
 +      die "$(gettext "You need to set your committer info first")"
  
  if git rev-parse --verify -q HEAD >/dev/null
  then
@@@ -90,8 -89,8 +91,8 @@@ safe_to_abort () 
        then
                return 0
        fi
 -      echo >&2 "You seem to have moved HEAD since the last 'am' failure."
 -      echo >&2 "Not rewinding to ORIG_HEAD"
 +              gettextln "You seem to have moved HEAD since the last 'am' failure.
 +Not rewinding to ORIG_HEAD" >&2
        return 1
  }
  
@@@ -100,9 -99,9 +101,9 @@@ stop_here_user_resolve () 
            printf '%s\n' "$resolvemsg"
            stop_here $1
      fi
 -    echo "When you have resolved this problem run \"$cmdline --resolved\"."
 -    echo "If you would prefer to skip this patch, instead run \"$cmdline --skip\"."
 -    echo "To restore the original branch and stop patching run \"$cmdline --abort\"."
 +    eval_gettextln "When you have resolved this problem run \"\$cmdline --resolved\".
 +If you would prefer to skip this patch, instead run \"\$cmdline --skip\".
 +To restore the original branch and stop patching run \"\$cmdline --abort\"."
  
      stop_here $1
  }
@@@ -116,7 -115,7 +117,7 @@@ go_next () 
  
  cannot_fallback () {
        echo "$1"
 -      echo "Cannot fall back to three-way merge."
 +      gettextln "Cannot fall back to three-way merge."
        exit 1
  }
  
@@@ -131,7 -130,7 +132,7 @@@ fall_back_3way () 
        "$dotest/patch" &&
      GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
      git write-tree >"$dotest/patch-merge-base+" ||
 -    cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
 +    cannot_fallback "$(gettext "Repository lacks necessary blobs to fall back on 3-way merge.")"
  
      say Using index info to reconstruct a base tree...
      if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
        mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
        mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
      else
 -        cannot_fallback "Did you hand edit your patch?
 -It does not apply to blobs recorded in its index."
 +      cannot_fallback "$(gettext "Did you hand edit your patch?
 +It does not apply to blobs recorded in its index.")"
      fi
  
      test -f "$dotest/patch-merge-index" &&
      orig_tree=$(cat "$dotest/patch-merge-base") &&
      rm -fr "$dotest"/patch-merge-* || exit 1
  
 -    say Falling back to patching base and 3-way merge...
 +    say "$(gettext "Falling back to patching base and 3-way merge...")"
  
      # This is not so wrong.  Depending on which base we picked,
      # orig_tree may be wildly different from ours, but his_tree
@@@ -194,15 -193,10 +195,15 @@@ check_patch_format () 
                return 0
        fi
  
 -      # otherwise, check the first few lines of the first patch to try
 -      # to detect its format
 +      # otherwise, check the first few non-blank lines of the first
 +      # patch to try to detect its format
        {
 -              read l1
 +              # Start from first line containing non-whitespace
 +              l1=
 +              while test -z "$l1"
 +              do
 +                      read l1
 +              done
                read l2
                read l3
                case "$l1" in
@@@ -261,7 -255,7 +262,7 @@@ split_patches () 
        stgit-series)
                if test $# -ne 1
                then
 -                      clean_abort "Only one StGIT patch series can be applied at once"
 +                      clean_abort "$(gettext "Only one StGIT patch series can be applied at once")"
                fi
                series_dir=`dirname "$1"`
                series_file="$1"
                        perl -ne 'BEGIN { $subject = 0 }
                                if ($subject > 1) { print ; }
                                elsif (/^\s+$/) { next ; }
 -                              elsif (/^Author:/) { print s/Author/From/ ; }
 +                              elsif (/^Author:/) { s/Author/From/ ; print ;}
                                elsif (/^(From|Date)/) { print ; }
                                elsif ($subject) {
                                        $subject = 2 ;
                this=
                msgnum=
                ;;
 +      hg)
 +              this=0
 +              for hg in "$@"
 +              do
 +                      this=$(( $this + 1 ))
 +                      msgnum=$(printf "%0${prec}d" $this)
 +                      # hg stores changeset metadata in #-commented lines preceding
 +                      # the commit message and diff(s). The only metadata we care about
 +                      # are the User and Date (Node ID and Parent are hashes which are
 +                      # only relevant to the hg repository and thus not useful to us)
 +                      # Since we cannot guarantee that the commit message is in
 +                      # git-friendly format, we put no Subject: line and just consume
 +                      # all of the message as the body
 +                      perl -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
 +                              if ($subject) { print ; }
 +                              elsif (/^\# User /) { s/\# User/From:/ ; print ; }
 +                              elsif (/^\# Date /) {
 +                                      my ($hashsign, $str, $time, $tz) = split ;
 +                                      $tz = sprintf "%+05d", (0-$tz)/36;
 +                                      print "Date: " .
 +                                            strftime("%a, %d %b %Y %H:%M:%S ",
 +                                                     localtime($time))
 +                                            . "$tz\n";
 +                              } elsif (/^\# /) { next ; }
 +                              else {
 +                                      print "\n", $_ ;
 +                                      $subject = 1;
 +                              }
 +                      ' <"$hg" >"$dotest/$msgnum" || clean_abort
 +              done
 +              echo "$this" >"$dotest/last"
 +              this=
 +              msgnum=
 +              ;;
        *)
 -              if test -n "$parse_patch" ; then
 -                      clean_abort "Patch format $patch_format is not supported."
 +              if test -n "$patch_format"
 +              then
 +                      clean_abort "$(eval_gettext "Patch format \$patch_format is not supported.")"
                else
 -                      clean_abort "Patch format detection failed."
 +                      clean_abort "$(gettext "Patch format detection failed.")"
                fi
                ;;
        esac
@@@ -387,6 -346,8 +388,8 @@@ d
                utf8= ;;
        -k|--keep)
                keep=t ;;
+       --keep-non-patch)
+               keep=b ;;
        -c|--scissors)
                scissors=t ;;
        --no-scissors)
        --rebasing)
                rebasing=t threeway=t keep=t scissors=f no_inbody_headers=t ;;
        -d|--dotest)
 -              die "-d option is no longer supported.  Do not use."
 +              die "$(gettext "-d option is no longer supported.  Do not use.")"
                ;;
        --resolvemsg)
                shift; resolvemsg=$1 ;;
 -      --whitespace|--directory)
 +      --whitespace|--directory|--exclude)
                git_apply_opt="$git_apply_opt $(sq "$1=$2")"; shift ;;
        -C|-p)
                git_apply_opt="$git_apply_opt $(sq "$1$2")"; shift ;;
@@@ -463,12 -424,12 +466,12 @@@ the
                false
                ;;
        esac ||
 -      die "previous rebase directory $dotest still exists but mbox given."
 +      die "$(eval_gettext "previous rebase directory \$dotest still exists but mbox given.")"
        resume=yes
  
        case "$skip,$abort" in
        t,t)
 -              die "Please make up your mind. --skip or --abort?"
 +              die "$(gettext "Please make up your mind. --skip or --abort?")"
                ;;
        t,)
                git rerere clear
  else
        # Make sure we are not given --skip, --resolved, nor --abort
        test "$skip$resolved$abort" = "" ||
 -              die "Resolve operation not in progress, we are not resuming."
 +              die "$(gettext "Resolve operation not in progress, we are not resuming.")"
  
        # Start afresh.
        mkdir -p "$dotest" || exit
        echo "$sign" >"$dotest/sign"
        echo "$utf8" >"$dotest/utf8"
        echo "$keep" >"$dotest/keep"
 -      echo "$keepcr" >"$dotest/keepcr"
        echo "$scissors" >"$dotest/scissors"
        echo "$no_inbody_headers" >"$dotest/no_inbody_headers"
        echo "$GIT_QUIET" >"$dotest/quiet"
        fi
  fi
  
 +git update-index -q --refresh
 +
  case "$resolved" in
  '')
        case "$HAS_HEAD" in
        if test "$files"
        then
                test -n "$HAS_HEAD" && : >"$dotest/dirtyindex"
 -              die "Dirty index: cannot apply patches (dirty: $files)"
 +              die "$(eval_gettext "Dirty index: cannot apply patches (dirty: \$files)")"
        fi
  esac
  
+ # Now, decide what command line options we will give to the git
+ # commands we invoke, based on the result of parsing command line
+ # options and previous invocation state stored in $dotest/ files.
  if test "$(cat "$dotest/utf8")" = t
  then
        utf8=-u
  else
        utf8=-n
  fi
- if test "$(cat "$dotest/keep")" = t
- then
-       keep=-k
- fi
+ keep=$(cat "$dotest/keep")
+ case "$keep" in
+ t)
+       keep=-k ;;
+ b)
+       keep=-b ;;
+ *)
+       keep= ;;
+ esac
 -case "$(cat "$dotest/keepcr")" in
 -t)
 -      keepcr=--keep-cr ;;
 -f)
 -      keepcr=--no-keep-cr ;;
 -esac
  case "$(cat "$dotest/scissors")" in
  t)
        scissors=--scissors ;;
@@@ -644,9 -619,9 +656,9 @@@ d
                        go_next && continue
  
                test -s "$dotest/patch" || {
 -                      echo "Patch is empty.  Was it split wrong?"
 -                      echo "If you would prefer to skip this patch, instead run \"$cmdline --skip\"."
 -                      echo "To restore the original branch and stop patching run \"$cmdline --abort\"."
 +                      eval_gettextln "Patch is empty.  Was it split wrong?
 +If you would prefer to skip this patch, instead run \"\$cmdline --skip\".
 +To restore the original branch and stop patching run \"\$cmdline --abort\"."
                        stop_here $this
                }
                rm -f "$dotest/original-commit" "$dotest/author-script"
  
        if test -z "$GIT_AUTHOR_EMAIL"
        then
 -              echo "Patch does not have a valid e-mail address."
 +              gettextln "Patch does not have a valid e-mail address."
                stop_here $this
        fi
  
        if test "$interactive" = t
        then
            test -t 0 ||
 -          die "cannot be interactive without stdin connected to a terminal."
 +          die "$(gettext "cannot be interactive without stdin connected to a terminal.")"
            action=again
            while test "$action" = again
            do
 -              echo "Commit Body is:"
 +              gettextln "Commit Body is:"
                echo "--------------------------"
                cat "$dotest/final-commit"
                echo "--------------------------"
 -              printf "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 +              # TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
 +              # in your translation. The program will only accept English
 +              # input at this point.
 +              gettext "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
                read reply
                case "$reply" in
                [yY]*) action=yes ;;
                stop_here $this
        fi
  
 -      say "Applying: $FIRSTLINE"
 +      say "$(eval_gettext "Applying: \$FIRSTLINE")"
  
        case "$resolved" in
        '')
                # working tree.
                resolved=
                git diff-index --quiet --cached HEAD -- && {
 -                      echo "No changes - did you forget to use 'git add'?"
 -                      echo "If there is nothing left to stage, chances are that something else"
 -                      echo "already introduced the same changes; you might want to skip this patch."
 +                      gettextln "No changes - did you forget to use 'git add'?
 +If there is nothing left to stage, chances are that something else
 +already introduced the same changes; you might want to skip this patch."
                        stop_here_user_resolve $this
                }
                unmerged=$(git ls-files -u)
                if test -n "$unmerged"
                then
 -                      echo "You still have unmerged paths in your index"
 -                      echo "did you forget to use 'git add'?"
 +                      gettextln "You still have unmerged paths in your index
 +did you forget to use 'git add'?"
                        stop_here_user_resolve $this
                fi
                apply_status=0
                    # Applying the patch to an earlier tree and merging the
                    # result may have produced the same tree as ours.
                    git diff-index --quiet --cached HEAD -- && {
 -                      say No changes -- Patch already applied.
 +                      say "$(gettext "No changes -- Patch already applied.")"
                        go_next
                        continue
                    }
        fi
        if test $apply_status != 0
        then
 -              printf 'Patch failed at %s %s\n' "$msgnum" "$FIRSTLINE"
 +              eval_gettextln 'Patch failed at $msgnum $FIRSTLINE'
                stop_here_user_resolve $this
        fi
  
                        GIT_AUTHOR_DATE=
                fi
                parent=$(git rev-parse --verify -q HEAD) ||
 -              say >&2 "applying to an empty history"
 +              say >&2 "$(gettext "applying to an empty history")"
  
                if test -n "$committer_date_is_author_date"
                then
diff --combined t/t4150-am.sh
index d7d9ccc1c8c31ef3b2d4763532344d0637a18b5c,a087254f644c05591f23232c134bf2930953b764..8807b602a51c58cd6fcc313441a0cc7339fc487c
@@@ -96,13 -96,6 +96,13 @@@ test_expect_success setup 
                echo "X-Fake-Field: Line Three" &&
                git format-patch --stdout first | sed -e "1d"
        } | append_cr >patch1-crlf.eml &&
 +      {
 +              printf "%255s\\n" ""
 +              echo "X-Fake-Field: Line One" &&
 +              echo "X-Fake-Field: Line Two" &&
 +              echo "X-Fake-Field: Line Three" &&
 +              git format-patch --stdout first | sed -e "1d"
 +      } > patch1-ws.eml &&
  
        sed -n -e "3,\$p" msg >file &&
        git add file &&
@@@ -174,17 -167,6 +174,17 @@@ test_expect_success 'am applies patch e
        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
  '
  
 +test_expect_success 'am applies patch e-mail with preceding whitespace' '
 +      rm -fr .git/rebase-apply &&
 +      git reset --hard &&
 +      git checkout first &&
 +      git am patch1-ws.eml &&
 +      ! test -d .git/rebase-apply &&
 +      git diff --exit-code second &&
 +      test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 +      test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 +'
 +
  test_expect_success 'setup: new author and committer' '
        GIT_AUTHOR_NAME="Another Thor" &&
        GIT_AUTHOR_EMAIL="a.thor@example.com" &&
@@@ -237,7 -219,7 +237,7 @@@ test_expect_success 'am stays in branch
  
  test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
        git format-patch --stdout HEAD^ >patch3 &&
-       sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4 &&
+       sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
        rm -fr .git/rebase-apply &&
        git reset --hard &&
        git checkout HEAD^ &&
@@@ -259,7 -241,17 +259,17 @@@ test_expect_success 'am --keep really k
        git am --keep patch4 &&
        ! test -d .git/rebase-apply &&
        git cat-file commit HEAD >actual &&
-       grep "Re: Re: Re: \[PATCH 1/5 v2\] third" actual
+       grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
+ '
+ test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
+       rm -fr .git/rebase-apply &&
+       git reset --hard &&
+       git checkout HEAD^ &&
+       git am --keep-non-patch patch4 &&
+       ! test -d .git/rebase-apply &&
+       git cat-file commit HEAD >actual &&
+       grep "^\[foo\] third" actual
  '
  
  test_expect_success 'am -3 falls back to 3-way merge' '
@@@ -483,7 -475,7 +493,7 @@@ test_expect_success 'am newline in subj
        test_tick &&
        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
        git am <patchnl >output.out 2>&1 &&
 -      grep "^Applying: second \\\n foo$" output.out
 +      test_i18ngrep "^Applying: second \\\n foo$" output.out
  '
  
  test_expect_success 'am -q is quiet' '