Closed Cyberbeni closed 4 years ago
I can confirm this exact problem as happening for me after I noticed super bad behavior (as described above) when using the hook as provided by the repo. This needs to be surfaced up and fixed immediately as it could be causing major (silent) damage to peoples commits!
@Cyberbeni How would you fix my config:
#!/bin/bash
SWIFTFORMAT_FILEPATH=".swiftformat"
git diff --diff-filter=d --staged --name-only | grep -e '\(.*\).swift$' | while read line; do
swiftformat --config $SWIFTFORMAT_FILEPATH $line "${line}";
git add "$line";
done
I went and changed it to:
#!/bin/sh
#pre-commit git hook
SWIFTFORMAT_FILEPATH=".swiftformat"
CHANGED_FILES="$(git diff-index --no-commit-id --name-only --cached -r HEAD)"
git stash --keep-index
swiftformat --config $SWIFTFORMAT_FILEPATH $CHANGED_FILES
git add $CHANGED_FILES
git stash pop
Hope I wont have any issues š
@donileo if you find a solution please open a PR.
Hi @nicklockwood, first wanted to say thanks for such a great binary! As far as fixes so far the changes I listed above are working and is definitely better than what is currently in master here but I want to do some further testing before a PR.
@donileo any update on this?
@nicklockwood A little after using the above solution I continued having issues, which made made me pull back on using that solution. Iāve just settled on manually running swift format via a simple script that runs it on all swift files, the script isnāt anything special.
I didnāt pursue finding a good commit hook, just havenāt had too much free time as of late.
@donileo ok, thanks.
Totally forgot about this.
@donileo try this:
#!/bin/sh
#pre-commit git hook
CONFIG_PATH=".swiftformat"
CHANGED_FILES="$(git diff-index --no-commit-id --name-only --cached -r HEAD | grep -e '\(.*\).swift$')"
if [ "$CHANGED_FILES" == "" ]; then
exit 0
fi
git diff --diff-filter=d --staged --name-only | grep -e '\(.*\).swift$' | while read line; do
/usr/local/bin/swiftformat --config $CONFIG_PATH "$line";
done
git stash --keep-index
git diff --diff-filter=d --staged --name-only | grep -e '\(.*\).swift$' | while read line; do
/usr/local/bin/swiftformat --config $CONFIG_PATH "$line";
git add "$line";
done
git stash pop
This way you will have the formatted version of all changes in local and formatted version of staged changes in origin
I had some time to test the hook and fixed my previous comment. Now I just need to find the correct way to force stash pop
@Cyberbeni, did you end up finalising your script? As you mentioned, the stash pop
would cause a conflict.
@raphaeloliveira moved formatting to pre build phase as it's important to check if your code builds/runs correctly before commiting.
You could try this instead of git stash pop
: git stash show -p | git apply && git stash drop
Thanks for the answer @Cyberbeni. Unfortunately, that's what I'm trying to move away from. Currently, my build phases are too big and a simple rebuild without any code changes takes 5 seconds, which I'm trying to improve. Swiftformat takes 0.5~1 seconds, even when there are no changes. That's why I'm trying to move it to a pre-commit hook script that solves this unstaged files issue. I'm currently looking at this script https://github.com/hallettj/git-format-staged/blob/master/README.md.
For those still searching for a script, I believe I found one that works well - https://github.com/hallettj/git-format-staged / https://www.olioapps.com/blog/automatic-code-formatting/.
I added the script on my project and run it on the pre-commit hook
./scripts/git-format-staged.sh --formatter 'swiftformat --swiftversion 5.0 --config ".swiftformat" stdin' './*.swift'
The stdin
was the trick to make it work with git-format-staged
.
It now correctly formats only the staged code. āļø
Now I don't have my work laptop with me, so I couldn't try it out, but I'm 99.9% sure this is what happens.
Here is the git hook I used for sorting imports in objective C files, that solves this problem: https://github.com/Cyberbeni/GitHooks/blob/master/pre-commit
tl;dr:
git stash --keep-index
before formatting and adding changesgit stash pop
after formatting and adding changesNot sure if formatting can cause merge conflicts when popping the stash(sorting imports never did). In that case, I'd do a round of formatting without adding changes before stashing and then format again, add changes, pop stash.