threads / discuss / 59684

git merge crash "fatal: stash failed" with smudge/clean filters

Subject: git merge crash "fatal: stash failed" with smudge/clean filters

## tl;dr

One message between May 2, 2023 and May 2, 2023.

replies: 0people: 1as markdown or json

Joey Hess· May 2, 2023, 17:21 UTC · lore

The attached testcase seems to show a bug in git. git merge crashes with an internal error of "fatal: stash failed".

The testcase uses some very basic smudge/clean filters, and that is necessary to see the crash. (The filters may be kinda broken, they're the first thing I tried to detangle this bug from git-annex.)

The test case first creates an empty file, and that is somehow significant. While the merge does not directly involve that empty file, omitting adding the empty file, or making it have any non-empty content avoids the merge crash. And the crash happens after cleaning the empty file:

joey@darkstar:~/tmp/x/testcase-workdir/repo1>GIT_PACKET_TRACE=1 GIT_TRACE=1 git merge repo2/master 13:17:20.064936 git.c:439 trace: built-in: git merge repo2/master 13:17:20.070120 run-command.c:655 trace: run_command: '.git/test-clean '\''emptyfile'\''' 13:17:20.094653 run-command.c:655 trace: run_command: git stash create 13:17:20.097780 git.c:439 trace: built-in: git stash create 13:17:20.099213 run-command.c:655 trace: run_command: '.git/test-clean '\''emptyfile'\''' fatal: stash failed

git version 2.40.1.459.g48d89b51b3
-- 
see shy jo


#!/bin/bash
setup_smudge_clean() {
	cat <<'EOF' > .git/test-clean
#!/bin/sh
mkdir -p ../content
cat > ../content/new.content
v=$(sha1sum ../content/new.content | cut -d ' ' -f 1)
mv ../content/new.content ../content/$v.content
echo "$v"
EOF
	cat <<'EOF' > .git/test-smudge
#!/bin/sh
v=$(cat)
cat ../content/$v.content
EOF
	chmod +x .git/test-clean
	chmod +x .git/test-smudge
	git config filter.foo.smudge '.git/test-smudge %f'
	git config filter.foo.clean '.git/test-clean %f'
	echo "* filter=foo" > .git/info/attributes
}

mkdir testcase-workdir
cd testcase-workdir
git init repo1
cd repo1
setup_smudge_clean
git commit --allow-empty -m foo
git remote add repo2 ../repo2
cd ..
git clone repo1 repo2
cd repo2
git remote add repo1 ../repo1
setup_smudge_clean
cd ..

cd repo1
touch emptyfile
git add emptyfile
git commit -m add
cd ../repo2
git pull

echo foo > testfile
git add testfile
git commit -m foo
cd ../repo1
echo bar > testfile
git add testfile
git commit -m bar
git fetch repo2 master
git merge repo2/master # crashes

← back to recent threads