Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 316
Sam Avatar asked Jul 04 '11 12:07

Sam


People also ask

How do I ignore a space in git?

Use the git diff Command to Ignore Whitespaces in Git We use the git diff -w command to ignore all whitespace differences. It will ignore spaces at the beginning, middle, and end of lines. We use the git diff --ignore-space-at-eol command to ignore whitespace changes at the end of our lines.

How do I ignore whitespace in diff?

The --ignore-trailing-space ( -Z ) option ignores white space at line end. Re: "-w or --ignore-all-space option does not ignore newline-related changes" So -w ignores all whitespace, except for the whitespace it doesn't ignore.

How do I ignore whitespace changes in Github?

On github, you simply append the w=1 parameter to the URL for it to ignore whitespace.

What@@ means in git diff?

Simple example analysis @@ -1,6 +1,4 @@ means: -1,6 means that this piece of the first file starts at line 1 and shows a total of 6 lines. Therefore it shows lines 1 to 6. 1 2 3 4 5 6. - means "old", as we usually invoke it as diff -u old new .


2 Answers

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.

like image 85
Justin C Avatar answered Oct 17 '22 08:10

Justin C


Note: This answer is old. 6 years down the road, the other answer by Justin is much better. Prefer to use git apply --cached

I suggest simply roundtripping a diff

Idea:

git diff --ignore-all-space | (git reset --hard && git apply) 

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 to

function cleanup_patch() {     if [ $# -lt 1 ]; then          echo 'Must provide explicit paths (wildcards allowed)';      else         git diff --ignore-all-space -- "$@" |             (git checkout HEAD -- "$@" &&              git apply)     fi } 

Afaict the seemingly useful --binary option to diff doesn't honour the whitespace ignore flags

like image 38
sehe Avatar answered Oct 17 '22 07:10

sehe