credit: publish only the names you chose¶
The problem¶
A commit's author, committer and trailers go public the moment it is pushed,
and mirrors and forks keep them. A repo that started private carries a work
email on every commit; a tool added a Co-authored-by: line you did not want.
Checking the whole repo blocks every push forever once old history is public
under another name. Checking @{u}..HEAD misses new branches and first pushes,
which publish everything.
The method¶
Git's pre-push hook gets one line per ref: local ref, local commit, remote ref, remote commit. What this push publishes is exactly:
Everything reachable from what you push that the remote does not have. A first push checks all history; a branch made from pushed work checks nothing.
Each commit is checked on its author, committer, and Co-authored-by: and
Signed-off-by: trailers; a pushed annotated tag on its tagger.
When it blocks, it offers a fix only when the fix is safe. The boundary of the unpushed set says where a rewrite may start:
One boundary commit: rebase from it, and only unpushed commits change. None: a
first push, rewrite from --root. Two or more (merged with pushed work): a
rebase would rewrite public commits, so it says to do it by hand.
Sample¶
git config --global --add credit.allow 'A N Author' # shell globs
git config --global --add credit.host '*github.com[:/]*' # optional
git config --global credit.name 'A N Author' # identity for the
git config --global credit.email [email protected] # rewrite line
printf '#!/bin/sh\nexec /path/to/credit "$@"\n' > .git/hooks/pre-push
chmod +x .git/hooks/pre-push # or drop it in a shared pre-push.d/ (githooks)
credit # what would pushing this branch publish?
CREDIT_SKIP=1 git push # once, anyway
Limits¶
- It compares with your remote-tracking refs, which can only be behind the server: it may check more, never less. Fetch first if it flags others' work.
- Raw names are checked, not
.mailmap, because raw names are published. - The trailer rewrite drops all
Co-authored-by:andSigned-off-by:lines. - Names inside messages or files are a different job (a pre-commit scanner).
Code¶
methods/credit/ in the methods repository: the script, a README and a
27-check test that pushes to real bare remotes through the hook, runs the
printed rewrite line, and proves already-pushed commits keep their ids.