These days I have a problem of pushing package-lock.json
unintentionally.
Ex)
I run npm install
in my feature branch and my package-lock.json
is updated.
I made a commit and my feature branch is merged into develop branch. Package-lock.json
in develop branch is overwritten by package-lock.json
in my feature branch.
Due to updated packages in package-lock.json
, it broke the application.
I know that I have to be careful not to push package-lock.json
unless package.json
has changed, however, sometime I forget.
So I'm thinking if I can add some rule in pre-commit to show some warning if I commit package-lock.json
only. Is there any way to accomplish it?
thank you
If you are already using Git Hooks like "pre-commit", you can basically add one more script to the "pre-commit" list and write a script that does what you need (code below).
Using a combination of git/grep commands you can check that in the list of staged files, "package.json" and "package-lock.json" are both there (or none of them is).
The script can be:
#!/bin/sh
if [ `git diff --name-only --cached | egrep -c 'package.json|package.lock.json'` == "0" -o `git diff --name-only --cached | egrep -c 'package.json|package.lock.json'` == "2" ]; then
echo "Checked successfully."
elif [ `git diff --name-only --cached | egrep -c 'package.json'` == "1" -a `git diff --name-only --cached | egrep -c 'package.lock.json'` == "0" ]; then
echo "Warning: you are committing package.json without package.lock.json"
else
echo "Error: make sure you commit BOTH package.json and package.lock.json"
exit 1
fi
exit 0
git diff --name-only --cached
gets the list of staged files (file names only)
|
use the result of previous command as argument for the next
egrep
to perform a search (in this case search for strings 'package.json' and 'package.lock.json')
-c
counts the number of matches
Wrapping the whole command in backticks will execute it and provide the result to the main script.
The result of the git+egrep command returns the number of occurrences found. You then check what this result is, to tell the script to continue (exit 0
) or quit (exit 1
).
Make the script file executable, and add the reference to it in your package.json:
"scripts": {
"check-package": "./bin/check-package.sh",
}
...
"pre-commit": [
"check-package"
]
That should be it!
When you are done, just make sure you first commit the script only, and then package.json (otherwise it would already look for the script, without finding it).
Final note: This approach is valid to check any 2 or more files that need to be there at the same time in the list of files staged for commit.