How can I do git add with patch mode but ignoring whitespace changes.
The use case is for when you've reformatted a file and also made changes to it. I want to commit the real code changes separately first (as shown by git diff -w path) and then commit the reformatting as a separate commit.
Here's an adaptation from a related question.
It has the benefit that you don't need to use
stash
, temporary files, or perform areset --hard
on your working folders.Addendum
The solution above only stages changes except whitespace-only edits. This did not address patch, though using
--patch
to stage isn't straight forward in this situation.Patch Option 1: Edit the diff in a text editor
There are many ways to implement this using a text editor. Vim is especially suited to this.
In the root directory of your repository, start Vim.
In normal mode, load the diff into an empty buffer with...
Edit the diff and remove the parts you don't want to stage.
To stage the contents of the vim buffer, run the vim ex command...
If you're a Vim afficionado, you could use visual mode to stage, too!
You can commit the staged changes with the ex command...
Clear the buffer, read the unstaged changes, and repeat
Eventually, you'll be left with only whitespace changes to commit.
If you don't use Vim, you could also dump
git diff
into a file, edit the file, save, then feed the file intogit apply
. Commit and repeat until done. It's a bit tedious, but functional.Patch Option 2: Patch reset
It's backwards from
git add --patch
, but once you've staged non-whitespace changes with......you can unstage chunks in patch mode with...
Keep in mind you're removing the changes that you want to keep staged. Repeat and commit as necessary until you only have whitespace changes left.
If you want to do git add --patch but ignore all whitespace like the asker is asking, you can do this in one command:
git diff -w --no-color
creates a diffgit apply --cached --ignore-whitespace
applies the diff ignoring whitepace, and indexes itgit checkout -- .
removes the unindexed “whitespace” changesgit reset
resets the index to just the non-whitespace changesgit add -p
adds the non-whitespace changes in patch modeWrap this up in an alias, like so:
alias gwap=“git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero && git checkout -- . && git reset && git add -p”
Or if you're on a unix based system like I am:
(Notice I added options
-U0
, and--unidiff-zero
respectively to workaround context matching issues, according to this comment.)Source: https://til.hashrocket.com/posts/696df00135-remove-whitespace-changes-then-git-add-p
A more robust and versatile version of @"Justin C"s answer is:
See this answer for more.
I suggest simply roundtripping a diff
Idea:
Warning: this is fraught with danger because of the
git reset
there (it will not preserve changes to binary files as written). Perhaps you'd want a bash function similar toAfaict the seemingly useful
--binary
option to diff doesn't honour the whitespace ignore flags