I organize my home folder something like this:
/home/varl ├── dev │ ├── work │ └── personal └── .gitconfig
In the main Git configuration file ~/.gitconfig
I set my defaults:
# ~/.gitconfig [pull] rebase = true [branch] autosetuprebase = always [commit] gpgSign = true [core] editor = vim [user] name = Viktor Varland email = varl@personal.com signingkey = PERSONAL_KEY_TO_SIGN_WITH
These settings are used everywhere, which is the normal way to do
things. However I would like to change user.email
and
user.signingkey
when I am working on different projects (e.g. work
account and key for work, and personal account and key for, well,
personal projects).
For each context under ~/dev
I add another .gitconfig
file:
/home/varl ├── dev │ ├── work │ │ └── .gitconfig │ └── personal │ └── .gitconfig └── .gitconfig
Back in the main ~/.gitconfig
, add the includeIF
directive to
conditionally include[1] configuration for different contexts:
# ~/.gitconfig # ... trunc ... [includeIF "gitdir:~/dev/work/"] path = ~/dev/work/.gitconfig [includeIF "gitdir:~/dev/personal/"] path = ~/dev/personal/.gitconfig
This makes Git load additional configuration if I am using Git within
e.g. ~/dev/work
.
In ~/dev/work/.gitconfig
I can override or set new options valid for the
repos within ~/dev/work
:
# ~/dev/work/.gitconfig [user] name = Viktor Varland email = viktor.varland@work.com signingKey = WORK_KEY_TO_SIGN_WITH
Note that I can use a different git user when working in repos below ~/dev/work than I use for my personal stuff.
Now, create the folder ~/dev/work/.hooks
. We are going to use this to
define hooks that apply for all the projects under ~/dev/work
.
/home/varl ├── dev │ ├── work │ │ ├── .hooks │ │ └── .gitconfig │ └── personal │ └── .gitconfig └── .gitconfig
# ~/dev/work/.gitconfig [core] hooksPath = ~/dev/work/.hooks # ... trunc ...
This makes it so that we can use global git hooks for all repos that belong to the same context, in this example, work.
For example, the ~/dev/work/.hooks/pre-commit
hook looks like this:
#!/bin/bash if [[ -f "$PWD/package.json" ]]; then npm run --if-present lint fi
So each time we try to commit in a repo that has a main package.json
file, it
attempts to run the lint
script.
We could add similar conditional statements for Rust, Go, Java, as well, and have a hook that does (mostly) the right thing based on the project.
The pre-commit script can be customized to run validation tools per repo, or made general like above.
Hooks can also be skipped anytime with the --no-verify
flag[2].
On pre-push we can do something similar, but for tests.
[1] https://git-scm.com/docs/git-config#_includes [2] https://git-scm.com/book/fa/v2/Customizing-Git-Git-Hooks