Bug Report ( including test script ): Non-Fastforward merges misses directory deletion
- From
Sebastian Thiel <byronimo@gmail.com>
- Date
- Feb 18, 2010, 10:00 UTC
- Message-ID
- <loom.20100218T104300-858@post.gmane.org>
Hello,
I recently recognized a bug that is related to the merge of deletions. If there is a single file at path 'dir/subdir/file', and the file is deleted in one branch called 'del', git merge fails to delete 'dir' if 'del' is merged into another branch where the path still existed if --no-ff is given ( or if a fast-forward is not possible ). Apparently, it will only delete the immediate parent directory, but cannot work its way up to the remaining empty directories. If a fast-forward is possible, 'dir' will be deleted as one would expect it - perhaps git will internally just do a checkout which is implemented differently.
The issue could be reproduced on git 1.7.0 and 1.6.5, I have not tested other versions though.
To reproduce the issue, execute the following script. It will exit with status 5 to indicate the base top-level directory still exists.
Regards, Sebastian
--------------------------------------------------------------------------
#!/bin/bash reponame=testrepo basedir=dir dirpath=$basedir/subdir filepath=$dirpath/file
# setup git repo mkdir $reponame cd $reponame git init
# make dir and file mkdir -p $dirpath echo data > $filepath
# initial commit git add $dirpath git commit -m "initial commit"
# create branch with deletion git co -b del git rm -r $dirpath git commit -m "deleted folder"
# merge fast forward - it works git co master git merge del
# assertion - directory must not exist [[ ! -d $dirpath ]] || exit 1 [[ ! -d $basedir ]] || exit 2
# undo merge, again with non-fastforward git reset --hard master~1
# as a test, one can make a fast-forward impossible - the issue still shows up #echo "some data" > new_file #git add new_file #git commit -m "new file" #git merge del
git merge --no-ff del
# the directory should be gone, but effectively only the file is AND the files # empty parent directory [[ ! -f $filepath ]] || exit 3 [[ ! -d $dirpath ]] || exit 4 [[ ! -d $basedir ]] || exit 5
echo "It worked actually !"