How can you combine git add patch -p mode with diff's ignore-all-space How can you combine git add patch -p mode with diff's ignore-all-space git git

How can you combine git add patch -p mode with diff's ignore-all-space


Here's an adaptation from a related question.

git diff -w --no-color | git apply --cached --ignore-whitespace

It has the benefit that you don't need to use stash, temporary files, or perform a reset --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...

:r !git diff -w --no-color:set ft=diff  # if you want syntax highlighting

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...

:w !git apply --cached --ignore-whitespace

If you're a Vim afficionado, you could use visual mode to stage, too!

:<',>'w !git apply --cached --ignore-whitespace

You can commit the staged changes with the ex command...

:!git commit -m "message"# or:!git commit

Clear the buffer, read the unstaged changes, and repeat

:bd! | set ft=diff | r !git diff -w --no-color

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 into git 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...

git diff -w --no-color | git apply --cached --ignore-whitespace

...you can unstage chunks in patch mode with...

git reset --patch .

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.


A more robust and versatile version of @"Justin C"s answer is:

anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"
  • With no argument - adds all tracked files' non-whitespace changes
  • Given files/directories - only adds non-whitespace changes in those locations

See this answer for more.


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 | git apply --cached --ignore-whitespace && git checkout -- . && git reset && git add -p

git diff -w --no-color creates a diff

git apply --cached --ignore-whitespace applies the diff ignoring whitepace, and indexes it

git checkout -- . removes the unindexed “whitespace” changes

git reset resets the index to just the non-whitespace changes

git add -p adds the non-whitespace changes in patch mode

Wrap 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:

gwap= !git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero && git checkout -- . && git reset && git add -p 

(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