Instantly share code, notes, and snippets.

Embed
What would you like to do?
Pre-commit hook for eslint, linting *only* staged changes.
#!/bin/bash
for file in $(git diff --cached --name-only | grep -E '\.(js|jsx)$')
do
git show ":$file" | node_modules/.bin/eslint --stdin --stdin-filename "$file" # we only want to lint the staged changes, not any un-staged changes
if [ $? -ne 0 ]; then
echo "ESLint failed on staged file '$file'. Please check your code and try again. You can run ESLint manually via npm run eslint."
exit 1 # exit with failure status
fi
done
@gichuwil

This comment has been minimized.

gichuwil commented Sep 9, 2016

Thanks. Very helpful.

@Fer0x

This comment has been minimized.

Fer0x commented Jan 20, 2017

Option --diff-filter=d should be specified in git diff to exclude deleted files.

@alburritos

This comment has been minimized.

alburritos commented Jan 28, 2017

@Fer0x Where would that go?

@rashtay

This comment has been minimized.

rashtay commented Apr 24, 2017

@alberth8 It'd be like this -> git diff --diff-filter=d --cached --name-only

@gilesbutler

This comment has been minimized.

gilesbutler commented May 30, 2017

Thanks @dahjelle! Great stuff :)

@solo474

This comment has been minimized.

solo474 commented Aug 8, 2017

Thank you very much

@julianlam

This comment has been minimized.

julianlam commented Aug 23, 2017

eslint is quite slow when it runs against my entire project, this is much faster, thanks!!

@SalTor

This comment has been minimized.

SalTor commented Dec 19, 2017

Has anyone figured out a workflow for using the --fix flag during this pre-commit hook?

What I've come across is that when the pre-commit hook is triggered for files that are staged, the new changes aren't included in the commit.

It makes sense why it wouldn't be included: this is changing a staged file, and those changes would also have to be staged.

lint-staged has a partly-working fix for this, however, and as they note, this doesn't work for partially-staged files, AKA files whose changes have been cherry-picked for a commit.

@artem-litvinov

This comment has been minimized.

artem-litvinov commented Jan 30, 2018

@SalTor take a look at this. It works well for me.

@suyanhanx

This comment has been minimized.

suyanhanx commented Apr 20, 2018

Thank you very much.

@jancimajek

This comment has been minimized.

jancimajek commented Apr 24, 2018

One-liner version of the above:

git diff --diff-filter=d --cached --name-only | grep -E '\.(js|jsx)$' | xargs -I % sh -c 'git show ":%" | eslint --stdin --stdin-filename "%";'
@richistron

This comment has been minimized.

richistron commented Apr 24, 2018

you can do this in one line git diff --cached --name-only | grep ".js$" | xargs ./node_modules/.bin/eslint

@Brantron

This comment has been minimized.

Brantron commented Apr 25, 2018

nice, @richistron

@luuuis

This comment has been minimized.

luuuis commented May 11, 2018

@jancimajek's one-liner is great but does not handle spaces (and other funny chars) in the filename. Using git diff -z with xargs -0 handles that nicely: luuuis/pre-commit.sh.

The @richistron one liner will lint the changed files in the local checkout, which is not necessarily what is being committed to Git if you have not staged every hunk in a file.

@TNT-Likely

This comment has been minimized.

TNT-Likely commented Sep 29, 2018

thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment