2005-10-07 18:44:18 +08:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
2006-02-19 12:51:26 +08:00
|
|
|
# Copyright (c) 2005, 2006 Junio C Hamano
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2008-03-01 14:22:55 +08:00
|
|
|
SUBDIRECTORY_OK=Yes
|
2007-11-04 18:30:57 +08:00
|
|
|
OPTIONS_KEEPDASHDASH=
|
2014-02-01 10:18:00 +08:00
|
|
|
OPTIONS_STUCKLONG=t
|
2007-11-04 18:30:57 +08:00
|
|
|
OPTIONS_SPEC="\
|
2010-10-09 01:31:17 +08:00
|
|
|
git am [options] [(<mbox>|<Maildir>)...]
|
2013-06-27 04:06:41 +08:00
|
|
|
git am [options] (--continue | --skip | --abort)
|
2007-11-04 18:30:57 +08:00
|
|
|
--
|
2007-11-09 15:04:31 +08:00
|
|
|
i,interactive run interactively
|
2009-01-28 23:03:10 +08:00
|
|
|
b,binary* (historical option -- no-op)
|
2007-11-04 18:30:57 +08:00
|
|
|
3,3way allow fall back on 3way merging if needed
|
2009-06-17 06:33:01 +08:00
|
|
|
q,quiet be quiet
|
2007-11-04 18:30:57 +08:00
|
|
|
s,signoff add a Signed-off-by line to the commit message
|
|
|
|
u,utf8 recode into utf8 (default)
|
2008-02-03 07:58:06 +08:00
|
|
|
k,keep pass -k flag to git-mailinfo
|
2012-01-16 18:53:00 +08:00
|
|
|
keep-non-patch pass -b flag to git-mailinfo
|
2014-11-25 22:00:56 +08:00
|
|
|
m,message-id pass -m flag to git-mailinfo
|
2010-02-27 22:20:26 +08:00
|
|
|
keep-cr pass --keep-cr flag to git-mailsplit for mbox format
|
2010-02-27 22:20:27 +08:00
|
|
|
no-keep-cr do not pass --keep-cr flag to git-mailsplit independent of am.keepcr
|
2009-08-27 12:36:05 +08:00
|
|
|
c,scissors strip everything before a scissors line
|
2007-11-04 18:30:57 +08:00
|
|
|
whitespace= pass it through git-apply
|
2009-08-04 19:16:49 +08:00
|
|
|
ignore-space-change pass it through git-apply
|
|
|
|
ignore-whitespace pass it through git-apply
|
2009-01-12 14:21:48 +08:00
|
|
|
directory= pass it through git-apply
|
2011-08-03 17:37:29 +08:00
|
|
|
exclude= pass it through git-apply
|
2012-03-28 19:11:28 +08:00
|
|
|
include= pass it through git-apply
|
2007-11-04 18:30:57 +08:00
|
|
|
C= pass it through git-apply
|
|
|
|
p= pass it through git-apply
|
2009-05-27 17:25:16 +08:00
|
|
|
patch-format= format the patch(es) are in
|
2009-01-23 08:31:21 +08:00
|
|
|
reject pass it through git-apply
|
2007-11-04 18:30:57 +08:00
|
|
|
resolvemsg= override error message when patch failure occurs
|
2010-02-12 06:27:14 +08:00
|
|
|
continue continue applying patches after resolving a conflict
|
|
|
|
r,resolved synonyms for --continue
|
2008-03-04 16:25:06 +08:00
|
|
|
skip skip the current patch
|
2008-07-16 18:39:10 +08:00
|
|
|
abort restore the original branch and abort the patching operation.
|
2009-01-23 08:14:58 +08:00
|
|
|
committer-date-is-author-date lie about committer date
|
2009-01-24 09:18:02 +08:00
|
|
|
ignore-date use current timestamp for author date
|
2009-12-04 16:20:48 +08:00
|
|
|
rerere-autoupdate update the index with reused conflict resolution if possible
|
2014-02-01 10:18:01 +08:00
|
|
|
S,gpg-sign? GPG-sign commits
|
2009-01-28 23:03:10 +08:00
|
|
|
rebasing* (internal use for git-rebase)"
|
2007-11-04 18:30:57 +08:00
|
|
|
|
2005-12-14 06:30:31 +08:00
|
|
|
. git-sh-setup
|
2011-05-22 02:43:42 +08:00
|
|
|
. git-sh-i18n
|
2008-03-04 16:25:04 +08:00
|
|
|
prefix=$(git rev-parse --show-prefix)
|
2006-12-28 15:34:48 +08:00
|
|
|
set_reflog_action am
|
2006-12-31 12:32:38 +08:00
|
|
|
require_work_tree
|
2008-03-01 14:22:55 +08:00
|
|
|
cd_to_toplevel
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2008-07-12 23:46:59 +08:00
|
|
|
git var GIT_COMMITTER_IDENT >/dev/null ||
|
2011-05-22 02:43:47 +08:00
|
|
|
die "$(gettext "You need to set your committer info first")"
|
2006-02-19 12:51:26 +08:00
|
|
|
|
2009-04-10 08:34:42 +08:00
|
|
|
if git rev-parse --verify -q HEAD >/dev/null
|
|
|
|
then
|
|
|
|
HAS_HEAD=yes
|
|
|
|
else
|
|
|
|
HAS_HEAD=
|
|
|
|
fi
|
|
|
|
|
2010-06-02 16:33:35 +08:00
|
|
|
cmdline="git am"
|
|
|
|
if test '' != "$interactive"
|
|
|
|
then
|
|
|
|
cmdline="$cmdline -i"
|
|
|
|
fi
|
|
|
|
if test '' != "$threeway"
|
|
|
|
then
|
|
|
|
cmdline="$cmdline -3"
|
|
|
|
fi
|
|
|
|
|
2015-06-06 19:46:07 +08:00
|
|
|
empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
|
|
|
|
2009-01-12 14:21:48 +08:00
|
|
|
sq () {
|
2009-04-24 14:29:01 +08:00
|
|
|
git rev-parse --sq-quote "$@"
|
2009-01-12 14:21:48 +08:00
|
|
|
}
|
|
|
|
|
2005-10-07 18:44:18 +08:00
|
|
|
stop_here () {
|
|
|
|
echo "$1" >"$dotest/next"
|
2010-12-22 02:35:53 +08:00
|
|
|
git rev-parse --verify -q HEAD >"$dotest/abort-safety"
|
2005-10-07 18:44:18 +08:00
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2010-12-22 02:35:53 +08:00
|
|
|
safe_to_abort () {
|
|
|
|
if test -f "$dotest/dirtyindex"
|
|
|
|
then
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
2015-06-06 19:46:12 +08:00
|
|
|
if ! test -f "$dotest/abort-safety"
|
2010-12-22 02:35:53 +08:00
|
|
|
then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
abort_safety=$(cat "$dotest/abort-safety")
|
|
|
|
if test "z$(git rev-parse --verify -q HEAD)" = "z$abort_safety"
|
|
|
|
then
|
|
|
|
return 0
|
|
|
|
fi
|
2012-07-25 22:53:11 +08:00
|
|
|
gettextln "You seem to have moved HEAD since the last 'am' failure.
|
2011-08-07 19:58:14 +08:00
|
|
|
Not rewinding to ORIG_HEAD" >&2
|
2010-12-22 02:35:53 +08:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2006-05-02 20:32:43 +08:00
|
|
|
stop_here_user_resolve () {
|
2006-05-14 11:34:08 +08:00
|
|
|
if [ -n "$resolvemsg" ]; then
|
2007-05-26 15:33:03 +08:00
|
|
|
printf '%s\n' "$resolvemsg"
|
2006-05-14 11:34:08 +08:00
|
|
|
stop_here $1
|
|
|
|
fi
|
2013-06-27 04:06:41 +08:00
|
|
|
eval_gettextln "When you have resolved this problem, run \"\$cmdline --continue\".
|
2012-07-25 22:53:08 +08:00
|
|
|
If you prefer to skip this patch, run \"\$cmdline --skip\" instead.
|
|
|
|
To restore the original branch and stop patching, run \"\$cmdline --abort\"."
|
2006-05-02 20:32:43 +08:00
|
|
|
|
|
|
|
stop_here $1
|
|
|
|
}
|
|
|
|
|
2005-10-07 18:44:18 +08:00
|
|
|
go_next () {
|
|
|
|
rm -f "$dotest/$msgnum" "$dotest/msg" "$dotest/msg-clean" \
|
|
|
|
"$dotest/patch" "$dotest/info"
|
|
|
|
echo "$next" >"$dotest/next"
|
|
|
|
this=$next
|
|
|
|
}
|
|
|
|
|
2006-08-13 07:16:47 +08:00
|
|
|
cannot_fallback () {
|
|
|
|
echo "$1"
|
2011-08-07 19:58:14 +08:00
|
|
|
gettextln "Cannot fall back to three-way merge."
|
2006-08-13 07:16:47 +08:00
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2005-10-07 18:44:18 +08:00
|
|
|
fall_back_3way () {
|
2014-03-26 01:22:22 +08:00
|
|
|
O_OBJECT=$(cd "$GIT_OBJECT_DIRECTORY" && pwd)
|
2005-10-07 18:44:18 +08:00
|
|
|
|
|
|
|
rm -fr "$dotest"/patch-merge-*
|
|
|
|
mkdir "$dotest/patch-merge-tmp-dir"
|
|
|
|
|
|
|
|
# First see if the patch records the index info that we can use.
|
2012-02-23 13:55:06 +08:00
|
|
|
cmd="git apply $git_apply_opt --build-fake-ancestor" &&
|
|
|
|
cmd="$cmd "'"$dotest/patch-merge-tmp-index" "$dotest/patch"' &&
|
|
|
|
eval "$cmd" &&
|
2006-08-13 07:16:47 +08:00
|
|
|
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
|
2007-07-03 13:52:14 +08:00
|
|
|
git write-tree >"$dotest/patch-merge-base+" ||
|
2011-05-22 02:43:48 +08:00
|
|
|
cannot_fallback "$(gettext "Repository lacks necessary blobs to fall back on 3-way merge.")"
|
2006-08-13 07:16:47 +08:00
|
|
|
|
2012-07-25 22:53:11 +08:00
|
|
|
say "$(gettext "Using index info to reconstruct a base tree...")"
|
2012-02-23 13:55:06 +08:00
|
|
|
|
|
|
|
cmd='GIT_INDEX_FILE="$dotest/patch-merge-tmp-index"'
|
2012-03-29 00:55:21 +08:00
|
|
|
|
|
|
|
if test -z "$GIT_QUIET"
|
|
|
|
then
|
|
|
|
eval "$cmd git diff-index --cached --diff-filter=AM --name-status HEAD"
|
|
|
|
fi
|
|
|
|
|
2012-02-23 13:55:06 +08:00
|
|
|
cmd="$cmd git apply --cached $git_apply_opt"' <"$dotest/patch"'
|
|
|
|
if eval "$cmd"
|
2005-10-07 18:44:18 +08:00
|
|
|
then
|
|
|
|
mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
|
|
|
|
mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
|
2006-08-13 07:16:47 +08:00
|
|
|
else
|
2011-05-22 02:43:48 +08:00
|
|
|
cannot_fallback "$(gettext "Did you hand edit your patch?
|
|
|
|
It does not apply to blobs recorded in its index.")"
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
|
|
|
|
|
|
|
test -f "$dotest/patch-merge-index" &&
|
2007-07-03 13:52:14 +08:00
|
|
|
his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree) &&
|
2005-10-07 18:44:18 +08:00
|
|
|
orig_tree=$(cat "$dotest/patch-merge-base") &&
|
|
|
|
rm -fr "$dotest"/patch-merge-* || exit 1
|
|
|
|
|
2011-05-22 02:43:51 +08:00
|
|
|
say "$(gettext "Falling back to patching base and 3-way merge...")"
|
2005-10-07 18:44:18 +08:00
|
|
|
|
|
|
|
# This is not so wrong. Depending on which base we picked,
|
|
|
|
# orig_tree may be wildly different from ours, but his_tree
|
|
|
|
# has the same set of wildly different changes in parts the
|
2006-12-28 15:35:27 +08:00
|
|
|
# patch did not touch, so recursive ends up canceling them,
|
2005-10-07 18:44:18 +08:00
|
|
|
# saying that we reverted all those changes.
|
|
|
|
|
2008-04-16 03:56:50 +08:00
|
|
|
eval GITHEAD_$his_tree='"$FIRSTLINE"'
|
2006-12-28 15:35:27 +08:00
|
|
|
export GITHEAD_$his_tree
|
2009-06-17 06:33:01 +08:00
|
|
|
if test -n "$GIT_QUIET"
|
|
|
|
then
|
2010-10-14 02:36:36 +08:00
|
|
|
GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
|
2009-06-17 06:33:01 +08:00
|
|
|
fi
|
2015-06-06 19:46:08 +08:00
|
|
|
our_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree)
|
|
|
|
git-merge-recursive $orig_tree -- $our_tree $his_tree || {
|
2009-12-04 16:20:48 +08:00
|
|
|
git rerere $allow_rerere_autoupdate
|
2012-07-25 22:53:11 +08:00
|
|
|
die "$(gettext "Failed to merge in the changes.")"
|
2005-10-07 18:44:18 +08:00
|
|
|
}
|
2006-12-28 15:35:27 +08:00
|
|
|
unset GITHEAD_$his_tree
|
2005-10-07 18:44:18 +08:00
|
|
|
}
|
|
|
|
|
2009-05-27 17:25:19 +08:00
|
|
|
clean_abort () {
|
|
|
|
test $# = 0 || echo >&2 "$@"
|
|
|
|
rm -fr "$dotest"
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2009-05-27 17:25:16 +08:00
|
|
|
patch_format=
|
|
|
|
|
|
|
|
check_patch_format () {
|
|
|
|
# early return if patch_format was set from the command line
|
|
|
|
if test -n "$patch_format"
|
|
|
|
then
|
|
|
|
return 0
|
|
|
|
fi
|
2009-05-28 05:20:12 +08:00
|
|
|
|
|
|
|
# we default to mbox format if input is from stdin and for
|
|
|
|
# directories
|
|
|
|
if test $# = 0 || test "x$1" = "x-" || test -d "$1"
|
|
|
|
then
|
|
|
|
patch_format=mbox
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
2011-08-08 10:49:04 +08:00
|
|
|
# otherwise, check the first few non-blank lines of the first
|
|
|
|
# patch to try to detect its format
|
2009-05-28 05:20:12 +08:00
|
|
|
{
|
2011-08-08 10:49:04 +08:00
|
|
|
# Start from first line containing non-whitespace
|
|
|
|
l1=
|
|
|
|
while test -z "$l1"
|
|
|
|
do
|
2012-02-26 01:34:26 +08:00
|
|
|
read l1 || break
|
2011-08-08 10:49:04 +08:00
|
|
|
done
|
2009-05-28 05:20:12 +08:00
|
|
|
read l2
|
|
|
|
read l3
|
|
|
|
case "$l1" in
|
|
|
|
"From "* | "From: "*)
|
|
|
|
patch_format=mbox
|
|
|
|
;;
|
|
|
|
'# This series applies on GIT commit'*)
|
|
|
|
patch_format=stgit-series
|
|
|
|
;;
|
|
|
|
"# HG changeset patch")
|
|
|
|
patch_format=hg
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
# if the second line is empty and the third is
|
|
|
|
# a From, Author or Date entry, this is very
|
|
|
|
# likely an StGIT patch
|
|
|
|
case "$l2,$l3" in
|
|
|
|
,"From: "* | ,"Author: "* | ,"Date: "*)
|
|
|
|
patch_format=stgit
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
;;
|
|
|
|
esac
|
2009-08-07 09:08:12 +08:00
|
|
|
if test -z "$patch_format" &&
|
|
|
|
test -n "$l1" &&
|
|
|
|
test -n "$l2" &&
|
|
|
|
test -n "$l3"
|
|
|
|
then
|
|
|
|
# This begins with three non-empty lines. Is this a
|
|
|
|
# piece of e-mail a-la RFC2822? Grab all the headers,
|
|
|
|
# discarding the indented remainder of folded lines,
|
|
|
|
# and see if it looks like that they all begin with the
|
|
|
|
# header field names...
|
2010-01-26 08:33:59 +08:00
|
|
|
tr -d '\015' <"$1" |
|
|
|
|
sed -n -e '/^$/q' -e '/^[ ]/d' -e p |
|
2009-11-24 07:56:32 +08:00
|
|
|
sane_egrep -v '^[!-9;-~]+:' >/dev/null ||
|
2009-08-07 09:08:12 +08:00
|
|
|
patch_format=mbox
|
|
|
|
fi
|
2009-05-27 17:25:19 +08:00
|
|
|
} < "$1" || clean_abort
|
2009-05-27 17:25:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
split_patches () {
|
|
|
|
case "$patch_format" in
|
|
|
|
mbox)
|
2012-06-26 22:51:57 +08:00
|
|
|
if test t = "$keepcr"
|
2010-02-27 22:20:26 +08:00
|
|
|
then
|
|
|
|
keep_cr=--keep-cr
|
|
|
|
else
|
|
|
|
keep_cr=
|
|
|
|
fi
|
2009-08-05 11:31:59 +08:00
|
|
|
git mailsplit -d"$prec" -o"$dotest" -b $keep_cr -- "$@" > "$dotest/last" ||
|
2009-05-27 17:25:19 +08:00
|
|
|
clean_abort
|
2009-05-27 17:25:16 +08:00
|
|
|
;;
|
2009-05-27 17:25:18 +08:00
|
|
|
stgit-series)
|
|
|
|
if test $# -ne 1
|
|
|
|
then
|
2011-05-22 02:43:49 +08:00
|
|
|
clean_abort "$(gettext "Only one StGIT patch series can be applied at once")"
|
2009-05-27 17:25:18 +08:00
|
|
|
fi
|
2014-03-26 01:22:22 +08:00
|
|
|
series_dir=$(dirname "$1")
|
2009-05-27 17:25:18 +08:00
|
|
|
series_file="$1"
|
|
|
|
shift
|
|
|
|
{
|
|
|
|
set x
|
|
|
|
while read filename
|
|
|
|
do
|
|
|
|
set "$@" "$series_dir/$filename"
|
|
|
|
done
|
|
|
|
# remove the safety x
|
|
|
|
shift
|
|
|
|
# remove the arg coming from the first-line comment
|
|
|
|
shift
|
2009-05-27 17:25:19 +08:00
|
|
|
} < "$series_file" || clean_abort
|
2009-05-27 17:25:18 +08:00
|
|
|
# set the patch format appropriately
|
|
|
|
patch_format=stgit
|
|
|
|
# now handle the actual StGIT patches
|
|
|
|
split_patches "$@"
|
|
|
|
;;
|
|
|
|
stgit)
|
|
|
|
this=0
|
2015-06-15 19:08:10 +08:00
|
|
|
test 0 -eq "$#" && set -- -
|
2009-05-27 17:25:18 +08:00
|
|
|
for stgit in "$@"
|
|
|
|
do
|
2014-03-26 01:22:22 +08:00
|
|
|
this=$(expr "$this" + 1)
|
|
|
|
msgnum=$(printf "%0${prec}d" $this)
|
2009-05-27 17:25:18 +08:00
|
|
|
# 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
|
2013-10-29 09:19:59 +08:00
|
|
|
@@PERL@@ -ne 'BEGIN { $subject = 0 }
|
2009-05-27 17:25:18 +08:00
|
|
|
if ($subject > 1) { print ; }
|
|
|
|
elsif (/^\s+$/) { next ; }
|
2011-08-30 00:44:07 +08:00
|
|
|
elsif (/^Author:/) { s/Author/From/ ; print ;}
|
2009-05-27 17:25:18 +08:00
|
|
|
elsif (/^(From|Date)/) { print ; }
|
|
|
|
elsif ($subject) {
|
|
|
|
$subject = 2 ;
|
|
|
|
print "\n" ;
|
|
|
|
print ;
|
|
|
|
} else {
|
|
|
|
print "Subject: ", $_ ;
|
|
|
|
$subject = 1;
|
|
|
|
}
|
2015-06-15 19:08:10 +08:00
|
|
|
' -- "$stgit" >"$dotest/$msgnum" || clean_abort
|
2009-05-27 17:25:18 +08:00
|
|
|
done
|
|
|
|
echo "$this" > "$dotest/last"
|
|
|
|
this=
|
|
|
|
msgnum=
|
|
|
|
;;
|
2011-08-30 00:44:06 +08:00
|
|
|
hg)
|
|
|
|
this=0
|
2015-06-15 19:08:13 +08:00
|
|
|
test 0 -eq "$#" && set -- -
|
2011-08-30 00:44:06 +08:00
|
|
|
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
|
2013-10-29 09:19:59 +08:00
|
|
|
LANG=C LC_ALL=C @@PERL@@ -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
|
2011-08-30 00:44:06 +08:00
|
|
|
if ($subject) { print ; }
|
|
|
|
elsif (/^\# User /) { s/\# User/From:/ ; print ; }
|
|
|
|
elsif (/^\# Date /) {
|
|
|
|
my ($hashsign, $str, $time, $tz) = split ;
|
am: use gmtime() to parse mercurial patch date
An example of the line in a mercurial patch that specifies the date of
the commit would be:
# Date 1433753301 25200
where the first number is the number of seconds since the unix epoch (in
UTC), and the second number is the offset of the timezone, in second s
west of UTC (negative if the timezone is east of UTC).
git-am uses localtime() to break down the first number into its
components (year, month, day, hours, minutes, seconds etc.). However,
the returned components are relative to the user's time zone. As a
result, if the user's time zone does not match the time zone specified
in the patch, the resulting commit will have the wrong author date.
Fix this by using gmtime() instead, which uses UTC instead of the user's
time zone.
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-15 19:08:12 +08:00
|
|
|
$tz_str = sprintf "%+05d", (0-$tz)/36;
|
2011-08-30 00:44:06 +08:00
|
|
|
print "Date: " .
|
|
|
|
strftime("%a, %d %b %Y %H:%M:%S ",
|
am: use gmtime() to parse mercurial patch date
An example of the line in a mercurial patch that specifies the date of
the commit would be:
# Date 1433753301 25200
where the first number is the number of seconds since the unix epoch (in
UTC), and the second number is the offset of the timezone, in second s
west of UTC (negative if the timezone is east of UTC).
git-am uses localtime() to break down the first number into its
components (year, month, day, hours, minutes, seconds etc.). However,
the returned components are relative to the user's time zone. As a
result, if the user's time zone does not match the time zone specified
in the patch, the resulting commit will have the wrong author date.
Fix this by using gmtime() instead, which uses UTC instead of the user's
time zone.
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-15 19:08:12 +08:00
|
|
|
gmtime($time-$tz))
|
|
|
|
. "$tz_str\n";
|
2011-08-30 00:44:06 +08:00
|
|
|
} elsif (/^\# /) { next ; }
|
|
|
|
else {
|
|
|
|
print "\n", $_ ;
|
|
|
|
$subject = 1;
|
|
|
|
}
|
2015-06-15 19:08:13 +08:00
|
|
|
' -- "$hg" >"$dotest/$msgnum" || clean_abort
|
2011-08-30 00:44:06 +08:00
|
|
|
done
|
|
|
|
echo "$this" >"$dotest/last"
|
|
|
|
this=
|
|
|
|
msgnum=
|
|
|
|
;;
|
2009-05-27 17:25:16 +08:00
|
|
|
*)
|
2011-08-29 23:22:06 +08:00
|
|
|
if test -n "$patch_format"
|
|
|
|
then
|
2011-05-22 02:43:49 +08:00
|
|
|
clean_abort "$(eval_gettext "Patch format \$patch_format is not supported.")"
|
2009-08-07 09:08:13 +08:00
|
|
|
else
|
2011-05-22 02:43:49 +08:00
|
|
|
clean_abort "$(gettext "Patch format detection failed.")"
|
2009-08-07 09:08:13 +08:00
|
|
|
fi
|
2009-05-27 17:25:16 +08:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2005-10-07 18:44:18 +08:00
|
|
|
prec=4
|
2008-07-21 18:51:02 +08:00
|
|
|
dotest="$GIT_DIR/rebase-apply"
|
2010-02-27 22:20:26 +08:00
|
|
|
sign= utf8=t keep= keepcr= skip= interactive= resolved= rebasing= abort=
|
2014-11-25 22:00:56 +08:00
|
|
|
messageid= resolvemsg= resume= scissors= no_inbody_headers=
|
2007-02-08 21:57:08 +08:00
|
|
|
git_apply_opt=
|
2009-01-23 08:14:58 +08:00
|
|
|
committer_date_is_author_date=
|
2009-01-24 09:18:02 +08:00
|
|
|
ignore_date=
|
2009-12-04 16:20:48 +08:00
|
|
|
allow_rerere_autoupdate=
|
2014-02-01 10:18:01 +08:00
|
|
|
gpg_sign_opt=
|
2015-06-04 23:04:53 +08:00
|
|
|
threeway=
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2014-11-25 22:00:56 +08:00
|
|
|
if test "$(git config --bool --get am.messageid)" = true
|
|
|
|
then
|
|
|
|
messageid=t
|
|
|
|
fi
|
|
|
|
|
2010-02-27 22:20:27 +08:00
|
|
|
if test "$(git config --bool --get am.keepcr)" = true
|
|
|
|
then
|
|
|
|
keepcr=t
|
|
|
|
fi
|
|
|
|
|
2007-09-24 04:42:08 +08:00
|
|
|
while test $# != 0
|
2005-10-07 18:44:18 +08:00
|
|
|
do
|
|
|
|
case "$1" in
|
2007-11-04 18:30:57 +08:00
|
|
|
-i|--interactive)
|
|
|
|
interactive=t ;;
|
|
|
|
-b|--binary)
|
2012-07-25 22:53:11 +08:00
|
|
|
gettextln >&2 "The -b/--binary option has been a no-op for long time, and
|
|
|
|
it will be removed. Please do not use it anymore."
|
2012-03-13 05:47:19 +08:00
|
|
|
;;
|
2007-11-04 18:30:57 +08:00
|
|
|
-3|--3way)
|
|
|
|
threeway=t ;;
|
2007-11-07 04:33:58 +08:00
|
|
|
-s|--signoff)
|
2007-11-04 18:30:57 +08:00
|
|
|
sign=t ;;
|
|
|
|
-u|--utf8)
|
|
|
|
utf8=t ;; # this is now default
|
|
|
|
--no-utf8)
|
|
|
|
utf8= ;;
|
2014-11-25 22:00:56 +08:00
|
|
|
-m|--message-id)
|
|
|
|
messageid=t ;;
|
|
|
|
--no-message-id)
|
|
|
|
messageid=f ;;
|
2007-11-04 18:30:57 +08:00
|
|
|
-k|--keep)
|
|
|
|
keep=t ;;
|
2012-01-16 18:53:00 +08:00
|
|
|
--keep-non-patch)
|
|
|
|
keep=b ;;
|
2009-08-27 12:36:05 +08:00
|
|
|
-c|--scissors)
|
|
|
|
scissors=t ;;
|
|
|
|
--no-scissors)
|
|
|
|
scissors=f ;;
|
2010-02-12 06:27:14 +08:00
|
|
|
-r|--resolved|--continue)
|
2007-11-04 18:30:57 +08:00
|
|
|
resolved=t ;;
|
|
|
|
--skip)
|
|
|
|
skip=t ;;
|
2008-07-16 18:39:10 +08:00
|
|
|
--abort)
|
|
|
|
abort=t ;;
|
2008-03-04 16:25:06 +08:00
|
|
|
--rebasing)
|
2012-06-26 22:51:57 +08:00
|
|
|
rebasing=t threeway=t ;;
|
2014-02-01 10:18:00 +08:00
|
|
|
--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=}" ;;
|
2009-08-04 19:16:49 +08:00
|
|
|
--reject|--ignore-whitespace|--ignore-space-change)
|
2009-01-23 08:31:21 +08:00
|
|
|
git_apply_opt="$git_apply_opt $1" ;;
|
2009-01-23 08:14:58 +08:00
|
|
|
--committer-date-is-author-date)
|
|
|
|
committer_date_is_author_date=t ;;
|
2009-01-24 09:18:02 +08:00
|
|
|
--ignore-date)
|
|
|
|
ignore_date=t ;;
|
2009-12-04 16:20:48 +08:00
|
|
|
--rerere-autoupdate|--no-rerere-autoupdate)
|
|
|
|
allow_rerere_autoupdate="$1" ;;
|
2009-06-17 06:33:01 +08:00
|
|
|
-q|--quiet)
|
|
|
|
GIT_QUIET=t ;;
|
2010-02-27 22:20:26 +08:00
|
|
|
--keep-cr)
|
|
|
|
keepcr=t ;;
|
2010-02-27 22:20:27 +08:00
|
|
|
--no-keep-cr)
|
|
|
|
keepcr=f ;;
|
2014-02-01 10:18:01 +08:00
|
|
|
--gpg-sign)
|
|
|
|
gpg_sign_opt=-S ;;
|
|
|
|
--gpg-sign=*)
|
|
|
|
gpg_sign_opt="-S${1#--gpg-sign=}" ;;
|
2005-10-07 18:44:18 +08:00
|
|
|
--)
|
2007-11-04 18:30:57 +08:00
|
|
|
shift; break ;;
|
2005-10-07 18:44:18 +08:00
|
|
|
*)
|
2007-11-04 18:30:57 +08:00
|
|
|
usage ;;
|
2005-10-07 18:44:18 +08:00
|
|
|
esac
|
2007-11-04 18:30:57 +08:00
|
|
|
shift
|
2005-10-07 18:44:18 +08:00
|
|
|
done
|
|
|
|
|
2005-11-16 16:19:32 +08:00
|
|
|
# If the dotest directory exists, but we have finished applying all the
|
|
|
|
# patches in them, clear it out.
|
2005-10-07 18:44:18 +08:00
|
|
|
if test -d "$dotest" &&
|
2013-05-12 19:56:35 +08:00
|
|
|
test -f "$dotest/last" &&
|
|
|
|
test -f "$dotest/next" &&
|
2005-10-07 18:44:18 +08:00
|
|
|
last=$(cat "$dotest/last") &&
|
|
|
|
next=$(cat "$dotest/next") &&
|
|
|
|
test $# != 0 &&
|
|
|
|
test "$next" -gt "$last"
|
|
|
|
then
|
|
|
|
rm -fr "$dotest"
|
|
|
|
fi
|
|
|
|
|
2013-05-12 19:56:35 +08:00
|
|
|
if test -d "$dotest" && test -f "$dotest/last" && test -f "$dotest/next"
|
2005-10-07 18:44:18 +08:00
|
|
|
then
|
2008-07-16 18:39:10 +08:00
|
|
|
case "$#,$skip$resolved$abort" in
|
2006-09-16 14:19:02 +08:00
|
|
|
0,*t*)
|
|
|
|
# Explicit resume command and we do not have file, so
|
|
|
|
# we are happy.
|
|
|
|
: ;;
|
|
|
|
0,)
|
|
|
|
# No file input but without resume parameters; catch
|
|
|
|
# user error to feed us a patch from standard input
|
2008-03-04 16:25:05 +08:00
|
|
|
# when there is already $dotest. This is somewhat
|
2006-09-16 14:19:02 +08:00
|
|
|
# unreliable -- stdin could be /dev/null for example
|
|
|
|
# and the caller did not intend to feed us a patch but
|
|
|
|
# wanted to continue unattended.
|
2009-01-28 23:03:10 +08:00
|
|
|
test -t 0
|
2006-09-16 14:19:02 +08:00
|
|
|
;;
|
|
|
|
*)
|
|
|
|
false
|
|
|
|
;;
|
|
|
|
esac ||
|
2011-05-22 02:43:47 +08:00
|
|
|
die "$(eval_gettext "previous rebase directory \$dotest still exists but mbox given.")"
|
2005-10-26 14:35:37 +08:00
|
|
|
resume=yes
|
2008-07-16 18:39:10 +08:00
|
|
|
|
2008-07-21 21:39:06 +08:00
|
|
|
case "$skip,$abort" in
|
2009-02-27 03:24:29 +08:00
|
|
|
t,t)
|
2011-05-22 02:43:47 +08:00
|
|
|
die "$(gettext "Please make up your mind. --skip or --abort?")"
|
2009-02-27 03:24:29 +08:00
|
|
|
;;
|
2008-07-21 21:39:06 +08:00
|
|
|
t,)
|
|
|
|
git rerere clear
|
2015-06-06 19:46:07 +08:00
|
|
|
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
|
2015-06-06 19:46:09 +08:00
|
|
|
git read-tree $head_tree
|
2008-07-21 21:39:06 +08:00
|
|
|
;;
|
|
|
|
,t)
|
2009-02-27 03:24:29 +08:00
|
|
|
if test -f "$dotest/rebasing"
|
|
|
|
then
|
|
|
|
exec git rebase --abort
|
|
|
|
fi
|
2008-07-16 18:39:10 +08:00
|
|
|
git rerere clear
|
2010-12-22 02:35:53 +08:00
|
|
|
if safe_to_abort
|
|
|
|
then
|
2015-06-06 19:46:10 +08:00
|
|
|
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
|
2015-06-06 19:46:11 +08:00
|
|
|
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
|
2010-12-22 02:35:53 +08:00
|
|
|
fi
|
2008-07-16 18:39:10 +08:00
|
|
|
rm -fr "$dotest"
|
|
|
|
exit ;;
|
|
|
|
esac
|
2009-02-26 17:52:53 +08:00
|
|
|
rm -f "$dotest/dirtyindex"
|
2005-10-07 18:44:18 +08:00
|
|
|
else
|
2013-06-15 20:43:11 +08:00
|
|
|
# Possible stray $dotest directory in the independent-run
|
|
|
|
# case; in the --rebasing case, it is upto the caller
|
|
|
|
# (git-rebase--am) to take care of stray directories.
|
|
|
|
if test -d "$dotest" && test -z "$rebasing"
|
|
|
|
then
|
|
|
|
case "$skip,$resolved,$abort" in
|
|
|
|
,,t)
|
|
|
|
rm -fr "$dotest"
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
die "$(eval_gettext "Stray \$dotest directory found.
|
|
|
|
Use \"git am --abort\" to remove it.")"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
fi
|
|
|
|
|
2014-04-01 06:11:46 +08:00
|
|
|
# Make sure we are not given --skip, --continue, or --abort
|
2008-07-16 18:39:10 +08:00
|
|
|
test "$skip$resolved$abort" = "" ||
|
2011-05-22 02:43:47 +08:00
|
|
|
die "$(gettext "Resolve operation not in progress, we are not resuming.")"
|
2005-10-07 18:44:18 +08:00
|
|
|
|
|
|
|
# Start afresh.
|
|
|
|
mkdir -p "$dotest" || exit
|
|
|
|
|
2008-03-04 16:25:04 +08:00
|
|
|
if test -n "$prefix" && test $# != 0
|
|
|
|
then
|
|
|
|
first=t
|
|
|
|
for arg
|
|
|
|
do
|
|
|
|
test -n "$first" && {
|
|
|
|
set x
|
|
|
|
first=
|
|
|
|
}
|
2010-09-30 21:24:07 +08:00
|
|
|
if is_absolute_path "$arg"
|
|
|
|
then
|
|
|
|
set "$@" "$arg"
|
|
|
|
else
|
|
|
|
set "$@" "$prefix$arg"
|
|
|
|
fi
|
2008-03-04 16:25:04 +08:00
|
|
|
done
|
|
|
|
shift
|
|
|
|
fi
|
2009-05-27 17:25:16 +08:00
|
|
|
|
|
|
|
check_patch_format "$@"
|
|
|
|
|
|
|
|
split_patches "$@"
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2009-08-27 12:36:05 +08:00
|
|
|
# -i can and must be given when resuming; everything
|
|
|
|
# else is kept
|
2008-12-06 03:19:43 +08:00
|
|
|
echo " $git_apply_opt" >"$dotest/apply-opt"
|
2008-12-05 07:38:27 +08:00
|
|
|
echo "$threeway" >"$dotest/threeway"
|
2005-10-07 18:44:18 +08:00
|
|
|
echo "$sign" >"$dotest/sign"
|
|
|
|
echo "$utf8" >"$dotest/utf8"
|
|
|
|
echo "$keep" >"$dotest/keep"
|
2014-11-25 22:00:56 +08:00
|
|
|
echo "$messageid" >"$dotest/messageid"
|
2009-08-27 12:36:05 +08:00
|
|
|
echo "$scissors" >"$dotest/scissors"
|
2009-11-21 00:12:47 +08:00
|
|
|
echo "$no_inbody_headers" >"$dotest/no_inbody_headers"
|
2009-06-17 06:33:01 +08:00
|
|
|
echo "$GIT_QUIET" >"$dotest/quiet"
|
2005-10-07 18:44:18 +08:00
|
|
|
echo 1 >"$dotest/next"
|
2008-03-04 16:25:06 +08:00
|
|
|
if test -n "$rebasing"
|
|
|
|
then
|
|
|
|
: >"$dotest/rebasing"
|
|
|
|
else
|
|
|
|
: >"$dotest/applying"
|
2009-04-10 08:34:42 +08:00
|
|
|
if test -n "$HAS_HEAD"
|
|
|
|
then
|
|
|
|
git update-ref ORIG_HEAD HEAD
|
|
|
|
else
|
|
|
|
git update-ref -d ORIG_HEAD >/dev/null 2>&1
|
|
|
|
fi
|
2008-03-04 16:25:06 +08:00
|
|
|
fi
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
|
|
|
|
2011-08-16 08:13:07 +08:00
|
|
|
git update-index -q --refresh
|
|
|
|
|
2005-11-16 16:19:32 +08:00
|
|
|
case "$resolved" in
|
|
|
|
'')
|
2009-04-10 08:34:42 +08:00
|
|
|
case "$HAS_HEAD" in
|
|
|
|
'')
|
|
|
|
files=$(git ls-files) ;;
|
|
|
|
?*)
|
|
|
|
files=$(git diff-index --cached --name-only HEAD --) ;;
|
|
|
|
esac || exit
|
2009-02-26 17:52:53 +08:00
|
|
|
if test "$files"
|
|
|
|
then
|
2009-04-10 08:34:42 +08:00
|
|
|
test -n "$HAS_HEAD" && : >"$dotest/dirtyindex"
|
2011-05-22 02:43:47 +08:00
|
|
|
die "$(eval_gettext "Dirty index: cannot apply patches (dirty: \$files)")"
|
2009-02-26 17:52:53 +08:00
|
|
|
fi
|
2005-11-16 16:19:32 +08:00
|
|
|
esac
|
|
|
|
|
2012-01-16 18:53:00 +08:00
|
|
|
# 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.
|
|
|
|
|
2005-10-07 18:44:18 +08:00
|
|
|
if test "$(cat "$dotest/utf8")" = t
|
|
|
|
then
|
|
|
|
utf8=-u
|
2007-01-10 13:31:36 +08:00
|
|
|
else
|
|
|
|
utf8=-n
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
2012-01-16 18:53:00 +08:00
|
|
|
keep=$(cat "$dotest/keep")
|
|
|
|
case "$keep" in
|
|
|
|
t)
|
|
|
|
keep=-k ;;
|
|
|
|
b)
|
|
|
|
keep=-b ;;
|
|
|
|
*)
|
|
|
|
keep= ;;
|
|
|
|
esac
|
2014-11-25 22:00:56 +08:00
|
|
|
case "$(cat "$dotest/messageid")" in
|
|
|
|
t)
|
|
|
|
messageid=-m ;;
|
|
|
|
f)
|
|
|
|
messageid= ;;
|
|
|
|
esac
|
2009-08-27 12:36:05 +08:00
|
|
|
case "$(cat "$dotest/scissors")" in
|
|
|
|
t)
|
|
|
|
scissors=--scissors ;;
|
|
|
|
f)
|
|
|
|
scissors=--no-scissors ;;
|
|
|
|
esac
|
2009-11-21 00:12:47 +08:00
|
|
|
if test "$(cat "$dotest/no_inbody_headers")" = t
|
|
|
|
then
|
|
|
|
no_inbody_headers=--no-inbody-headers
|
|
|
|
else
|
|
|
|
no_inbody_headers=
|
|
|
|
fi
|
2009-06-17 06:33:01 +08:00
|
|
|
if test "$(cat "$dotest/quiet")" = t
|
|
|
|
then
|
|
|
|
GIT_QUIET=t
|
|
|
|
fi
|
2008-12-05 07:38:27 +08:00
|
|
|
if test "$(cat "$dotest/threeway")" = t
|
|
|
|
then
|
|
|
|
threeway=t
|
|
|
|
fi
|
2008-12-06 03:19:43 +08:00
|
|
|
git_apply_opt=$(cat "$dotest/apply-opt")
|
2005-10-07 18:44:18 +08:00
|
|
|
if test "$(cat "$dotest/sign")" = t
|
|
|
|
then
|
2014-03-26 01:22:22 +08:00
|
|
|
SIGNOFF=$(git var GIT_COMMITTER_IDENT | sed -e '
|
2005-10-07 18:44:18 +08:00
|
|
|
s/>.*/>/
|
|
|
|
s/^/Signed-off-by: /'
|
2014-03-26 01:22:22 +08:00
|
|
|
)
|
2005-10-07 18:44:18 +08:00
|
|
|
else
|
|
|
|
SIGNOFF=
|
|
|
|
fi
|
|
|
|
|
2014-03-26 01:22:22 +08:00
|
|
|
last=$(cat "$dotest/last")
|
|
|
|
this=$(cat "$dotest/next")
|
2005-10-07 18:44:18 +08:00
|
|
|
if test "$skip" = t
|
|
|
|
then
|
2014-03-26 01:22:22 +08:00
|
|
|
this=$(expr "$this" + 1)
|
2005-12-17 14:01:06 +08:00
|
|
|
resume=
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
|
|
|
|
|
|
|
while test "$this" -le "$last"
|
|
|
|
do
|
2014-03-26 01:22:22 +08:00
|
|
|
msgnum=$(printf "%0${prec}d" $this)
|
|
|
|
next=$(expr "$this" + 1)
|
2005-10-07 18:44:18 +08:00
|
|
|
test -f "$dotest/$msgnum" || {
|
2005-12-17 14:01:06 +08:00
|
|
|
resume=
|
2005-10-07 18:44:18 +08:00
|
|
|
go_next
|
|
|
|
continue
|
|
|
|
}
|
2005-11-16 16:19:32 +08:00
|
|
|
|
|
|
|
# If we are not resuming, parse and extract the patch information
|
|
|
|
# into separate files:
|
|
|
|
# - info records the authorship and title
|
|
|
|
# - msg is the rest of commit log message
|
|
|
|
# - patch is the patch body.
|
|
|
|
#
|
|
|
|
# When we are resuming, these files are either already prepared
|
2013-06-27 04:06:41 +08:00
|
|
|
# by the user, or the user can tell us to do so by --continue flag.
|
2005-10-26 14:35:37 +08:00
|
|
|
case "$resume" in
|
|
|
|
'')
|
2012-06-26 22:51:57 +08:00
|
|
|
if test -f "$dotest/rebasing"
|
|
|
|
then
|
2008-04-17 03:50:48 +08:00
|
|
|
commit=$(sed -e 's/^From \([0-9a-f]*\) .*/\1/' \
|
|
|
|
-e q "$dotest/$msgnum") &&
|
2012-06-26 22:51:57 +08:00
|
|
|
test "$(git cat-file -t "$commit")" = commit ||
|
|
|
|
stop_here $this
|
2008-04-17 03:50:48 +08:00
|
|
|
git cat-file commit "$commit" |
|
|
|
|
sed -e '1,/^$/d' >"$dotest/msg-clean"
|
2012-06-26 22:51:57 +08:00
|
|
|
echo "$commit" >"$dotest/original-commit"
|
|
|
|
get_author_ident_from_commit "$commit" >"$dotest/author-script"
|
2013-02-01 11:26:21 +08:00
|
|
|
git diff-tree --root --binary --full-index "$commit" >"$dotest/patch"
|
2008-04-17 03:50:48 +08:00
|
|
|
else
|
2014-11-25 22:00:56 +08:00
|
|
|
git mailinfo $keep $no_inbody_headers $messageid $scissors $utf8 "$dotest/msg" "$dotest/patch" \
|
2012-06-26 22:51:57 +08:00
|
|
|
<"$dotest/$msgnum" >"$dotest/info" ||
|
|
|
|
stop_here $this
|
|
|
|
|
|
|
|
# skip pine's internal folder data
|
|
|
|
sane_grep '^Author: Mail System Internal Data$' \
|
|
|
|
<"$dotest"/info >/dev/null &&
|
|
|
|
go_next && continue
|
|
|
|
|
|
|
|
test -s "$dotest/patch" || {
|
|
|
|
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"
|
2009-11-28 07:06:37 +08:00
|
|
|
{
|
|
|
|
sed -n '/^Subject/ s/Subject: //p' "$dotest/info"
|
|
|
|
echo
|
|
|
|
cat "$dotest/msg"
|
|
|
|
} |
|
|
|
|
git stripspace > "$dotest/msg-clean"
|
2008-04-17 03:50:48 +08:00
|
|
|
fi
|
2005-10-26 14:35:37 +08:00
|
|
|
;;
|
|
|
|
esac
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2010-06-16 15:12:40 +08:00
|
|
|
if test -f "$dotest/author-script"
|
|
|
|
then
|
|
|
|
eval $(cat "$dotest/author-script")
|
|
|
|
else
|
|
|
|
GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$dotest/info")"
|
|
|
|
GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")"
|
|
|
|
GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")"
|
|
|
|
fi
|
2005-12-15 08:31:06 +08:00
|
|
|
|
2007-12-06 05:16:35 +08:00
|
|
|
if test -z "$GIT_AUTHOR_EMAIL"
|
2005-12-15 08:31:06 +08:00
|
|
|
then
|
2011-08-07 19:58:14 +08:00
|
|
|
gettextln "Patch does not have a valid e-mail address."
|
2005-12-15 08:31:06 +08:00
|
|
|
stop_here $this
|
|
|
|
fi
|
|
|
|
|
2005-10-21 13:31:56 +08:00
|
|
|
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2005-11-08 16:41:37 +08:00
|
|
|
case "$resume" in
|
|
|
|
'')
|
|
|
|
if test '' != "$SIGNOFF"
|
|
|
|
then
|
2014-03-26 01:22:22 +08:00
|
|
|
LAST_SIGNED_OFF_BY=$(
|
2005-11-08 16:41:37 +08:00
|
|
|
sed -ne '/^Signed-off-by: /p' \
|
|
|
|
"$dotest/msg-clean" |
|
2008-03-13 05:34:34 +08:00
|
|
|
sed -ne '$p'
|
2014-03-26 01:22:22 +08:00
|
|
|
)
|
|
|
|
ADD_SIGNOFF=$(
|
2005-11-08 16:41:37 +08:00
|
|
|
test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
|
2005-10-07 18:44:18 +08:00
|
|
|
test '' = "$LAST_SIGNED_OFF_BY" && echo
|
|
|
|
echo "$SIGNOFF"
|
2014-03-26 01:22:22 +08:00
|
|
|
})
|
2005-11-08 16:41:37 +08:00
|
|
|
else
|
2005-10-07 18:44:18 +08:00
|
|
|
ADD_SIGNOFF=
|
2005-11-08 16:41:37 +08:00
|
|
|
fi
|
|
|
|
{
|
2005-10-07 18:44:18 +08:00
|
|
|
if test -s "$dotest/msg-clean"
|
|
|
|
then
|
|
|
|
cat "$dotest/msg-clean"
|
|
|
|
fi
|
|
|
|
if test '' != "$ADD_SIGNOFF"
|
|
|
|
then
|
|
|
|
echo "$ADD_SIGNOFF"
|
|
|
|
fi
|
2005-11-08 16:41:37 +08:00
|
|
|
} >"$dotest/final-commit"
|
|
|
|
;;
|
2005-11-16 16:19:32 +08:00
|
|
|
*)
|
2006-02-24 14:14:47 +08:00
|
|
|
case "$resolved$interactive" in
|
2005-11-16 16:19:32 +08:00
|
|
|
tt)
|
|
|
|
# This is used only for interactive view option.
|
2007-11-29 08:15:04 +08:00
|
|
|
git diff-index -p --cached HEAD -- >"$dotest/patch"
|
2005-11-16 16:19:32 +08:00
|
|
|
;;
|
|
|
|
esac
|
2005-11-08 16:41:37 +08:00
|
|
|
esac
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2005-11-08 16:41:37 +08:00
|
|
|
resume=
|
2005-10-07 18:44:18 +08:00
|
|
|
if test "$interactive" = t
|
|
|
|
then
|
2005-10-13 09:31:41 +08:00
|
|
|
test -t 0 ||
|
2011-05-22 02:43:47 +08:00
|
|
|
die "$(gettext "cannot be interactive without stdin connected to a terminal.")"
|
2005-10-07 18:44:18 +08:00
|
|
|
action=again
|
|
|
|
while test "$action" = again
|
|
|
|
do
|
2011-08-07 19:58:14 +08:00
|
|
|
gettextln "Commit Body is:"
|
2005-10-07 18:44:18 +08:00
|
|
|
echo "--------------------------"
|
|
|
|
cat "$dotest/final-commit"
|
|
|
|
echo "--------------------------"
|
2011-05-22 02:43:50 +08:00
|
|
|
# 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 "
|
2005-10-07 18:44:18 +08:00
|
|
|
read reply
|
|
|
|
case "$reply" in
|
2005-10-26 14:43:59 +08:00
|
|
|
[yY]*) action=yes ;;
|
|
|
|
[aA]*) action=yes interactive= ;;
|
|
|
|
[nN]*) action=skip ;;
|
2007-07-20 13:09:35 +08:00
|
|
|
[eE]*) git_editor "$dotest/final-commit"
|
2005-10-07 18:44:18 +08:00
|
|
|
action=again ;;
|
2005-10-26 14:43:59 +08:00
|
|
|
[vV]*) action=again
|
2010-02-15 13:04:13 +08:00
|
|
|
git_pager "$dotest/patch" ;;
|
2005-10-26 14:43:59 +08:00
|
|
|
*) action=again ;;
|
2005-10-07 18:44:18 +08:00
|
|
|
esac
|
|
|
|
done
|
|
|
|
else
|
|
|
|
action=yes
|
|
|
|
fi
|
2010-06-02 16:33:37 +08:00
|
|
|
|
2005-10-07 18:44:18 +08:00
|
|
|
if test $action = skip
|
|
|
|
then
|
|
|
|
go_next
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
2014-11-30 16:24:38 +08:00
|
|
|
hook="$(git rev-parse --git-path hooks/applypatch-msg)"
|
|
|
|
if test -x "$hook"
|
2005-10-07 18:44:18 +08:00
|
|
|
then
|
2014-11-30 16:24:38 +08:00
|
|
|
"$hook" "$dotest/final-commit" || stop_here $this
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
|
|
|
|
2013-03-21 10:40:17 +08:00
|
|
|
if test -f "$dotest/final-commit"
|
|
|
|
then
|
|
|
|
FIRSTLINE=$(sed 1q "$dotest/final-commit")
|
|
|
|
else
|
|
|
|
FIRSTLINE=""
|
|
|
|
fi
|
|
|
|
|
2011-05-22 02:43:52 +08:00
|
|
|
say "$(eval_gettext "Applying: \$FIRSTLINE")"
|
2005-10-07 18:44:18 +08:00
|
|
|
|
2005-11-16 16:19:32 +08:00
|
|
|
case "$resolved" in
|
|
|
|
'')
|
2009-06-17 06:32:58 +08:00
|
|
|
# When we are allowed to fall back to 3-way later, don't give
|
|
|
|
# false errors during the initial attempt.
|
|
|
|
squelch=
|
|
|
|
if test "$threeway" = t
|
|
|
|
then
|
|
|
|
squelch='>/dev/null 2>&1 '
|
|
|
|
fi
|
|
|
|
eval "git apply $squelch$git_apply_opt"' --index "$dotest/patch"'
|
2005-11-16 16:19:32 +08:00
|
|
|
apply_status=$?
|
|
|
|
;;
|
|
|
|
t)
|
|
|
|
# Resolved means the user did all the hard work, and
|
|
|
|
# we do not have to do any patch application. Just
|
|
|
|
# trust what the user has in the index file and the
|
|
|
|
# working tree.
|
|
|
|
resolved=
|
2007-11-29 08:15:04 +08:00
|
|
|
git diff-index --quiet --cached HEAD -- && {
|
2011-08-07 19:58:14 +08:00
|
|
|
gettextln "No changes - did you forget to use 'git add'?
|
2011-05-22 02:43:44 +08:00
|
|
|
If there is nothing left to stage, chances are that something else
|
2011-08-07 19:58:14 +08:00
|
|
|
already introduced the same changes; you might want to skip this patch."
|
2006-05-02 20:32:43 +08:00
|
|
|
stop_here_user_resolve $this
|
2007-03-25 08:56:13 +08:00
|
|
|
}
|
2007-07-03 13:52:14 +08:00
|
|
|
unmerged=$(git ls-files -u)
|
2006-04-28 17:32:44 +08:00
|
|
|
if test -n "$unmerged"
|
|
|
|
then
|
2011-08-07 19:58:14 +08:00
|
|
|
gettextln "You still have unmerged paths in your index
|
|
|
|
did you forget to use 'git add'?"
|
2006-05-02 20:32:43 +08:00
|
|
|
stop_here_user_resolve $this
|
2006-04-28 17:32:44 +08:00
|
|
|
fi
|
2005-11-16 16:19:32 +08:00
|
|
|
apply_status=0
|
2007-07-06 20:05:59 +08:00
|
|
|
git rerere
|
2005-11-16 16:19:32 +08:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
am -3: recover the diagnostic messages for corrupt patches
"git am -3" first tries to apply the patch without any extra trick, and
applies it to a synthesized tree for 3-way merge after the first attempt
fails. "git apply" exits with status 1 for a patch that is well-formed
but is not applicable (and it dies on other errors with non-zereo, non-1
status) and has an optimization to fall back to the 3-way merge only in
the case.
An earlier patch 3ddd170 (am: suppress apply errors when using 3-way,
2009-06-16) squelched diagnostic messages from the first attempt, not to
be shown to the end user. This worked reasonably well if the reason the
first application failed was because the patch was made against a wrong
version.
When the patch is corrupt (e.g. line-wrapped or leading whitespaces got
dropped), however, because the second patch application is not even
attempted, the error message from the first application is never shown
and is forever lost. This message is necessary to locate where the patch
is corrupt and fix it up.
We could fix this issue by reverting 3dd170, or keeping the error message
to somewhere and showing it, but because this is an error codepath, the
easiest is to disable the optimization. The second patch application is
attempted even when the input is corrupt, and it will notice, diagnose,
and stop with an error message.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-10 07:58:28 +08:00
|
|
|
if test $apply_status != 0 && test "$threeway" = t
|
2005-10-07 18:44:18 +08:00
|
|
|
then
|
2005-10-14 02:46:43 +08:00
|
|
|
if (fall_back_3way)
|
2005-10-07 18:44:18 +08:00
|
|
|
then
|
2005-10-14 02:46:43 +08:00
|
|
|
# Applying the patch to an earlier tree and merging the
|
|
|
|
# result may have produced the same tree as ours.
|
2007-11-29 08:15:04 +08:00
|
|
|
git diff-index --quiet --cached HEAD -- && {
|
2011-05-22 02:43:52 +08:00
|
|
|
say "$(gettext "No changes -- Patch already applied.")"
|
2007-03-25 08:56:13 +08:00
|
|
|
go_next
|
|
|
|
continue
|
|
|
|
}
|
2005-10-14 02:46:43 +08:00
|
|
|
# clear apply_status -- we have successfully merged.
|
|
|
|
apply_status=0
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if test $apply_status != 0
|
|
|
|
then
|
2011-08-07 19:58:14 +08:00
|
|
|
eval_gettextln 'Patch failed at $msgnum $FIRSTLINE'
|
2012-07-13 23:51:30 +08:00
|
|
|
if test "$(git config --bool advice.amworkdir)" != false
|
|
|
|
then
|
2012-08-22 22:48:03 +08:00
|
|
|
eval_gettextln 'The copy of the patch that failed is found in:
|
|
|
|
$dotest/patch'
|
2012-07-13 23:51:30 +08:00
|
|
|
fi
|
2006-05-02 20:32:43 +08:00
|
|
|
stop_here_user_resolve $this
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
|
|
|
|
2014-11-30 16:24:38 +08:00
|
|
|
hook="$(git rev-parse --git-path hooks/pre-applypatch)"
|
|
|
|
if test -x "$hook"
|
2005-10-07 18:44:18 +08:00
|
|
|
then
|
2014-11-30 16:24:38 +08:00
|
|
|
"$hook" || stop_here $this
|
2005-10-07 18:44:18 +08:00
|
|
|
fi
|
|
|
|
|
2007-07-03 13:52:14 +08:00
|
|
|
tree=$(git write-tree) &&
|
2009-01-23 08:14:58 +08:00
|
|
|
commit=$(
|
2009-01-24 09:18:02 +08:00
|
|
|
if test -n "$ignore_date"
|
|
|
|
then
|
|
|
|
GIT_AUTHOR_DATE=
|
|
|
|
fi
|
2009-04-10 08:34:42 +08:00
|
|
|
parent=$(git rev-parse --verify -q HEAD) ||
|
2011-05-22 02:43:52 +08:00
|
|
|
say >&2 "$(gettext "applying to an empty history")"
|
2009-04-10 08:34:42 +08:00
|
|
|
|
2009-01-23 08:14:58 +08:00
|
|
|
if test -n "$committer_date_is_author_date"
|
|
|
|
then
|
|
|
|
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
|
|
|
|
export GIT_COMMITTER_DATE
|
|
|
|
fi &&
|
2014-02-01 10:18:01 +08:00
|
|
|
git commit-tree ${parent:+-p} $parent ${gpg_sign_opt:+"$gpg_sign_opt"} $tree \
|
|
|
|
<"$dotest/final-commit"
|
2009-01-23 08:14:58 +08:00
|
|
|
) &&
|
2008-04-16 03:56:50 +08:00
|
|
|
git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent ||
|
2005-10-07 18:44:18 +08:00
|
|
|
stop_here $this
|
|
|
|
|
2010-03-13 01:04:29 +08:00
|
|
|
if test -f "$dotest/original-commit"; then
|
|
|
|
echo "$(cat "$dotest/original-commit") $commit" >> "$dotest/rewritten"
|
|
|
|
fi
|
|
|
|
|
2014-11-30 16:24:38 +08:00
|
|
|
hook="$(git rev-parse --git-path hooks/post-applypatch)"
|
|
|
|
test -x "$hook" && "$hook"
|
2005-10-07 18:44:18 +08:00
|
|
|
|
|
|
|
go_next
|
|
|
|
done
|
|
|
|
|
2010-03-13 01:04:33 +08:00
|
|
|
if test -s "$dotest"/rewritten; then
|
|
|
|
git notes copy --for-rewrite=rebase < "$dotest"/rewritten
|
2014-11-30 16:24:38 +08:00
|
|
|
hook="$(git rev-parse --git-path hooks/post-rewrite)"
|
|
|
|
if test -x "$hook"; then
|
|
|
|
"$hook" rebase < "$dotest"/rewritten
|
2010-03-13 01:04:33 +08:00
|
|
|
fi
|
2010-03-13 01:04:29 +08:00
|
|
|
fi
|
|
|
|
|
2013-05-12 19:56:38 +08:00
|
|
|
# If am was called with --rebasing (from git-rebase--am), it's up to
|
|
|
|
# the caller to take care of housekeeping.
|
|
|
|
if ! test -f "$dotest/rebasing"
|
|
|
|
then
|
|
|
|
rm -fr "$dotest"
|
|
|
|
git gc --auto
|
|
|
|
fi
|