Skip to content

Instantly share code, notes, and snippets.

@EtherZa
Created August 12, 2019 02:53
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save EtherZa/581d9276336353838b2c939f9554d479 to your computer and use it in GitHub Desktop.
Save EtherZa/581d9276336353838b2c939f9554d479 to your computer and use it in GitHub Desktop.
Format c# with dotnet-format with pre-commit hook
#!/bin/sh
#
# modified from sample: https://prettier.io/docs/en/precommit.html
#
# install dotnet-format: dotnet tool install -g dotnet-format
# copy to .git/hooks/pre-commit and make executable
#
FILES=$(git diff --cached --name-only --diff-filter=ACM "*.cs" | sed 's| |\\ |g')
[ -z "$FILES" ] && exit 0
# Format all selected files
echo "$FILES" | cat | xargs | sed -e 's/ /,/g' | xargs dotnet-format --files
# Add back the modified files to staging
echo "$FILES" | xargs git add
exit 0
@dazinator
Copy link

dazinator commented Mar 30, 2020

Thanks for this @EtherZa. I have tried this, but it doesn't seem to be working.
If I add some weird formatting to "Program.cs" - 2 extra spaces before "public class Program":

       public class Program
    {

Now, if I run dotnet-format in the project directory, it corrects this.

However if I don't run dotnet-format, and instead commit this file and rely on the pre-commit hook, it doesn't get corrected.

Any ideas why this might be the case?

@dkreider
Copy link

dkreider commented Aug 3, 2020

@dazinator you could try removing the --cached option.

In other words change this...

FILES=$(git diff --cached --name-only --diff-filter=ACM "*.cs" | sed 's| |\\ |g')

...to this.

FILES=$(git diff --name-only --diff-filter=ACM "*.cs" | sed 's| |\\ |g')

@simonauner
Copy link

I didn't get this script working but I used it as a base and modified it to my needs.

dotnet format has replaced --files with --include.

https://gist.github.com/simonauner/09d4e3241f26d2bd139261816e6c18f6

@redachl
Copy link

redachl commented Dec 25, 2020

Thanks @EtherZa!

Also, you could use the --staged tag to select staged files only (but of course, if one always stages all the edited files, then there's no difference).

git diff --staged --name-only --diff-filter=ACM "*.cs"

@EtherZa
Copy link
Author

EtherZa commented Apr 24, 2021

I have abandoned this implementation as it is prone to errors. It assumes that a staged file does not have an unstaged change. Formatting is completed in the unstaged file which is then staged and committed.

Please refer to https://www.olioapps.com/blog/automatic-code-formatting/ for a better implementation.

@ryanbuening
Copy link

@EtherZa are there instructions or a sample project on how to use that with dotnet format?

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