Git tool to remove lines from staging if they consist only of changes in whitespace

前端 未结 3 1777
感情败类
感情败类 2021-02-05 22:28

The point in removing trailing whitespace is that if everyone does it always then you end up with a diff that is minimal, ie. it consists only of code changes and not whitespace

相关标签:
3条回答
  • 2021-02-05 23:08

    The following will get you most of the way there:

    $ clean=`git diff --cached -b`; \
      git apply --cached <(git diff --cached -R); \
      echo "$clean" | git apply --cached -; \
      clean=

    For releases of git prior to 1.7.0, it fails if one or more files have all-whitespace changes. For example

    $ git diff --cached -b
    diff --git a/file1 b/file1
    index b2bd1a5..3b18e51 100644
    diff --git a/file2 b/file2
    new file mode 100644
    index 0000000..092bfb9
    --- /dev/null
    +++ b/file2
    [...]

    The empty delta (of file1 above, which really ought to be suppressed) makes git-apply unhappy:

    fatal: patch with only garbage at line 3

    UPDATE: The 1.7.0 release of git fixes this issue.

    Say our repository is in the following state:

    $ git diff --cached
    diff --git a/foo b/foo
    index 3b18e51..a75018e 100644
    --- a/foo
    +++ b/foo
    @@ -1 +1,2 @@
    -hello world
    +hello  world
    +howdy also

    We could then run the above commands to fork the index and work tree:

    $ git diff --cached
    diff --git a/foo b/foo
    index 3b18e51..1715a9b 100644
    --- a/foo
    +++ b/foo
    @@ -1 +1,2 @@
     hello world
    +howdy also
    
    $ git diff 
    diff --git a/foo b/foo
    index 1715a9b..a75018e 100644
    --- a/foo
    +++ b/foo
    @@ -1,2 +1,2 @@
    -hello world
    +hello  world
     howdy also

    If all changes are whitespace-only, you'll see

    error: No changes

    I suspect fixing the index and leaving undesired changes in the work tree would surprise or even irritate most users, but that's the behavior the question asked for.

    0 讨论(0)
  • 2021-02-05 23:26

    I'd been using a script based on @GregBacon's answer for years, but at some point git changed the output of git diff -b so that the whitespace changes it didn't show as changes were included in the patch context lines in the after state rather than the before state.

    I found if I reversed the clean diff and the corresponding apply, the script would work again.

    So my complete script used to look like this:

    #!/bin/bash
    
    clean=`git diff --cached -b`
    git apply --cached <(git diff --cached -R)
    echo "$clean" | git apply --cached -
    clean=
    

    And now looks like:

    #!/bin/bash
    
    clean=`git diff --cached -b -R`
    git apply --cached <(git diff --cached -R)
    echo "$clean" | git apply --cached -R -
    clean=
    

    I also have a script to leave only whitespace changes in a commit. This is useful if while you fix something you make some whitespace fixes elsewhere in the file, and you want to commit the whitespace fixes first in a separate commit. It is just:

    git apply --cached -R <(git diff --cached -w)
    
    0 讨论(0)
  • 2021-02-05 23:27

    My solution on git 1.7.2.5 was as follows (starting without any changes staged):

    git diff -w > temp.patch
    git stash
    git apply --ignore-space-change --ignore-whitespace temp.patch
    # tidy up:
    rm temp.patch
    git stash drop
    

    This leaves your repo back in the starting state with any whitespace only changes removed.

    You can then stage your changes as usual.

    0 讨论(0)
提交回复
热议问题