Bug ===
The command
git rebase --whitespace=fix --keep-empty <commit>
does not fix whitespace in the rebased commits.
Example =======
Set up a repo with a whitespace error commit and an empty commit:
git init rebase-bug.git cd rebase-bug.git touch foo git add foo touch foo git add foo git commit -m "Empty foo" echo "xxx " > foo git add foo git commit -m "Trailing whitespace foo" git commit --allow-empty -m "Empty commit
Now we have the following commits (adding '$' at EOL to make trailing whitespace clear):
git log --oneline --patch | sed -re 's/$/$/'
d383707 Empty commit$ 4b71cd0 Trailing whitespace foo$ diff --git foo foo$ index e69de29..272a831 100644$ --- foo$ +++ foo$ @@ -0,0 +1 @@$ +xxx $ 26d51d6 Empty foo$ diff --git foo foo$ new file mode 100644$ index 0000000..e69de29$
Make a backup:
cp -r ../rebase-bug.git{,.backup}We can now fix the whitespace with 'git rebase --whitespace=fix', but this drops the empty commit:
git rebase --whitespace=fix HEAD~2
Current branch master is up to date, rebase forced. First, rewinding head to replay your work on top of it... Applying: Trailing whitespace foo
git log --oneline --patch | sed -re 's/$/$/'
2f6f66d Trailing whitespace foo$ diff --git foo foo$ index e69de29..d6459e0 100644$ --- foo$ +++ foo$ @@ -0,0 +1 @@$ +xxx$ 26d51d6 Empty foo$ diff --git foo foo$ new file mode 100644$ index 0000000..e69de29$
If we add '--keep-empty', then we keep the empty commit, but the whitespace is not fixed:
cd ../rebase-bug.git.backup git rebase --whitespace=fix --keep-empty HEAD~2
Current branch master is up to date, rebase forced. First, rewinding head to replay your work on top of it... [detached HEAD a48c4c8] Trailing whitespace foo 1 file changed, 1 insertion(+) [detached HEAD 8a15ca4] Empty commit
git log --oneline --patch | sed -re 's/$/$/'
f852c53 Empty commit$ f8c3626 Trailing whitespace foo$ diff --git foo foo$ index e69de29..272a831 100644$ --- foo$ +++ foo$ @@ -0,0 +1 @@$ +xxx $ 26d51d6 Empty foo$ diff --git foo foo$ new file mode 100644$ index 0000000..e69de29$
Git version ===========
I'm using git version 1.8.2.3.
Motivation ==========
http://stackoverflow.com/a/15398512/470844
I wanted a Git alias to remove whitespace errors from the index and tree. I tried this:
fixws-global-tree-and-index = !"\
git commit --allow-empty -m FIXWS_SAVE_INDEX && \
git add -u :/ && \
git commit --allow-empty -m FIXWS_SAVE_TREE && \
git rebase --whitespace=fix --keep-empty HEAD~2 && \
git reset HEAD~ && \
git reset --soft HEAD~"But, it does not work, because of the bug illustrated above. So, instead, I have this:
fixws-global-tree-and-index = !"\
if (! git diff-files --quiet .) && \
(! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git add -u :/ && \
git commit -m FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~2 && \
git reset HEAD~ && \
git reset --soft HEAD~ ; \
elif (! git diff-files --quiet .) ; then \
git add -u :/ && \
git commit -m FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~ && \
git reset HEAD~ ; \
elif (! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git rebase --whitespace=fix HEAD~ && \
git reset --soft HEAD~ ; \
fi"I.e., I calculate which commits are non-empty and only make those commits.
Cheers,
-nathan