I have a script that among other things uses git rebase
to remove a specific commit from the current branch.
In one case, it removes a seemingly random file.
After long debugging session, I've managed to track it down to a rename detection mechanism during a merge performed by git rebase
.
All my attempts to disable this mechanism failed. What can I do?
Here is a shell script that reproduces the problem:
#!/bin/sh
mkdir test-repo
cd test-repo
git init
git config --local user.name nobody # just in case
git config --local user.email whatever@myself.lan # just in case
printf 'x\nx\n' >foo
git add .
git commit -m 'Added some files'
rm foo
printf 'y\nx\n' >bar # the contents of bar are slightly similar to foo
git add .
git commit -m 'The comit to discard'
printf 'z\nx\n' >bar
git add .
git commit -m 'The commit to keep'
git rebase --strategy-option=theirs --onto HEAD~2 HEAD~1
if [ ! -f bar ]
then
echo 'WHY!?'
fi
It looks like the modern merge strategy called ort
does not implement merge.renames=false
and always does rename detection.
You can select the old merge strategy recursive
that does heed this setting:
git -c merge.renames=false rebase --strategy=recursive --onto HEAD~2 HEAD~1
Be warned, though, that this will leave behind a conflict that cannot be resolved automatically. In particular, --strategy-option=theirs
does not do anything useful. You can then
git checkout --theirs bar
to resolve the conflict but is that really what you need, because then you have both foo
and bar
in the repository?