Posted about 5 years ago. Visible to the public.

How to not leave trailing whitespace (using your editor or Git)

There is no reason to leave trailing whitespace characters in your project's files, so don't add any.

A git diff --check will tell you if there are any and you should not commit when you see them. So go ahead and switch your editor/IDE to automatically remove them for you.
Below are a few instructions on how to get them removed by your favorite IDE or editor.

Note that except for RubyMine, the following changes will remove trailing white-space on all lines, not only those that you changed.
While this should not be a problem if your project is always clean of trailing spaces, it may not be what you want if you are in the wild west.

In that case you need to take care not to commit trailing spaces. Always git diff --check, kids!

RubyMine

  • Open Settings (Ctrl-Alt-S)
  • Go to "Editor" → "General"
  • At the bottom, set "Strip trailing white spaces on Save" to "Modified Lines"

Sublime Text 2

  • Open the "Preferences" menu
  • Choose "File Settings – Default" (it will open Base File.sublime-settings for you)
  • Set "trim_trailing_white_space_on_save": true

Vim

  • Open up your ~/.vimrc file
  • Add this:

    Copy
    autocmd BufWritePre * :%s/\s\+$//e

If that is too invasive for you, try only highlighting trailing spaces like suggested in the Vim wiki (also put this into your ~/.vimrc):

Copy
" Show trailing whitepace and spaces before a tab: :highlight ExtraWhitespace ctermbg=red guibg=red :autocmd Syntax * syn match ExtraWhitespace /\s\+$\| \+\ze\t/

TextMate

  • The Text bundle offers a command Remove Trailing Spaces in Document / Selection, which you can call before saving. This is not aware of git (i.e., which lines YOU have edited).
  • In the bundle editor, assign it a shortcut like Cmd + Alt + Backspace.
  • Update: Since 9-29-2012, TextMate2 has a callback will-save. In the above command, set 'Semantic class' to callback.document.will-save, and it will be called before saving the document.

Git (manually)

Git can fix whitespace in patches which you can make use of: git diff --cached --no-color > stage.diff && git apply --index -R stage.diff && git apply --index --whitespace=fix stage.diff && rm -f stage.diff. Store this as an alias and run before committing.

Git (automatically before commit)

You can tell git to react on trailing whitespace in a pre-commit hook. By default it will cancel a commit that contains trailing whitespace (and disallow non-ascii filenames), but you can modify it to automatically fix the whitespace, see below. (Note that this might lead to unexpected behaviour e.g. in Markdown documents.)

The global git hooks live in $PREFIX/share/git-core/templates/hooks (where $PREFIX is probably /usr/local or /usr). Rename the pre-commit.sample file to pre-commit to activate it. Afterwards, you'll need to re-initialize already cloned repositories with git init, which will essentially copy all hooks from the templates directory to that repository's .git/hooks. (You can always bypass the pre-commit hook by committing with the --no-verify option.)

In order to have git fix whitespace on lines you edited before each commit, append the following code to the pre-commit hook template (but before existing whitespace checks like exec git diff-index --check --cached $against --):

Copy
# A git hook script to find and fix trailing whitespace in your commits. Bypass # it with the --no-verify option to git-commit. # detect platform platform="win" uname_result=`uname` if [[ "$uname_result" == "Linux" ]]; then platform="linux" elif [[ "$uname_result" == "Darwin" ]]; then platform="mac" fi # change IFS to ignore filename's space in |for| IFS=" " # remove trailing whitespace in modified lines for line in `git diff --check --cached | sed '/^[+-]/d'` ; do # get file name if [[ "$platform" == "mac" ]]; then file="`echo $line | sed -E 's/:[0-9]+: .*//'`" line_number="`echo $line | sed -E 's/.*:([0-9]+).*/\1/'`" else file="`echo $line | sed -r 's/:[0-9]+: .*//'`" line_number="`echo $line | sed -r 's/.*:([0-9]+).*/\1/'`" fi # since $file in working directory isn't always equal to $file in index, # we backup it; thereby we can add our whitespace fixes without accidently # adding unstaged changes backup_file="${file}.working_directory_backup" cat "$file" > "$backup_file" git checkout -- "$file" # discard unstaged changes in working directory # remove trailing whitespace in $file (modified lines only) if [[ "$platform" == "win" ]]; then # in windows, `sed -i` adds ready-only attribute to $file (I don't kown why), so we use temp file instead sed "${line_number}s/[[:space:]]*$//" "$file" > "${file}.bak" mv -f "${file}.bak" "$file" elif [[ "$platform" == "mac" ]]; then sed -i "" "${line_number}s/[[:space:]]*$//" "$file" else sed -i "${line_number}s/[[:space:]]*$//" "$file" fi git add "$file" # to index, so our whitespace changes will be committed # restore unstaged changes in $file from its working directory backup, fixing # whitespace that we fixed above sed "${line_number}s/[[:space:]]*$//" "$backup_file" > "$file" rm "$backup_file" [[ "$platform" == "mac" ]] || e_option="-e" # mac does not understand -e echo $e_option "Removed trailing whitespace in \033[31m$file\033[0m:$line_number" done echo # credits: # https://github.com/philz/snippets/blob/master/pre-commit-remove-trailing-whitespace.sh # https://github.com/imoldman/config/blob/master/pre-commit.git.sh # If there still are whitespace errors, print the offending file names and fail. exec git diff-index --check --cached $against -- # Now we can commit exit
Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Author of this card:

Avatar
Arne Hartherz
Last edit:
over 2 years ago
by Arne Hartherz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandropedia