summaryrefslogtreecommitdiff
path: root/git-am.sh
diff options
context:
space:
mode:
Diffstat (limited to 'git-am.sh')
-rwxr-xr-xgit-am.sh137
1 files changed, 89 insertions, 48 deletions
diff --git a/git-am.sh b/git-am.sh
index 7ea40fe644..455ce4fca0 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -4,6 +4,7 @@
SUBDIRECTORY_OK=Yes
OPTIONS_KEEPDASHDASH=
+OPTIONS_STUCKLONG=t
OPTIONS_SPEC="\
git am [options] [(<mbox>|<Maildir>)...]
git am [options] (--continue | --skip | --abort)
@@ -16,6 +17,7 @@ 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
+m,message-id pass -m 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
@@ -37,6 +39,7 @@ abort restore the original branch and abort the patching operation.
committer-date-is-author-date lie about committer date
ignore-date use current timestamp for author date
rerere-autoupdate update the index with reused conflict resolution if possible
+S,gpg-sign? GPG-sign commits
rebasing* (internal use for git-rebase)"
. git-sh-setup
@@ -66,6 +69,8 @@ then
cmdline="$cmdline -3"
fi
+empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+
sq () {
git rev-parse --sq-quote "$@"
}
@@ -82,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
@@ -123,7 +128,7 @@ cannot_fallback () {
}
fall_back_3way () {
- O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
+ O_OBJECT=$(cd "$GIT_OBJECT_DIRECTORY" && pwd)
rm -fr "$dotest"/patch-merge-*
mkdir "$dotest/patch-merge-tmp-dir"
@@ -174,7 +179,8 @@ It does not apply to blobs recorded in its index.")"
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.")"
}
@@ -273,7 +279,7 @@ split_patches () {
then
clean_abort "$(gettext "Only one StGIT patch series can be applied at once")"
fi
- series_dir=`dirname "$1"`
+ series_dir=$(dirname "$1")
series_file="$1"
shift
{
@@ -296,13 +302,13 @@ split_patches () {
this=0
for stgit in "$@"
do
- this=`expr "$this" + 1`
- msgnum=`printf "%0${prec}d" $this`
+ this=$(expr "$this" + 1)
+ msgnum=$(printf "%0${prec}d" $this)
# Perl version of StGIT parse_patch. The first nonemptyline
# not starting with Author, From or Date is the
# subject, and the body starts with the next nonempty
# line not starting with Author, From or Date
- perl -ne 'BEGIN { $subject = 0 }
+ @@PERL@@ -ne 'BEGIN { $subject = 0 }
if ($subject > 1) { print ; }
elsif (/^\s+$/) { next ; }
elsif (/^Author:/) { s/Author/From/ ; print ;}
@@ -334,7 +340,7 @@ split_patches () {
# 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
- LANG=C LC_ALL=C perl -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
+ LANG=C LC_ALL=C @@PERL@@ -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
if ($subject) { print ; }
elsif (/^\# User /) { s/\# User/From:/ ; print ; }
elsif (/^\# Date /) {
@@ -369,11 +375,18 @@ split_patches () {
prec=4
dotest="$GIT_DIR/rebase-apply"
sign= utf8=t keep= keepcr= skip= interactive= resolved= rebasing= abort=
-resolvemsg= resume= scissors= no_inbody_headers=
+messageid= resolvemsg= resume= scissors= no_inbody_headers=
git_apply_opt=
committer_date_is_author_date=
ignore_date=
allow_rerere_autoupdate=
+gpg_sign_opt=
+threeway=
+
+if test "$(git config --bool --get am.messageid)" = true
+then
+ messageid=t
+fi
if test "$(git config --bool --get am.keepcr)" = true
then
@@ -397,6 +410,10 @@ it will be removed. Please do not use it anymore."
utf8=t ;; # this is now default
--no-utf8)
utf8= ;;
+ -m|--message-id)
+ messageid=t ;;
+ --no-message-id)
+ messageid=f ;;
-k|--keep)
keep=t ;;
--keep-non-patch)
@@ -413,14 +430,14 @@ it will be removed. Please do not use it anymore."
abort=t ;;
--rebasing)
rebasing=t threeway=t ;;
- --resolvemsg)
- shift; resolvemsg=$1 ;;
- --whitespace|--directory|--exclude|--include)
- git_apply_opt="$git_apply_opt $(sq "$1=$2")"; shift ;;
- -C|-p)
- git_apply_opt="$git_apply_opt $(sq "$1$2")"; shift ;;
- --patch-format)
- shift ; patch_format="$1" ;;
+ --resolvemsg=*)
+ resolvemsg="${1#--resolvemsg=}" ;;
+ --whitespace=*|--directory=*|--exclude=*|--include=*)
+ git_apply_opt="$git_apply_opt $(sq "$1")" ;;
+ -C*|-p*)
+ git_apply_opt="$git_apply_opt $(sq "$1")" ;;
+ --patch-format=*)
+ patch_format="${1#--patch-format=}" ;;
--reject|--ignore-whitespace|--ignore-space-change)
git_apply_opt="$git_apply_opt $1" ;;
--committer-date-is-author-date)
@@ -435,6 +452,10 @@ it will be removed. Please do not use it anymore."
keepcr=t ;;
--no-keep-cr)
keepcr=f ;;
+ --gpg-sign)
+ gpg_sign_opt=-S ;;
+ --gpg-sign=*)
+ gpg_sign_opt="-S${1#--gpg-sign=}" ;;
--)
shift; break ;;
*)
@@ -485,10 +506,11 @@ then
;;
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 -m $head_tree
;;
,t)
if test -f "$dotest/rebasing"
@@ -498,8 +520,19 @@ then
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 ;;
@@ -523,7 +556,7 @@ Use \"git am --abort\" to remove it.")"
esac
fi
- # Make sure we are not given --skip, --continue, nor --abort
+ # Make sure we are not given --skip, --continue, or --abort
test "$skip$resolved$abort" = "" ||
die "$(gettext "Resolve operation not in progress, we are not resuming.")"
@@ -560,6 +593,7 @@ Use \"git am --abort\" to remove it.")"
echo "$sign" >"$dotest/sign"
echo "$utf8" >"$dotest/utf8"
echo "$keep" >"$dotest/keep"
+ echo "$messageid" >"$dotest/messageid"
echo "$scissors" >"$dotest/scissors"
echo "$no_inbody_headers" >"$dotest/no_inbody_headers"
echo "$GIT_QUIET" >"$dotest/quiet"
@@ -614,6 +648,12 @@ b)
*)
keep= ;;
esac
+case "$(cat "$dotest/messageid")" in
+t)
+ messageid=-m ;;
+f)
+ messageid= ;;
+esac
case "$(cat "$dotest/scissors")" in
t)
scissors=--scissors ;;
@@ -637,26 +677,26 @@ fi
git_apply_opt=$(cat "$dotest/apply-opt")
if test "$(cat "$dotest/sign")" = t
then
- SIGNOFF=`git var GIT_COMMITTER_IDENT | sed -e '
+ SIGNOFF=$(git var GIT_COMMITTER_IDENT | sed -e '
s/>.*/>/
s/^/Signed-off-by: /'
- `
+ )
else
SIGNOFF=
fi
-last=`cat "$dotest/last"`
-this=`cat "$dotest/next"`
+last=$(cat "$dotest/last")
+this=$(cat "$dotest/next")
if test "$skip" = t
then
- this=`expr "$this" + 1`
+ this=$(expr "$this" + 1)
resume=
fi
while test "$this" -le "$last"
do
- msgnum=`printf "%0${prec}d" $this`
- next=`expr "$this" + 1`
+ msgnum=$(printf "%0${prec}d" $this)
+ next=$(expr "$this" + 1)
test -f "$dotest/$msgnum" || {
resume=
go_next
@@ -685,7 +725,7 @@ do
get_author_ident_from_commit "$commit" >"$dotest/author-script"
git diff-tree --root --binary --full-index "$commit" >"$dotest/patch"
else
- git mailinfo $keep $no_inbody_headers $scissors $utf8 "$dotest/msg" "$dotest/patch" \
+ git mailinfo $keep $no_inbody_headers $messageid $scissors $utf8 "$dotest/msg" "$dotest/patch" \
<"$dotest/$msgnum" >"$dotest/info" ||
stop_here $this
@@ -732,16 +772,16 @@ To restore the original branch and stop patching run \"\$cmdline --abort\"."
'')
if test '' != "$SIGNOFF"
then
- LAST_SIGNED_OFF_BY=`
+ LAST_SIGNED_OFF_BY=$(
sed -ne '/^Signed-off-by: /p' \
"$dotest/msg-clean" |
sed -ne '$p'
- `
- ADD_SIGNOFF=`
+ )
+ ADD_SIGNOFF=$(
test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
test '' = "$LAST_SIGNED_OFF_BY" && echo
echo "$SIGNOFF"
- }`
+ })
else
ADD_SIGNOFF=
fi
@@ -803,10 +843,10 @@ To restore the original branch and stop patching run \"\$cmdline --abort\"."
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"
@@ -880,9 +920,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) &&
@@ -899,7 +940,8 @@ did you forget to use 'git add'?"
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
export GIT_COMMITTER_DATE
fi &&
- git commit-tree $tree ${parent:+-p} $parent <"$dotest/final-commit"
+ git commit-tree ${parent:+-p} $parent ${gpg_sign_opt:+"$gpg_sign_opt"} $tree \
+ <"$dotest/final-commit"
) &&
git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent ||
stop_here $this
@@ -908,18 +950,17 @@ did you forget to use 'git add'?"
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