Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git remove trailing whitespace in new files before commit

I know removing trailing whitespace can be done with a pre-commit hook. I am interested in doing it manually. I read the question here:
Make git automatically remove trailing whitespace before committing - Stack Overflow
The answer closest to what I want is the "automatic version" from ntc2:

(export VISUAL=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset


That command works well except it seems to be only for changes on files that are already in the repo, not new files. I have a bunch of files that are new, meaning they aren't yet in the repo. I want to remove whitespace from those files so I tried add -A instead of -u but that didn't make a difference.

like image 968
loop Avatar asked Oct 03 '13 06:10

loop


People also ask

How do I remove a trailing space in git?

You can have two spaces at end of line in markdown and not have it as trailing whitespace by adding " \ " before \n . This user is first on the weekly GitLab leaderboard. Turns out git can be convinced to fix whitespace in your working copy via apply.

What is a trailing whitespace?

Trailing whitespace is any spaces or tabs after the last non-whitespace character on the line until the newline.

How do I delete a trailing space in Vim?

Every time the user issues a :w command, Vim will automatically remove all trailing whitespace before saving.


2 Answers

To manually clean up whitespace from your last 3 commits, you can do this:

git rebase --whitespace=fix HEAD~3

When I work on a topic branch, I track the upstream branch (usually by creating it like this)

git checkout -b topic -t

Which allows me to drop the last argument from git rebase. So once I'm done & ready to merge, I can clean the whole topic branch quickly with:

git ws # aliased to rebase --whitespace=fix

Note that, unlike the HEAD~3 example, this will actually rebase your changes upon the upstream branch if it's changed! (But that's also what I want, in my workflow.)

like image 144
Luke Usherwood Avatar answered Sep 21 '22 13:09

Luke Usherwood


I like Luke's answer, except for the limitation that you need to either manually specify the base commit, or use a rebase-style workflow, where your history is linearized. I propose a modification that doesn't need an extra argument and doesn't change the topology of your commit graph. As a shell command:

git rebase --whitespace=fix --onto $(git merge-base HEAD @{u})

Or as a ~/.gitconfig alias:

ws = "!git rebase --whitespace=fix --onto $(git merge-base HEAD @{u})"

I prefer this because sometimes I want to rebase my changes, but if I think think there might be a merge conflict I prefer to merge, so that both my original change and the conflict resolution will be recorded in the history. That way I can later second-guess the conflict resolution and redo it if necessary.

Given that I don't always rebase, I prefer not to mix whitespace-fixing with rebasing; hence this modification to Luke's answer.

In addition, I enable the default pre-commit hook which aborts on whitespace errors:

cp .git/hooks/pre-commit.sample .git/hooks/pre-commit

This gives the following workflow, which I like because it's manual enough that I know what's going on but automated enough not to get in the way:

  1. hack hack hack, introduce whitespace error
  2. attempt to commit
  3. commit fails with whitespace error due to pre-commit hook
  4. git commit --no-verify to commit anyway
  5. git ws use the alias to fix

Note on the usage of --onto: It's not necessary here, but I find it easier to reason about how the rebase works this way. In Luke's version, HEAD~3 is the <upstream> in the man page, while in my version <upstream> keeps its default value of the real upstream of the branch. You wind up with the same result either way though.

like image 30
jbyler Avatar answered Sep 23 '22 13:09

jbyler