2008-06-01 00:11:42 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='git am running'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
2010-07-23 19:03:07 +02:00
|
|
|
test_expect_success 'setup: messages' '
|
|
|
|
cat >msg <<-\EOF &&
|
|
|
|
second
|
|
|
|
|
|
|
|
Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy
|
|
|
|
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
|
|
|
|
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
|
|
|
|
kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem
|
|
|
|
ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
|
|
|
|
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
|
|
|
|
vero eos et accusam et justo duo dolores et ea rebum.
|
|
|
|
|
|
|
|
EOF
|
2013-03-22 19:10:03 +01:00
|
|
|
qz_to_tab_space <<-\EOF >>msg &&
|
2010-07-23 19:03:07 +02:00
|
|
|
QDuis autem vel eum iriure dolor in hendrerit in vulputate velit
|
|
|
|
Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis
|
|
|
|
Qat vero eros et accumsan et iusto odio dignissim qui blandit
|
|
|
|
Qpraesent luptatum zzril delenit augue duis dolore te feugait nulla
|
|
|
|
Qfacilisi.
|
|
|
|
EOF
|
|
|
|
cat >>msg <<-\EOF &&
|
|
|
|
|
|
|
|
Lorem ipsum dolor sit amet,
|
|
|
|
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
|
|
|
|
laoreet dolore magna aliquam erat volutpat.
|
|
|
|
|
|
|
|
git
|
|
|
|
---
|
|
|
|
+++
|
|
|
|
|
|
|
|
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
|
|
|
|
lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
|
|
|
|
dolor in hendrerit in vulputate velit esse molestie consequat, vel illum
|
|
|
|
dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
|
|
|
|
dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
|
|
|
|
feugait nulla facilisi.
|
2017-08-08 12:25:33 +02:00
|
|
|
|
|
|
|
Reported-by: A N Other <a.n.other@example.com>
|
2010-07-23 19:03:07 +02:00
|
|
|
EOF
|
|
|
|
|
|
|
|
cat >failmail <<-\EOF &&
|
|
|
|
From foo@example.com Fri May 23 10:43:49 2008
|
|
|
|
From: foo@example.com
|
|
|
|
To: bar@example.com
|
|
|
|
Subject: Re: [RFC/PATCH] git-foo.sh
|
|
|
|
Date: Fri, 23 May 2008 05:23:42 +0200
|
|
|
|
|
|
|
|
Sometimes we have to find out that there'\''s nothing left.
|
|
|
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
cat >pine <<-\EOF &&
|
|
|
|
From MAILER-DAEMON Fri May 23 10:43:49 2008
|
|
|
|
Date: 23 May 2008 05:23:42 +0200
|
|
|
|
From: Mail System Internal Data <MAILER-DAEMON@example.com>
|
|
|
|
Subject: DON'\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
|
|
|
|
Message-ID: <foo-0001@example.com>
|
|
|
|
|
|
|
|
This text is part of the internal format of your mail folder, and is not
|
|
|
|
a real message. It is created automatically by the mail system software.
|
|
|
|
If deleted, important folder data will be lost, and it will be re-created
|
|
|
|
with the data reset to initial values.
|
|
|
|
|
|
|
|
EOF
|
|
|
|
|
2015-07-19 17:49:16 +02:00
|
|
|
cat >scissors-msg <<-\EOF &&
|
|
|
|
Test git-am with scissors line
|
|
|
|
|
|
|
|
This line should be included in the commit message.
|
|
|
|
EOF
|
|
|
|
|
|
|
|
cat - scissors-msg >no-scissors-msg <<-\EOF &&
|
|
|
|
This line should not be included in the commit message with --scissors enabled.
|
|
|
|
|
|
|
|
- - >8 - - remove everything above this line - - >8 - -
|
|
|
|
|
|
|
|
EOF
|
|
|
|
|
2010-07-23 19:03:07 +02:00
|
|
|
signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
|
|
|
|
'
|
2008-06-01 00:11:42 +02:00
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
echo hello >file &&
|
|
|
|
git add file &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m first &&
|
|
|
|
git tag first &&
|
2010-07-23 19:03:07 +02:00
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
echo world >>file &&
|
|
|
|
git add file &&
|
|
|
|
test_tick &&
|
2017-08-08 12:25:33 +02:00
|
|
|
git commit -F msg &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git tag second &&
|
2010-07-23 19:03:07 +02:00
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
git format-patch --stdout first >patch1 &&
|
2009-08-07 03:08:12 +02:00
|
|
|
{
|
2014-11-25 15:00:56 +01:00
|
|
|
echo "Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru>" &&
|
2009-08-07 03:08:12 +02:00
|
|
|
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.eml &&
|
2010-01-26 01:33:59 +01:00
|
|
|
{
|
|
|
|
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"
|
|
|
|
} | append_cr >patch1-crlf.eml &&
|
2011-08-08 04:49:04 +02:00
|
|
|
{
|
|
|
|
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 &&
|
2015-06-08 17:48:47 +02:00
|
|
|
{
|
|
|
|
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 "---" &&
|
|
|
|
git diff-tree --no-commit-id --stat -p second
|
|
|
|
} >patch1-stgit.eml &&
|
2015-06-15 13:08:11 +02:00
|
|
|
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 &&
|
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 13:08:12 +02:00
|
|
|
{
|
|
|
|
echo "# HG changeset patch" &&
|
|
|
|
echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
|
|
|
|
echo "# Date $test_tick 25200" &&
|
|
|
|
echo "# $(git show --pretty="%aD" -s second)" &&
|
2018-05-13 04:24:13 +02:00
|
|
|
echo "# Node ID $ZERO_OID" &&
|
|
|
|
echo "# Parent $ZERO_OID" &&
|
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 13:08:12 +02:00
|
|
|
cat msg &&
|
|
|
|
echo &&
|
|
|
|
git diff-tree --no-commit-id -p second
|
|
|
|
} >patch1-hg.eml &&
|
2015-06-15 13:08:11 +02:00
|
|
|
|
2010-07-23 19:03:07 +02:00
|
|
|
|
2015-07-19 17:49:16 +02:00
|
|
|
echo scissors-file >scissors-file &&
|
|
|
|
git add scissors-file &&
|
|
|
|
git commit -F scissors-msg &&
|
|
|
|
git tag scissors &&
|
|
|
|
git format-patch --stdout scissors^ >scissors-patch.eml &&
|
|
|
|
git reset --hard HEAD^ &&
|
|
|
|
|
|
|
|
echo no-scissors-file >no-scissors-file &&
|
|
|
|
git add no-scissors-file &&
|
|
|
|
git commit -F no-scissors-msg &&
|
|
|
|
git tag no-scissors &&
|
|
|
|
git format-patch --stdout no-scissors^ >no-scissors-patch.eml &&
|
|
|
|
git reset --hard HEAD^ &&
|
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
sed -n -e "3,\$p" msg >file &&
|
|
|
|
git add file &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m third &&
|
2010-07-23 19:03:07 +02:00
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
git format-patch --stdout first >patch2 &&
|
2010-07-23 19:03:07 +02:00
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout -b lorem &&
|
|
|
|
sed -n -e "11,\$p" msg >file &&
|
|
|
|
head -n 9 msg >>file &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -a -m "moved stuff" &&
|
2010-07-23 19:03:07 +02:00
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
echo goodbye >another &&
|
|
|
|
git add another &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m "added another file" &&
|
|
|
|
|
2010-07-23 19:03:07 +02:00
|
|
|
git format-patch --stdout master >lorem-move.patch &&
|
2012-02-27 08:00:47 +01:00
|
|
|
git format-patch --no-prefix --stdout master >lorem-zero.patch &&
|
2008-11-11 00:49:03 +01:00
|
|
|
|
|
|
|
git checkout -b rename &&
|
|
|
|
git mv file renamed &&
|
|
|
|
git commit -m "renamed a file" &&
|
|
|
|
|
|
|
|
git format-patch -M --stdout lorem >rename.patch &&
|
|
|
|
|
|
|
|
git reset --soft lorem^ &&
|
|
|
|
git commit -m "renamed a file and added another" &&
|
|
|
|
|
|
|
|
git format-patch -M --stdout lorem^ >rename-add.patch &&
|
|
|
|
|
2010-07-23 19:03:07 +02:00
|
|
|
# reset time
|
2012-02-12 02:05:12 +01:00
|
|
|
sane_unset test_tick &&
|
2010-07-23 19:03:07 +02:00
|
|
|
test_tick
|
|
|
|
'
|
2008-06-01 00:11:42 +02:00
|
|
|
|
|
|
|
test_expect_success 'am applies patch correctly' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout first &&
|
|
|
|
test_tick &&
|
|
|
|
git am <patch1 &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code second &&
|
2008-06-01 00:11:42 +02:00
|
|
|
test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
|
|
|
|
test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
|
2009-08-07 03:08:12 +02:00
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:08 +02:00
|
|
|
test_expect_success 'am fails if index is dirty' '
|
|
|
|
test_when_finished "rm -f dirtyfile" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout first &&
|
|
|
|
echo dirtyfile >dirtyfile &&
|
|
|
|
git add dirtyfile &&
|
|
|
|
test_must_fail git am patch1 &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
test_cmp_rev first HEAD
|
|
|
|
'
|
|
|
|
|
2009-08-07 03:08:12 +02:00
|
|
|
test_expect_success 'am applies patch e-mail not in a mbox' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2009-08-07 03:08:12 +02:00
|
|
|
git checkout first &&
|
|
|
|
git am patch1.eml &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code second &&
|
2009-08-07 03:08:12 +02:00
|
|
|
test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
|
|
|
|
test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
|
2010-01-26 01:33:59 +01:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2010-01-26 01:33:59 +01:00
|
|
|
git checkout first &&
|
|
|
|
git am patch1-crlf.eml &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code second &&
|
2010-01-26 01:33:59 +01:00
|
|
|
test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
|
|
|
|
test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
2011-08-08 04:49:04 +02:00
|
|
|
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 &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2011-08-08 04:49:04 +02:00
|
|
|
git diff --exit-code second &&
|
|
|
|
test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
|
|
|
|
test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
|
|
|
|
'
|
|
|
|
|
2015-06-08 17:48:47 +02:00
|
|
|
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 &&
|
2015-06-15 13:08:10 +02:00
|
|
|
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 &&
|
2015-06-15 13:08:11 +02:00
|
|
|
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 &&
|
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 13:08:12 +02:00
|
|
|
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 &&
|
2015-06-15 13:08:13 +02:00
|
|
|
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 &&
|
2015-06-08 17:48:47 +02:00
|
|
|
test_cmp_rev second^ HEAD^
|
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:13 +02:00
|
|
|
test_expect_success 'am with applypatch-msg hook' '
|
|
|
|
test_when_finished "rm -f .git/hooks/applypatch-msg" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout first &&
|
|
|
|
mkdir -p .git/hooks &&
|
|
|
|
write_script .git/hooks/applypatch-msg <<-\EOF &&
|
|
|
|
cat "$1" >actual-msg &&
|
|
|
|
echo hook-message >"$1"
|
|
|
|
EOF
|
|
|
|
git am patch1 &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git diff --exit-code second &&
|
|
|
|
echo hook-message >expected &&
|
|
|
|
git log -1 --format=format:%B >actual &&
|
|
|
|
test_cmp expected actual &&
|
|
|
|
git log -1 --format=format:%B second >expected &&
|
|
|
|
test_cmp expected actual-msg
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am with failing applypatch-msg hook' '
|
|
|
|
test_when_finished "rm -f .git/hooks/applypatch-msg" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout first &&
|
|
|
|
mkdir -p .git/hooks &&
|
|
|
|
write_script .git/hooks/applypatch-msg <<-\EOF &&
|
|
|
|
exit 1
|
|
|
|
EOF
|
|
|
|
test_must_fail git am patch1 &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
git diff --exit-code first &&
|
|
|
|
test_cmp_rev first HEAD
|
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:14 +02:00
|
|
|
test_expect_success 'am with pre-applypatch hook' '
|
|
|
|
test_when_finished "rm -f .git/hooks/pre-applypatch" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout first &&
|
|
|
|
mkdir -p .git/hooks &&
|
|
|
|
write_script .git/hooks/pre-applypatch <<-\EOF &&
|
|
|
|
git diff first >diff.actual
|
|
|
|
exit 0
|
|
|
|
EOF
|
|
|
|
git am patch1 &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git diff --exit-code second &&
|
|
|
|
test_cmp_rev second HEAD &&
|
|
|
|
git diff first..second >diff.expected &&
|
|
|
|
test_cmp diff.expected diff.actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am with failing pre-applypatch hook' '
|
|
|
|
test_when_finished "rm -f .git/hooks/pre-applypatch" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout first &&
|
|
|
|
mkdir -p .git/hooks &&
|
|
|
|
write_script .git/hooks/pre-applypatch <<-\EOF &&
|
|
|
|
exit 1
|
|
|
|
EOF
|
|
|
|
test_must_fail git am patch1 &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
git diff --exit-code second &&
|
|
|
|
test_cmp_rev first HEAD
|
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:15 +02:00
|
|
|
test_expect_success 'am with post-applypatch hook' '
|
|
|
|
test_when_finished "rm -f .git/hooks/post-applypatch" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout first &&
|
|
|
|
mkdir -p .git/hooks &&
|
|
|
|
write_script .git/hooks/post-applypatch <<-\EOF &&
|
|
|
|
git rev-parse HEAD >head.actual
|
|
|
|
git diff second >diff.actual
|
|
|
|
exit 0
|
|
|
|
EOF
|
|
|
|
git am patch1 &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
test_cmp_rev second HEAD &&
|
|
|
|
git rev-parse second >head.expected &&
|
|
|
|
test_cmp head.expected head.actual &&
|
|
|
|
git diff second >diff.expected &&
|
|
|
|
test_cmp diff.expected diff.actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am with failing post-applypatch hook' '
|
|
|
|
test_when_finished "rm -f .git/hooks/post-applypatch" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout first &&
|
|
|
|
mkdir -p .git/hooks &&
|
|
|
|
write_script .git/hooks/post-applypatch <<-\EOF &&
|
|
|
|
git rev-parse HEAD >head.actual
|
|
|
|
exit 1
|
|
|
|
EOF
|
|
|
|
git am patch1 &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git diff --exit-code second &&
|
|
|
|
test_cmp_rev second HEAD &&
|
|
|
|
git rev-parse second >head.expected &&
|
|
|
|
test_cmp head.expected head.actual
|
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:16 +02:00
|
|
|
test_expect_success 'am --scissors cuts the message at the scissors line' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout second &&
|
|
|
|
git am --scissors scissors-patch.eml &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git diff --exit-code scissors &&
|
|
|
|
test_cmp_rev scissors HEAD
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am --no-scissors overrides mailinfo.scissors' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout second &&
|
|
|
|
test_config mailinfo.scissors true &&
|
|
|
|
git am --no-scissors no-scissors-patch.eml &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git diff --exit-code no-scissors &&
|
|
|
|
test_cmp_rev no-scissors HEAD
|
|
|
|
'
|
|
|
|
|
2010-07-23 19:03:07 +02:00
|
|
|
test_expect_success 'setup: new author and committer' '
|
|
|
|
GIT_AUTHOR_NAME="Another Thor" &&
|
|
|
|
GIT_AUTHOR_EMAIL="a.thor@example.com" &&
|
|
|
|
GIT_COMMITTER_NAME="Co M Miter" &&
|
|
|
|
GIT_COMMITTER_EMAIL="c.miter@example.com" &&
|
|
|
|
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
|
|
|
|
'
|
2008-06-01 00:11:42 +02:00
|
|
|
|
|
|
|
compare () {
|
2010-07-23 19:03:07 +02:00
|
|
|
a=$(git cat-file commit "$2" | grep "^$1 ") &&
|
|
|
|
b=$(git cat-file commit "$3" | grep "^$1 ") &&
|
|
|
|
test "$a" = "$b"
|
2008-06-01 00:11:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'am changes committer and keeps author' '
|
|
|
|
test_tick &&
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout first &&
|
|
|
|
git am patch2 &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2008-06-01 00:11:42 +02:00
|
|
|
test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code master..HEAD &&
|
|
|
|
git diff --exit-code master^..HEAD^ &&
|
2008-06-01 00:11:42 +02:00
|
|
|
compare author master HEAD &&
|
|
|
|
compare author master^ HEAD^ &&
|
|
|
|
test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
|
|
|
|
"$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am --signoff adds Signed-off-by: line' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout -b master2 first &&
|
|
|
|
git am --signoff <patch2 &&
|
2017-08-08 12:25:33 +02:00
|
|
|
{
|
|
|
|
printf "third\n\nSigned-off-by: %s <%s>\n\n" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
|
|
|
|
cat msg &&
|
|
|
|
printf "Signed-off-by: %s <%s>\n\n" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
|
|
|
|
} >expected-log &&
|
|
|
|
git log --pretty=%B -2 HEAD >actual &&
|
|
|
|
test_cmp expected-log actual
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am stays in branch' '
|
2010-07-23 19:03:07 +02:00
|
|
|
echo refs/heads/master2 >expected &&
|
|
|
|
git symbolic-ref HEAD >actual &&
|
|
|
|
test_cmp expected actual
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
|
2017-08-08 12:25:33 +02:00
|
|
|
git format-patch --stdout first >patch3 &&
|
|
|
|
git reset --hard first &&
|
|
|
|
git am --signoff <patch3 &&
|
|
|
|
git log --pretty=%B -2 HEAD >actual &&
|
|
|
|
test_cmp expected-log actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
|
|
|
|
NAME="A N Other" &&
|
|
|
|
EMAIL="a.n.other@example.com" &&
|
|
|
|
{
|
|
|
|
printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
|
|
|
|
"$NAME" "$EMAIL" &&
|
|
|
|
cat msg &&
|
|
|
|
printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
|
|
|
|
"$NAME" "$EMAIL"
|
|
|
|
} >expected-log &&
|
|
|
|
git reset --hard first &&
|
|
|
|
GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
|
|
|
|
git am --signoff <patch3 &&
|
|
|
|
git log --pretty=%B -2 HEAD >actual &&
|
|
|
|
test_cmp expected-log actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
|
|
|
|
NAME="A N Other" &&
|
|
|
|
EMAIL="a.n.other@example.com" &&
|
|
|
|
{
|
|
|
|
printf "third\n\nSigned-off-by: %s <%s>\n\
|
|
|
|
Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
|
|
|
|
"$NAME" "$EMAIL" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
|
|
|
|
cat msg &&
|
|
|
|
printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
|
|
|
|
Signed-off-by: %s <%s>\n\n" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
|
|
|
|
"$NAME" "$EMAIL" \
|
|
|
|
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
|
|
|
|
} >expected-log &&
|
|
|
|
git format-patch --stdout first >patch3 &&
|
|
|
|
git reset --hard first &&
|
|
|
|
git am --signoff <patch3 &&
|
|
|
|
git log --pretty=%B -2 HEAD >actual &&
|
|
|
|
test_cmp expected-log actual
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
|
2017-08-08 12:25:33 +02:00
|
|
|
git format-patch --stdout HEAD^ >tmp &&
|
|
|
|
sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
|
|
|
|
git reset --hard HEAD^ &&
|
|
|
|
git am <patch4 &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git rev-parse HEAD >expected &&
|
|
|
|
git rev-parse master2 >actual &&
|
|
|
|
test_cmp expected actual
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am --keep really keeps the subject' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout HEAD^ &&
|
|
|
|
git am --keep patch4 &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git cat-file commit HEAD >actual &&
|
2012-01-16 11:53:00 +01:00
|
|
|
grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
|
|
|
|
'
|
|
|
|
|
2012-01-16 11:53:01 +01:00
|
|
|
test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
|
2012-01-16 11:53:00 +01:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout HEAD^ &&
|
|
|
|
git am --keep-non-patch patch4 &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2012-01-16 11:53:00 +01:00
|
|
|
git cat-file commit HEAD >actual &&
|
|
|
|
grep "^\[foo\] third" actual
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
2015-06-04 17:04:54 +02:00
|
|
|
test_expect_success 'setup am -3' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2015-06-04 17:04:54 +02:00
|
|
|
git checkout -b base3way master2 &&
|
2008-06-01 00:11:42 +02:00
|
|
|
sed -n -e "3,\$p" msg >file &&
|
|
|
|
head -n 9 msg >>file &&
|
|
|
|
git add file &&
|
|
|
|
test_tick &&
|
2015-06-04 17:04:54 +02:00
|
|
|
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 &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git am -3 lorem-move.patch &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code lorem
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
2012-02-27 08:00:47 +01:00
|
|
|
test_expect_success 'am -3 -p0 can read --no-prefix patch' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2015-06-04 17:04:54 +02:00
|
|
|
git checkout -b lorem3 base3way &&
|
2012-02-27 08:00:47 +01:00
|
|
|
git am -3 -p0 lorem-zero.patch &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2012-02-27 08:00:47 +01:00
|
|
|
git diff --exit-code lorem
|
|
|
|
'
|
|
|
|
|
2015-08-04 16:19:26 +02:00
|
|
|
test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout -b lorem4 base3way &&
|
|
|
|
test_config am.threeWay 1 &&
|
|
|
|
git am lorem-move.patch &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git diff --exit-code lorem
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am with config am.threeWay overridden by --no-3way' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout -b lorem5 base3way &&
|
|
|
|
test_config am.threeWay 1 &&
|
|
|
|
test_must_fail git am --no-3way lorem-move.patch &&
|
|
|
|
test_path_is_dir .git/rebase-apply
|
|
|
|
'
|
|
|
|
|
2008-11-11 00:49:03 +01:00
|
|
|
test_expect_success 'am can rename a file' '
|
|
|
|
grep "^rename from" rename.patch &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout lorem^0 &&
|
|
|
|
git am rename.patch &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2008-11-11 00:49:03 +01:00
|
|
|
git update-index --refresh &&
|
|
|
|
git diff --exit-code rename
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am -3 can rename a file' '
|
|
|
|
grep "^rename from" rename.patch &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout lorem^0 &&
|
|
|
|
git am -3 rename.patch &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2008-11-11 00:49:03 +01:00
|
|
|
git update-index --refresh &&
|
|
|
|
git diff --exit-code rename
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
|
|
|
|
grep "^rename from" rename-add.patch &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout lorem^0 &&
|
|
|
|
git am -3 rename-add.patch &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2008-11-11 00:49:03 +01:00
|
|
|
git update-index --refresh &&
|
|
|
|
git diff --exit-code rename
|
|
|
|
'
|
|
|
|
|
2009-06-17 00:33:01 +02:00
|
|
|
test_expect_success 'am -3 -q is quiet' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
2008-11-11 00:49:03 +01:00
|
|
|
git checkout -f lorem2 &&
|
2015-06-04 17:04:54 +02:00
|
|
|
git reset base3way --hard &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git am -3 -q lorem-move.patch >output.out 2>&1 &&
|
2009-06-17 00:33:01 +02:00
|
|
|
! test -s output.out
|
|
|
|
'
|
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
test_expect_success 'am pauses on conflict' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout lorem2^^ &&
|
2008-07-12 17:47:52 +02:00
|
|
|
test_must_fail git am lorem-move.patch &&
|
2008-07-21 12:51:02 +02:00
|
|
|
test -d .git/rebase-apply
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
2018-02-11 10:43:26 +01:00
|
|
|
test_expect_success 'am --show-current-patch' '
|
|
|
|
git am --show-current-patch >actual.patch &&
|
|
|
|
test_cmp .git/rebase-apply/0001 actual.patch
|
|
|
|
'
|
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
test_expect_success 'am --skip works' '
|
2010-07-23 19:03:07 +02:00
|
|
|
echo goodbye >expected &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git am --skip &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code lorem2^^ -- file &&
|
|
|
|
test_cmp expected another
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
2013-06-15 14:43:11 +02:00
|
|
|
test_expect_success 'am --abort removes a stray directory' '
|
|
|
|
mkdir .git/rebase-apply &&
|
|
|
|
git am --abort &&
|
|
|
|
test_path_is_missing .git/rebase-apply
|
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:10 +02:00
|
|
|
test_expect_success 'am refuses patches when paused' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout lorem2^^ &&
|
|
|
|
|
|
|
|
test_must_fail git am lorem-move.patch &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
test_cmp_rev lorem2^^ HEAD &&
|
|
|
|
|
|
|
|
test_must_fail git am <lorem-move.patch &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
test_cmp_rev lorem2^^ HEAD
|
|
|
|
'
|
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
test_expect_success 'am --resolved works' '
|
2010-07-23 19:03:07 +02:00
|
|
|
echo goodbye >expected &&
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout lorem2^^ &&
|
2008-07-12 17:47:52 +02:00
|
|
|
test_must_fail git am lorem-move.patch &&
|
2008-07-21 12:51:02 +02:00
|
|
|
test -d .git/rebase-apply &&
|
2008-06-01 00:11:42 +02:00
|
|
|
echo resolved >>file &&
|
|
|
|
git add file &&
|
|
|
|
git am --resolved &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
test_cmp expected another
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:11 +02:00
|
|
|
test_expect_success 'am --resolved fails if index has no changes' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout lorem2^^ &&
|
|
|
|
test_must_fail git am lorem-move.patch &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
test_cmp_rev lorem2^^ HEAD &&
|
|
|
|
test_must_fail git am --resolved &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
test_cmp_rev lorem2^^ HEAD
|
|
|
|
'
|
|
|
|
|
2015-07-19 17:49:12 +02:00
|
|
|
test_expect_success 'am --resolved fails if index has unmerged entries' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout second &&
|
|
|
|
test_must_fail git am -3 lorem-move.patch &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
test_cmp_rev second HEAD &&
|
|
|
|
test_must_fail git am --resolved >err &&
|
|
|
|
test_path_is_dir .git/rebase-apply &&
|
|
|
|
test_cmp_rev second HEAD &&
|
|
|
|
test_i18ngrep "still have unmerged paths" err
|
|
|
|
'
|
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
test_expect_success 'am takes patches from a Pine mailbox' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git checkout first &&
|
|
|
|
cat pine patch1 | git am &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code master^..HEAD
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am fails on mail without patch' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-07-12 17:47:52 +02:00
|
|
|
test_must_fail git am <failmail &&
|
2010-07-23 19:04:01 +02:00
|
|
|
git am --abort &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am fails on empty patch' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:42 +02:00
|
|
|
echo "---" >>failmail &&
|
2008-07-12 17:47:52 +02:00
|
|
|
test_must_fail git am <failmail &&
|
2008-06-01 00:11:42 +02:00
|
|
|
git am --skip &&
|
2013-06-15 14:43:12 +02:00
|
|
|
test_path_is_missing .git/rebase-apply
|
2008-06-01 00:11:42 +02:00
|
|
|
'
|
|
|
|
|
2008-06-01 00:11:43 +02:00
|
|
|
test_expect_success 'am works from stdin in subdirectory' '
|
|
|
|
rm -fr subdir &&
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:43 +02:00
|
|
|
git checkout first &&
|
|
|
|
(
|
|
|
|
mkdir -p subdir &&
|
|
|
|
cd subdir &&
|
|
|
|
git am <../patch1
|
|
|
|
) &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code second
|
2008-06-01 00:11:43 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am works from file (relative path given) in subdirectory' '
|
|
|
|
rm -fr subdir &&
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:43 +02:00
|
|
|
git checkout first &&
|
|
|
|
(
|
|
|
|
mkdir -p subdir &&
|
|
|
|
cd subdir &&
|
|
|
|
git am ../patch1
|
|
|
|
) &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code second
|
2008-06-01 00:11:43 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am works from file (absolute path given) in subdirectory' '
|
|
|
|
rm -fr subdir &&
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2008-06-01 00:11:43 +02:00
|
|
|
git checkout first &&
|
|
|
|
P=$(pwd) &&
|
|
|
|
(
|
|
|
|
mkdir -p subdir &&
|
|
|
|
cd subdir &&
|
|
|
|
git am "$P/patch1"
|
|
|
|
) &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git diff --exit-code second
|
2008-06-01 00:11:43 +02:00
|
|
|
'
|
|
|
|
|
2009-01-23 01:14:58 +01:00
|
|
|
test_expect_success 'am --committer-date-is-author-date' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2009-01-23 01:14:58 +01:00
|
|
|
git checkout first &&
|
|
|
|
test_tick &&
|
|
|
|
git am --committer-date-is-author-date patch1 &&
|
2010-01-27 00:08:31 +01:00
|
|
|
git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
|
2010-07-23 19:03:07 +02:00
|
|
|
sed -ne "/^author /s/.*> //p" head1 >at &&
|
|
|
|
sed -ne "/^committer /s/.*> //p" head1 >ct &&
|
|
|
|
test_cmp at ct
|
2009-01-23 01:14:58 +01:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'am without --committer-date-is-author-date' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2009-01-23 01:14:58 +01:00
|
|
|
git checkout first &&
|
|
|
|
test_tick &&
|
|
|
|
git am patch1 &&
|
2010-01-27 00:08:31 +01:00
|
|
|
git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
|
2010-07-23 19:03:07 +02:00
|
|
|
sed -ne "/^author /s/.*> //p" head1 >at &&
|
|
|
|
sed -ne "/^committer /s/.*> //p" head1 >ct &&
|
|
|
|
! test_cmp at ct
|
2009-01-23 01:14:58 +01:00
|
|
|
'
|
|
|
|
|
2009-01-24 02:18:02 +01:00
|
|
|
# This checks for +0000 because TZ is set to UTC and that should
|
|
|
|
# show up when the current time is used. The date in message is set
|
|
|
|
# by test_tick that uses -0700 timezone; if this feature does not
|
|
|
|
# work, we will see that instead of +0000.
|
|
|
|
test_expect_success 'am --ignore-date' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2009-01-24 02:18:02 +01:00
|
|
|
git checkout first &&
|
|
|
|
test_tick &&
|
|
|
|
git am --ignore-date patch1 &&
|
2010-01-27 00:08:31 +01:00
|
|
|
git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
|
2010-07-23 19:03:07 +02:00
|
|
|
sed -ne "/^author /s/.*> //p" head1 >at &&
|
|
|
|
grep "+0000" at
|
2009-01-24 02:18:02 +01:00
|
|
|
'
|
|
|
|
|
2009-04-10 02:34:42 +02:00
|
|
|
test_expect_success 'am into an unborn branch' '
|
2010-07-23 19:03:07 +02:00
|
|
|
git rev-parse first^{tree} >expected &&
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2009-04-10 02:34:42 +02:00
|
|
|
rm -fr subdir &&
|
2010-07-23 19:03:07 +02:00
|
|
|
mkdir subdir &&
|
2009-04-10 02:34:42 +02:00
|
|
|
git format-patch --numbered-files -o subdir -1 first &&
|
|
|
|
(
|
|
|
|
cd subdir &&
|
|
|
|
git init &&
|
|
|
|
git am 1
|
|
|
|
) &&
|
2010-07-23 19:03:07 +02:00
|
|
|
(
|
|
|
|
cd subdir &&
|
|
|
|
git rev-parse HEAD^{tree} >../actual
|
2009-04-10 02:34:42 +02:00
|
|
|
) &&
|
2010-07-23 19:03:07 +02:00
|
|
|
test_cmp expected actual
|
2009-04-10 02:34:42 +02:00
|
|
|
'
|
|
|
|
|
2009-06-17 00:32:57 +02:00
|
|
|
test_expect_success 'am newline in subject' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2009-06-17 00:32:57 +02:00
|
|
|
git checkout first &&
|
|
|
|
test_tick &&
|
2010-07-23 19:03:07 +02:00
|
|
|
sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
|
|
|
|
git am <patchnl >output.out 2>&1 &&
|
2011-05-21 20:43:52 +02:00
|
|
|
test_i18ngrep "^Applying: second \\\n foo$" output.out
|
2009-06-17 00:32:57 +02:00
|
|
|
'
|
|
|
|
|
2009-06-17 00:33:01 +02:00
|
|
|
test_expect_success 'am -q is quiet' '
|
2010-07-23 19:04:01 +02:00
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
2009-06-17 00:33:01 +02:00
|
|
|
git checkout first &&
|
|
|
|
test_tick &&
|
2010-07-23 19:03:07 +02:00
|
|
|
git am -q <patch1 >output.out 2>&1 &&
|
2009-06-17 00:33:01 +02:00
|
|
|
! test -s output.out
|
|
|
|
'
|
|
|
|
|
2012-02-25 18:34:26 +01:00
|
|
|
test_expect_success 'am empty-file does not infloop' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
touch empty-file &&
|
|
|
|
test_tick &&
|
2012-04-14 06:48:13 +02:00
|
|
|
test_must_fail git am empty-file 2>actual &&
|
2012-02-25 18:34:26 +01:00
|
|
|
echo Patch format detection failed. >expected &&
|
2012-04-14 06:46:18 +02:00
|
|
|
test_i18ncmp expected actual
|
2012-02-25 18:34:26 +01:00
|
|
|
'
|
|
|
|
|
2014-11-25 15:00:56 +01:00
|
|
|
test_expect_success 'am --message-id really adds the message id' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout HEAD^ &&
|
|
|
|
git am --message-id patch1.eml &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git cat-file commit HEAD | tail -n1 >actual &&
|
|
|
|
grep Message-Id patch1.eml >expected &&
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2015-07-07 16:08:23 +02:00
|
|
|
test_expect_success 'am.messageid really adds the message id' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout HEAD^ &&
|
|
|
|
test_config am.messageid true &&
|
|
|
|
git am patch1.eml &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git cat-file commit HEAD | tail -n1 >actual &&
|
|
|
|
grep Message-Id patch1.eml >expected &&
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2014-11-25 15:00:56 +01:00
|
|
|
test_expect_success 'am --message-id -s signs off after the message id' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout HEAD^ &&
|
|
|
|
git am -s --message-id patch1.eml &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
|
|
|
|
grep Message-Id patch1.eml >expected &&
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
rerere: release lockfile in non-writing functions
There's a bug in builtin/am.c in which we take a lock on
MERGE_RR recursively. But rather than fix am.c, this patch
fixes the confusing interface from rerere.c that caused the
bug. Read on for the gory details.
The setup_rerere() function both reads the existing MERGE_RR
file, and takes MERGE_RR.lock. In the rerere() and
rerere_forget() functions, we end up in write_rr(), which
will then commit the lock file.
But for functions like rerere_clear() that do not write to
MERGE_RR, we expect the caller to have handled
setup_rerere(). That caller would then need to release the
lockfile, but it can't; the lock struct is local to
rerere.c.
For builtin/rerere.c, this is OK. We run a single rerere
operation and then exit immediately, which has the side
effect of rolling back the lockfile.
But in builtin/am.c, this is actively wrong. If we run "git
am -3 --skip", we call setup-rerere twice without releasing
the lock:
1. The "--skip" causes us to call am_rerere_clear(), which
calls setup_rerere(), but never drops the lock.
2. We then proceed to the next patch.
3. The "--3way" may cause us to call rerere() to handle
conflicts in that patch, but we are already holding the
lock. The lockfile code dies with:
BUG: prepare_tempfile_object called for active object
We could fix this by having rerere_clear() call
rollback_lock_file(). But it feels a bit odd for it to roll
back a lockfile that it did not itself take. So let's
simplify the interface further, and handle setup_rerere in
the function itself, taking away the question from the
caller over whether they need to do so.
We can give rerere_gc() the same treatment, as well (even
though it doesn't have any callers besides builtin/rerere.c
at this point). Note that these functions don't take flags
from their callers to pass along to setup_rerere; that's OK,
because the flags would not be meaningful for what they are
doing.
Both of those functions need to hold the lock because even
though they do not write to MERGE_RR, they are still writing
and should be protected from a simultaneous "rerere" run.
But rerere_remaining(), "rerere diff", and "rerere status"
are all read-only operations. They want to setup_rerere(),
but do not care about taking the lock in the first place.
Since our update of MERGE_RR is the usual atomic rename done
by commit_lock_file, they can just do a lockless read. For
that, we teach setup_rerere a READONLY flag to avoid the
lock.
As a bonus, this pushes builtin/rerere.c's setup_rerere call
closer to the functions that use it. Which means that "git
rerere totally-bogus-command" will no longer silently
exit(0) in a repository without rerere enabled.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-02 00:14:09 +02:00
|
|
|
test_expect_success 'am -3 works with rerere' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
|
|
|
|
# make patches one->two and two->three...
|
|
|
|
test_commit one file &&
|
|
|
|
test_commit two file &&
|
|
|
|
test_commit three file &&
|
|
|
|
git format-patch -2 --stdout >seq.patch &&
|
|
|
|
|
|
|
|
# and create a situation that conflicts...
|
|
|
|
git reset --hard one &&
|
|
|
|
test_commit other file &&
|
|
|
|
|
|
|
|
# enable rerere...
|
|
|
|
test_config rerere.enabled true &&
|
|
|
|
test_when_finished "rm -rf .git/rr-cache" &&
|
|
|
|
|
|
|
|
# ...and apply. Our resolution is to skip the first
|
|
|
|
# patch, and the rerere the second one.
|
|
|
|
test_must_fail git am -3 seq.patch &&
|
|
|
|
test_must_fail git am --skip &&
|
|
|
|
echo resolved >file &&
|
|
|
|
git add file &&
|
|
|
|
git am --resolved &&
|
|
|
|
|
|
|
|
# now apply again, and confirm that rerere engaged (we still
|
|
|
|
# expect failure from am because rerere does not auto-commit
|
|
|
|
# for us).
|
|
|
|
git reset --hard other &&
|
|
|
|
test_must_fail git am -3 seq.patch &&
|
|
|
|
test_must_fail git am --skip &&
|
|
|
|
echo resolved >expect &&
|
|
|
|
test_cmp expect file
|
|
|
|
'
|
|
|
|
|
am: match --signoff to the original scripted version
Linus noticed that the recently reimplemented "git am -s" defines
the trailer block too rigidly, resulting in an unnecessary blank
line between the existing sign-offs and his new sign-off. An e-mail
submission sent to Linus in real life ends with mixture of sign-offs
and commentaries, e.g.
title here
message here
Signed-off-by: Original Author <original@auth.or>
[rv: tweaked frotz and nitfol]
Signed-off-by: Re Viewer <rv@ew.er>
Signed-off-by: Other Reviewer <other@rev.ewer>
---
patch here
Because the reimplementation reused append_signoff() helper that is
used by other codepaths, which is unaware that people intermix such
comments with their sign-offs in the trailer block, such a message
was judged to end with a non-trailer, resulting in an extra blank
line before adding a new sign-off.
The original scripted version of "git am" used a lot looser
definition, i.e. "if and only if there is no line that begins with
Signed-off-by:, add a blank line before adding a new sign-off". For
the upcoming release, stop using the append_signoff() in "git am"
and reimplement the looser definition used by the scripted version
to use only in "git am" to fix this regression in "am" while
avoiding new regressions to other users of append_signoff().
In the longer term, we should look into loosening append_signoff()
so that other codepaths that add a new sign-off behave the same way
as "git am -s", but that is a task for post-release.
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-06 04:56:20 +02:00
|
|
|
test_expect_success 'am -s unexpected trailer block' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git reset --hard &&
|
|
|
|
echo signed >file &&
|
|
|
|
git add file &&
|
|
|
|
cat >msg <<-EOF &&
|
|
|
|
subject here
|
|
|
|
|
|
|
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
|
|
|
[jc: tweaked log message]
|
|
|
|
Signed-off-by: J C H <j@c.h>
|
|
|
|
EOF
|
|
|
|
git commit -F msg &&
|
|
|
|
git cat-file commit HEAD | sed -e '1,/^$/d' >original &&
|
|
|
|
git format-patch --stdout -1 >patch &&
|
|
|
|
|
|
|
|
git reset --hard HEAD^ &&
|
|
|
|
git am -s patch &&
|
|
|
|
(
|
|
|
|
cat original &&
|
|
|
|
echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
|
|
|
|
) >expect &&
|
|
|
|
git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
cat >msg <<-\EOF &&
|
|
|
|
subject here
|
|
|
|
|
|
|
|
We make sure that there is a blank line between the log
|
|
|
|
message proper and Signed-off-by: line added.
|
|
|
|
EOF
|
|
|
|
git reset HEAD^ &&
|
|
|
|
git commit -F msg file &&
|
|
|
|
git cat-file commit HEAD | sed -e '1,/^$/d' >original &&
|
|
|
|
git format-patch --stdout -1 >patch &&
|
|
|
|
|
|
|
|
git reset --hard HEAD^ &&
|
|
|
|
git am -s patch &&
|
|
|
|
|
|
|
|
(
|
|
|
|
cat original &&
|
|
|
|
echo &&
|
|
|
|
echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
|
|
|
|
) >expect &&
|
|
|
|
git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2016-06-05 06:46:41 +02:00
|
|
|
test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git checkout -f first &&
|
|
|
|
echo mboxrd >>file &&
|
|
|
|
git add file &&
|
|
|
|
cat >msg <<-\INPUT_END &&
|
|
|
|
mboxrd should escape the body
|
|
|
|
|
|
|
|
From could trip up a loose mbox parser
|
|
|
|
>From extra escape for reversibility
|
|
|
|
INPUT_END
|
|
|
|
git commit -F msg &&
|
|
|
|
git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
|
|
|
|
grep "^>From could trip up a loose mbox parser" mboxrd1 &&
|
|
|
|
git checkout -f first &&
|
|
|
|
git am --patch-format=mboxrd mboxrd1 &&
|
|
|
|
git cat-file commit HEAD | tail -n4 >out &&
|
|
|
|
test_cmp msg out
|
|
|
|
'
|
|
|
|
|
2016-09-20 19:17:53 +02:00
|
|
|
test_expect_success 'am works with multi-line in-body headers' '
|
|
|
|
FORTY="String that has a length of more than forty characters" &&
|
|
|
|
LONG="$FORTY $FORTY" &&
|
|
|
|
rm -fr .git/rebase-apply &&
|
|
|
|
git checkout -f first &&
|
|
|
|
echo one >> file &&
|
2017-04-01 21:14:39 +02:00
|
|
|
git commit -am "$LONG
|
|
|
|
|
|
|
|
Body test" --author="$LONG <long@example.com>" &&
|
2016-09-20 19:17:53 +02:00
|
|
|
git format-patch --stdout -1 >patch &&
|
|
|
|
# bump from, date, and subject down to in-body header
|
|
|
|
perl -lpe "
|
|
|
|
if (/^From:/) {
|
|
|
|
print \"From: x <x\@example.com>\";
|
|
|
|
print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
|
|
|
|
print \"Subject: x\n\";
|
|
|
|
}
|
|
|
|
" patch >msg &&
|
|
|
|
git checkout HEAD^ &&
|
|
|
|
git am msg &&
|
|
|
|
# Ensure that the author and full message are present
|
|
|
|
git cat-file commit HEAD | grep "^author.*long@example.com" &&
|
2017-04-01 21:14:39 +02:00
|
|
|
git cat-file commit HEAD | grep "^$LONG$"
|
2016-09-20 19:17:53 +02:00
|
|
|
'
|
|
|
|
|
2018-02-14 12:16:06 +01:00
|
|
|
test_expect_success 'am --quit keeps HEAD where it is' '
|
|
|
|
mkdir .git/rebase-apply &&
|
|
|
|
>.git/rebase-apply/last &&
|
|
|
|
>.git/rebase-apply/next &&
|
|
|
|
git rev-parse HEAD^ >.git/ORIG_HEAD &&
|
|
|
|
git rev-parse HEAD >expected &&
|
|
|
|
git am --quit &&
|
|
|
|
test_path_is_missing .git/rebase-apply &&
|
|
|
|
git rev-parse HEAD >actual &&
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2008-06-01 00:11:42 +02:00
|
|
|
test_done
|