I have a script that does a git rebase with the flags --empty=keep and --keep-empty. It's important that no commit is dropped because the script later relies on relative refs (like HEAD~3) and on the order of the commits in general. Unfortunately, I found a scenario in which a commit is still lost in the rebase.
If during a rebase you have a conflict of a file being modified in the target branch and deleted in the rebased branch, and you solve it by keeping the file, the commit that removes it is dropped from the rebase despite the option to keep empty commits. Here's a script that reproduces that scenario:
git init git config --local user.name foo git config --local user.email [email protected] echo foo >aaa git add aaa git commit -m 'Added aaa' git branch -m target_branch echo bar >aaa git add aaa git commit -m 'Changed aaa' git switch -c rebased_branch HEAD~1 git rm aaa git commit -m 'Removed aaa' git log --oneline --graph --all --decorate # * 25bd816 (HEAD -> rebased_branch) Removed aaa # | * 7c888f8 (target_branch) Changed aaa # |/ # * d22ceb0 Added aaa git rebase target_branch --empty=keep --keep-empty git add aaa git rebase --continue git log --oneline --graph --all --decorate # * 7c888f8 (HEAD -> rebased_branch, target_branch) Changed aaa # * d22ceb0 Added aaa The first git log shows the expected commit tree. Then the rebase happens and the commit "Removed aaa" vanishes.
Is this intended or a bug? Is there some way to keep this commit?