I have some trouble using the --keep-empty
option of git rebase
, and I'm
not sure whether I'm misunderstanding what this option does, or there's a bug.
Here is a minimal example:
Setup
Create a new Git repository and an initial, unrelated commit.
$ git init $ echo something >base.txt $ git add base.txt $ git commit -m 'some base commit to not run into the root corner case'
Create a new commit which adds two new files.
$ echo A >a.txt; echo B >b.txt $ git add a.txt b.txt $ git commit -m 'add A and B'
Modify one of the files.
$ echo A1 >a.txt $ git add a.txt $ git commit -m 'change A'
Modify the other file.
$ echo B1 >b.txt $ git add b.txt $ git commit -m 'change B'
Rebase
$ git checkout -b rebased master
$ git rebase --keep-empty -i :/base
… choosing to edit
the commit where A
and B
are added, and changing it so that only B
is added (in a real scenario the reason might be that A
is confidential):
$ git rm a.txt
$ git commit --amend
$ git rebase --continue
Naturally, the next commit where A
is modified now gives a conflict:
error: could not apply 182aaa1... change A
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply 182aaa1701ad100fc02a5d5500cacebdd317a24b... change A
… choosing to not add the modified version of a.txt
:
$ git mergetool
Merging:
a.txt
Deleted merge conflict for 'a.txt':
{local}: deleted
{remote}: modified file
Use (m)odified or (d)eleted file, or (a)bort? d
The commit where A
was modified is now empty:
$ git diff --cached
# nothing
… and finishing the rebase:
$ git rebase --continue
Successfully rebased and updated refs/heads/rebased.
Question
So now I have two versions of my history, with the difference that there is no trace of A
in one of them. However, because I chose the --keep-empty
option, I still expect an empty commit to exist in rebased
, which would show me that A
would have been modified, had it been there.
But apparently, this is not the case:
$ git log --oneline master
f893569 change B
182aaa1 change A
3340b71 add A and B
38cb5da some base commit to not run into the root corner case
$ git log --oneline rebased
73a2c05 change B
55f502b add A and B
38cb5da some base commit to not run into the root corner case
Is this not what --keep-empty
is supposed to do, or does it not work
correctly?
Related: Rebase on the root and keep empty commits is a very similar question, but it involves the --root
corner case which I explicitly avoided here. And it has no answer, only some comments which suggest that what I'm showing here should work. Another difference is that in the other question the commit is empty in the first place, while here it only becomes empty after resolving a conflict.