I am doing a rebase of a big change, with a lot of whitespace changes. In order for the merge to work at all, I need -Xignore-all-space.
According to git --help rebase:
ignore-space-change, ignore-all-space, ignore-space-at-eol
Treats lines with the indicated type of whitespace change as unchanged for the sake of a three-way merge. Whitespace changes mixed with other changes to a line are not ignored. See also git-diff(1) -b, -w, and --ignore-space-at-eol.
o If their version only introduces whitespace changes to a line, our version is used;
o If our version introduces whitespace changes but their version includes a substantial change, their version is used;
o Otherwise, the merge proceeds in the usual way.
However, when in a rebase, theirs and ours are swapped from their usual meaning. This means that in my rebase, all my whitespace changes are lost, since they are on their side of the merge.
How do I get git-rebase to keep my whitespace changes?
The Rebase Option But, instead of using a merge commit, rebasing re-writes the project history by creating brand new commits for each commit in the original branch. The major benefit of rebasing is that you get a much cleaner project history. First, it eliminates the unnecessary merge commits required by git merge .
Some things to keep in mind before you rebase: Never rebase commits that have been pushed and shared with others. The only exception to this rule is when you are certain no one on your team is using the commits or the branch you pushed.
If the feature branch you are getting changes from is shared with other developers, rebasing is not recommended, because the rebasing process will create inconsistent repositories. For individuals, rebasing makes a lot of sense. If you want to see the history completely same as it happened, you should use merge.
All the commits on a feature branch are combined into a single commit on the master branch. All commits are rebased, and the same number of commits are added to the master branch. Merge is best used when the target branch is supposed to be shared. Rebase is best used when the target branch is private.
There's a way, but it's ugly. You're much better off keeping whitespace and "real" changes separate, and upstreaming the former first before doing the latter. But if you find yourself in this situation...
For the sake of simplicity, I am assuming that everything is in a single commit in the current branch. This should work in a multi-commit situation, it just (again) will be more ugly. I'm also assuming the branch to rebase onto is master
, and your working branch forked from it somewhere down the line.
git merge master -Xignore-all-space --no-commit
. Resolve the merge to your satisfaction.rm .git/MERGE_*
. We're going to convince git that this is a regular commit, not a merge.git commit -a -m "Pseudo-merge from master"
git rebase -i HEAD^^
and "fixup" the last change into your original one. We could have combined this with the previous step, but actually committing the pseudo-merge gives us a commit to reset to in case something goes wrong later. If this is a multiple-commit change you're working with, you may want/need to move the psuedo-merge change to a different point in the history before you squash it, to properly simulate the rebase.git rebase HEAD^ --onto master -Xtheirs
The "-Xtheirs" says to always prefer their changes, but "ours" and "theirs" are flipped in a rebase, so that means to always prefer ours. This is safe, since we manually resolved the rebase (via merge) already.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With