git-am doesn't compute intermediate hashes when patch applies cleanly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
(Git 2.48.1)
Imagine this scenario:
* I have a patch file with two commit, A and B that both touch the same file F.
* The patch file has hashes on the files (for --3way)
* I apply the patches with --3way
* A applies cleanly (even though the file is different)
* B requires a 3way merge

Now, because A applies cleanly, no fake ancestor was created for F.
Then, when B fails to apply cleanly, the patch file for F contains
unknown sha1 hash and the 3way merge fails.
In other words, because Git didn't build fake ancestors for A it lost
the opportunity to learn about hashes that are relevant for B.

Is there a way to "force" using a 3-way merge for all commits, even
when a patch applies cleanly?

Here's a bash script to reproduce the issue:

---- START OF SCRIPT ----
#!/bin/bash

set -e

echo
echo ====================================
echo "GENERATE PATCH"
echo ====================================
echo

rm -rf src_repo
git -c init.defaultBranch=bug init src_repo
cd src_repo

printf "1\n2\n3\n4\n5\n6\n7\n8\n9" > file
git add file
git commit -m base

printf "11\n2\n3\n4\n5\n6\n7\n8\n9" > file
git commit -am first
printf "11\n2\n3\n4\n5\n66\n7\n8\n9" > file
git commit -am second

git format-patch -2 --stdout > test.patch
cd ..

echo
echo ====================================
echo "SANITY TEST"
echo " - apply to indentical file in another repository"
echo ====================================
echo

rm -rf sanity_repo
git -c init.defaultBranch=bug init sanity_repo
cd sanity_repo

printf "1\n2\n3\n4\n5\n6\n7\n8\n9" > file
git add file
git commit -m "identical content"

git am --3way --keep-cr ../src_repo/test.patch
cd ..

echo
echo ====================================
echo "GOOD 3-WAY TEST"
echo " - apply to modified file in another repository"
echo " - have the original file in the repository as well, so that
sha1 is present"
echo " - change the file so that the first commit fails to apply cleanly"
echo " - this will force a 3-way merge and the intermediate sha1 will
be created"
echo " - the second commit will fail to apply cleanly"
echo " - this will force a 3-way merge and the intermediate sha1 will
be used to create an ancestor"
echo ====================================
echo

rm -rf good_repo
git -c init.defaultBranch=bug init good_repo
cd good_repo

printf "1\n2\n3\n4\n5\n6\n7\n8\n9" > file
git add file
git commit -m "identical content"

printf "1\n2\n3\n4XXX\n5\n6\n7\n8\n9" > file
git commit -am "change in hunk"

git am --3way --keep-cr ../src_repo/test.patch
cd ..

echo
echo ====================================
echo "BAD 3-WAY TEST"
echo " - apply to modified file in another repository"
echo " - have the original file in the repository as well, so that
sha1 is present"
echo " - change the file so that the first commit does apply cleanly
but the hashes are different now"
echo " - no 3-way merge was performed so the intermediate sha1 is missing"
echo " - the second commit will fail to apply cleanly"
echo " - this will force a 3-way merge and the git will complain about
intermediate sha1 error"
echo ====================================
echo

rm -rf bad_repo
git -c init.defaultBranch=bug init bad_repo
cd bad_repo

printf "1\n2\n3\n4\n5\n6\n7\n8\n9" > file
git add file
git commit -m "identical content"

printf "1\n2\n3\n4\n5\n6\n7\n8\n9XXX" > file
git commit -am "change outside of hunk"

git am --3way --keep-cr ../src_repo/test.patch || echo FAILED!!!

cd ..

echo
echo ====================================
echo "WORKAROUND 3-WAY ISSUE"
echo " - demonstrate the patch can in theory be applied"
echo " - start with the same report as bad_repo"
echo " - first apply the patch to the original commit to reconstruct
intermediate hashes"
echo " - then apply to the latest commit, now it succeeds"
echo ====================================
echo

rm -rf workaround_repo
git -c init.defaultBranch=bug init workaround_repo
cd workaround_repo

printf "1\n2\n3\n4\n5\n6\n7\n8\n9" > file
git add file
git commit -m "identical content"

printf "1\n2\n3\n4\n5\n6\n7\n8\n9XXX" > file
git commit -am "change outside of hunk"

git checkout @~
git am --3way --keep-cr ../src_repo/test.patch
git checkout bug

git am --3way --keep-cr ../src_repo/test.patch

cd ..

---- END OF SCRIPT ----




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux