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

前端 未结 4 2118
别跟我提以往
别跟我提以往 2021-01-31 08:36

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 t

相关标签:
4条回答
  • 2021-01-31 09:11

    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

    0 讨论(0)
  • 2021-01-31 09:29

    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

    0 讨论(0)
  • 2021-01-31 09:32

    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.

    0 讨论(0)
  • 2021-01-31 09:35

    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.

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