diff --git a/git-am.sh b/git-am.sh
index 4b157fe5d536fdbdbf85e0e06c419b5927a90867..58d4eb6d2dc2eaa99ae0c70a414813cd0ce43e43 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
git am [options] [<mbox>|<Maildir>...]
git am [options] (--resolved | --skip | --abort)
--
git am [options] [<mbox>|<Maildir>...]
git am [options] (--resolved | --skip | --abort)
--
-d,dotest= (removed -- do not use)
i,interactive run interactively
i,interactive run interactively
-b,binary (historical option -- no-op)
+b,binary* (historical option -- no-op)
3,3way allow fall back on 3way merging if needed
3,3way allow fall back on 3way merging if needed
+q,quiet be quiet
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
whitespace= pass it through git-apply
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
whitespace= pass it through git-apply
+directory= pass it through git-apply
C= pass it through git-apply
p= pass it through git-apply
C= pass it through git-apply
p= pass it through git-apply
+reject pass it through git-apply
resolvemsg= override error message when patch failure occurs
r,resolved to be used after a patch failure
skip skip the current patch
abort restore the original branch and abort the patching operation.
resolvemsg= override error message when patch failure occurs
r,resolved to be used after a patch failure
skip skip the current patch
abort restore the original branch and abort the patching operation.
-rebasing (internal use for git-rebase)"
+committer-date-is-author-date lie about committer date
+ignore-date use current timestamp for author date
+rebasing* (internal use for git-rebase)"
. git-sh-setup
prefix=$(git rev-parse --show-prefix)
. git-sh-setup
prefix=$(git rev-parse --show-prefix)
git var GIT_COMMITTER_IDENT >/dev/null ||
die "You need to set your committer info first"
git var GIT_COMMITTER_IDENT >/dev/null ||
die "You need to set your committer info first"
+if git rev-parse --verify -q HEAD >/dev/null
+then
+ HAS_HEAD=yes
+else
+ HAS_HEAD=
+fi
+
+sq () {
+ git rev-parse --sq-quote "$@"
+}
+
stop_here () {
echo "$1" >"$dotest/next"
exit 1
stop_here () {
echo "$1" >"$dotest/next"
exit 1
git write-tree >"$dotest/patch-merge-base+" ||
cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
git write-tree >"$dotest/patch-merge-base+" ||
cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
- echo Using index info to reconstruct a base tree...
+ say Using index info to reconstruct a base tree...
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git apply --cached <"$dotest/patch"
then
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git apply --cached <"$dotest/patch"
then
orig_tree=$(cat "$dotest/patch-merge-base") &&
rm -fr "$dotest"/patch-merge-* || exit 1
orig_tree=$(cat "$dotest/patch-merge-base") &&
rm -fr "$dotest"/patch-merge-* || exit 1
- echo Falling back to patching base and 3-way merge...
+ say 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
# This is not so wrong. Depending on which base we picked,
# orig_tree may be wildly different from ours, but his_tree
eval GITHEAD_$his_tree='"$FIRSTLINE"'
export GITHEAD_$his_tree
eval GITHEAD_$his_tree='"$FIRSTLINE"'
export GITHEAD_$his_tree
+ if test -n "$GIT_QUIET"
+ then
+ export GIT_MERGE_VERBOSITY=0
+ fi
git-merge-recursive $orig_tree -- HEAD $his_tree || {
git rerere
echo Failed to merge in the changes.
git-merge-recursive $orig_tree -- HEAD $his_tree || {
git rerere
echo Failed to merge in the changes.
sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
resolvemsg= resume=
git_apply_opt=
sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
resolvemsg= resume=
git_apply_opt=
+committer_date_is_author_date=
+ignore_date=
while test $# != 0
do
while test $# != 0
do
;;
--resolvemsg)
shift; resolvemsg=$1 ;;
;;
--resolvemsg)
shift; resolvemsg=$1 ;;
- --whitespace)
- git_apply_opt="$git_apply_opt $1=$2"; shift ;;
+ --whitespace|--directory)
+ git_apply_opt="$git_apply_opt $(sq "$1=$2")"; shift ;;
-C|-p)
-C|-p)
- git_apply_opt="$git_apply_opt $1$2"; shift ;;
+ git_apply_opt="$git_apply_opt $(sq "$1$2")"; shift ;;
+ --reject)
+ git_apply_opt="$git_apply_opt $1" ;;
+ --committer-date-is-author-date)
+ committer_date_is_author_date=t ;;
+ --ignore-date)
+ ignore_date=t ;;
+ -q|--quiet)
+ GIT_QUIET=t ;;
--)
shift; break ;;
*)
--)
shift; break ;;
*)
# unreliable -- stdin could be /dev/null for example
# and the caller did not intend to feed us a patch but
# wanted to continue unattended.
# unreliable -- stdin could be /dev/null for example
# and the caller did not intend to feed us a patch but
# wanted to continue unattended.
- tty -s
+ test -t 0
;;
*)
false
;;
*)
false
resume=yes
case "$skip,$abort" in
resume=yes
case "$skip,$abort" in
+ t,t)
+ die "Please make up your mind. --skip or --abort?"
+ ;;
t,)
git rerere clear
git read-tree --reset -u HEAD HEAD
t,)
git rerere clear
git read-tree --reset -u HEAD HEAD
git update-ref ORIG_HEAD $orig_head
;;
,t)
git update-ref ORIG_HEAD $orig_head
;;
,t)
+ if test -f "$dotest/rebasing"
+ then
+ exec git rebase --abort
+ fi
git rerere clear
git rerere clear
- git read-tree --reset -u HEAD ORIG_HEAD
- git reset ORIG_HEAD
+ test -f "$dotest/dirtyindex" || {
+ git read-tree --reset -u HEAD ORIG_HEAD
+ git reset ORIG_HEAD
+ }
rm -fr "$dotest"
exit ;;
esac
rm -fr "$dotest"
exit ;;
esac
+ rm -f "$dotest/dirtyindex"
else
# Make sure we are not given --skip, --resolved, nor --abort
test "$skip$resolved$abort" = "" ||
else
# Make sure we are not given --skip, --resolved, nor --abort
test "$skip$resolved$abort" = "" ||
exit 1
}
exit 1
}
- # -s, -u, -k, --whitespace, -3, -C and -p flags are kept
+ # -s, -u, -k, --whitespace, -3, -C, -q and -p flags are kept
# for the resuming session after a patch failure.
# -i can and must be given when resuming.
echo " $git_apply_opt" >"$dotest/apply-opt"
# for the resuming session after a patch failure.
# -i can and must be given when resuming.
echo " $git_apply_opt" >"$dotest/apply-opt"
echo "$sign" >"$dotest/sign"
echo "$utf8" >"$dotest/utf8"
echo "$keep" >"$dotest/keep"
echo "$sign" >"$dotest/sign"
echo "$utf8" >"$dotest/utf8"
echo "$keep" >"$dotest/keep"
+ echo "$GIT_QUIET" >"$dotest/quiet"
echo 1 >"$dotest/next"
if test -n "$rebasing"
then
: >"$dotest/rebasing"
else
: >"$dotest/applying"
echo 1 >"$dotest/next"
if test -n "$rebasing"
then
: >"$dotest/rebasing"
else
: >"$dotest/applying"
- git update-ref ORIG_HEAD HEAD
+ if test -n "$HAS_HEAD"
+ then
+ git update-ref ORIG_HEAD HEAD
+ else
+ git update-ref -d ORIG_HEAD >/dev/null 2>&1
+ fi
fi
fi
case "$resolved" in
'')
fi
fi
case "$resolved" in
'')
- files=$(git diff-index --cached --name-only HEAD --) || exit
- if [ "$files" ]; then
- echo "Dirty index: cannot apply patches (dirty: $files)" >&2
- exit 1
+ case "$HAS_HEAD" in
+ '')
+ files=$(git ls-files) ;;
+ ?*)
+ files=$(git diff-index --cached --name-only HEAD --) ;;
+ esac || exit
+ if test "$files"
+ then
+ test -n "$HAS_HEAD" && : >"$dotest/dirtyindex"
+ die "Dirty index: cannot apply patches (dirty: $files)"
fi
esac
fi
esac
then
keep=-k
fi
then
keep=-k
fi
+if test "$(cat "$dotest/quiet")" = t
+then
+ GIT_QUIET=t
+fi
if test "$(cat "$dotest/threeway")" = t
then
threeway=t
if test "$(cat "$dotest/threeway")" = t
then
threeway=t
if test "$this" -gt "$last"
then
if test "$this" -gt "$last"
then
- echo Nothing to do.
+ say Nothing to do.
rm -fr "$dotest"
exit
fi
rm -fr "$dotest"
exit
fi
stop_here $this
fi
stop_here $this
fi
- printf 'Applying: %s\n' "$FIRSTLINE"
+ say "Applying: $FIRSTLINE"
case "$resolved" in
'')
case "$resolved" in
'')
- git apply $git_apply_opt --index "$dotest/patch"
+ # 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"'
apply_status=$?
;;
t)
apply_status=$?
;;
t)
# 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 -- && {
# 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 -- && {
- echo No changes -- Patch already applied.
+ say No changes -- Patch already applied.
go_next
continue
}
go_next
continue
}
fi
if test $apply_status != 0
then
fi
if test $apply_status != 0
then
- echo Patch failed at $msgnum.
+ printf 'Patch failed at %s %s\n' "$msgnum" "$FIRSTLINE"
stop_here_user_resolve $this
fi
stop_here_user_resolve $this
fi
fi
tree=$(git write-tree) &&
fi
tree=$(git write-tree) &&
- parent=$(git rev-parse --verify HEAD) &&
- commit=$(git commit-tree $tree -p $parent <"$dotest/final-commit") &&
+ commit=$(
+ if test -n "$ignore_date"
+ then
+ GIT_AUTHOR_DATE=
+ fi
+ parent=$(git rev-parse --verify -q HEAD) ||
+ say >&2 "applying to an empty history"
+
+ if test -n "$committer_date_is_author_date"
+ then
+ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+ export GIT_COMMITTER_DATE
+ fi &&
+ git commit-tree $tree ${parent:+-p} $parent <"$dotest/final-commit"
+ ) &&
git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent ||
stop_here $this
git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent ||
stop_here $this