Skip to content

Latest commit

 

History

History
312 lines (236 loc) · 10.5 KB

File metadata and controls

312 lines (236 loc) · 10.5 KB

Git Usage

This guide explains how to configure Git for trunk-based development, enable signed commits, and use safe day-to-day workflows.

Table of contents

Scope

This guide covers baseline Git configuration, commit signing, and practical workflows used by this repository.

How to use this guide

  1. Start with Before you begin to prepare your identity and signing details.
  2. Apply Configuration, then validate it.
  3. Complete Signing commits and Additional settings as needed.

Before you begin

Use your real identity and verified email for Git metadata and signing.

  • Replace Your Name with your full name.
  • Replace youremail@domain / your.name@email with your verified email address.
  • Replace pleaseChooseYourKeyPassphrase with a strong passphrase and store it in your password manager.

Configuration

The commands below configure your Git command-line client globally.

This configuration supports trunk-based development and linear history.

Apply global configuration

git config user.name "Your Name" # Use your full name here
git config user.email "youremail@domain" # Use your email address here
git config branch.autosetupmerge false
git config branch.autosetuprebase always
git config commit.gpgsign true
git config core.autocrlf input
git config core.filemode true
git config core.hidedotfiles false
git config core.ignorecase false
git config credential.helper cache
git config pull.rebase true
git config push.default current
git config push.followTags true
git config rebase.autoStash true
git config remote.origin.prune true

This is already set in dot_gitconfig.tmpl, used as a template to create ~/.gitconfig.

What each setting does

Setting Why it is used
user.name Sets the commit author name.
user.email Sets the commit author email (should match your verified GitHub email).
branch.autosetupmerge=false Avoids automatic merge tracking defaults.
branch.autosetuprebase=always Prefers rebase workflows for cleaner linear history.
commit.gpgsign=true Signs commits by default for authenticity.
core.autocrlf=input Normalises line endings on commit to avoid cross-platform diffs.
core.filemode=true Tracks executable-bit permission changes when relevant.
core.hidedotfiles=false Avoids hidden dotfile behaviour on systems that support it.
core.ignorecase=false Keeps case-sensitive path behaviour for consistency.
credential.helper=cache Caches credentials to reduce repeated prompts.
pull.rebase=true Rebases when pulling to maintain a linear commit history.
push.default=current Pushes the current branch by default.
push.followTags=true Pushes annotated tags related to pushed commits.
rebase.autoStash=true Temporarily stashes local changes during rebase.
remote.origin.prune=true Removes stale remote-tracking references on fetch/pull.

Verify configuration

git config --list --show-origin

More information on Git settings is available in the Git Reference documentation.

Signing commits

Signing commits helps establish trust and verify commit authorship.

Generate a new GPG key pair

If you do not have a key pair yet, generate one.

USER_NAME="Your Name"
USER_EMAIL="your.name@email"
file=$(echo "$USER_EMAIL" | sed "s/[^[:alpha:]]/-/g")

mkdir -p "$HOME/.gnupg"
chmod 0700 "$HOME/.gnupg"
cd "$HOME/.gnupg"
cat > "$file.gpg-key.script" <<EOF
  %echo Generating a GPG key
  Key-Type: ECDSA
  Key-Curve: nistp256
  Subkey-Type: ECDH
  Subkey-Curve: nistp256
  Name-Real: $USER_NAME
  Name-Email: $USER_EMAIL
  Expire-Date: 0
  Passphrase: pleaseChooseYourKeyPassphrase
  %commit
  %echo done
EOF
gpg --batch --generate-key "$file.gpg-key.script"
rm "$file.gpg-key.script"
# or do it manually by running `gpg --full-gen-key`

Find your key ID

Make note of the ID and store your key material safely.

gpg --list-secret-keys --keyid-format LONG "$USER_EMAIL"

You should see output similar to:

sec   nistp256/AAAAAAAAAAAAAAAA 2023-01-01 [SCA]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid                 [ultimate] Your Name <your.name@email>
ssb   nistp256/BBBBBBBBBBBBBBBB 2023-01-01 [E]

Export your keys (backup)

ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
gpg --armor --export "$ID" > "$file.gpg-key.pub"
gpg --armor --export-secret-keys "$ID" > "$file.gpg-key"

Keep *.gpg-key private and never commit it to a repository.

Import an existing private key

gpg --import "$file.gpg-key"

Remove keys from your local GPG keyring

Use this only if keys are no longer needed on the machine.

gpg --delete-secret-keys "$ID"
gpg --delete-keys "$ID"

Configure Git to use your signing key

git config user.signingkey "$ID"

Optional validation:

git config --get user.signingkey
git config --get commit.gpgsign

Upload your public key to GitHub

Upload the public key in GitHub GPG keys settings.

After uploading, verify your email is recognised as verified on commits pushed to remote.

cat "$file.gpg-key.pub"

After a signed commit, you can inspect signature status with:

git log --show-signature -1

Troubleshooting

If you get error: gpg failed to sign the data, ensure export GPG_TTY=$TTY is defined in ~/.zshrc or a sourced file (for example ~/.exports), then restart your terminal.

Portable (macOS/Linux) approach:

grep -v '^export GPG_TTY=' ~/.exports > ~/.exports.tmp || true
mv ~/.exports.tmp ~/.exports
echo "export GPG_TTY=\$TTY" >> ~/.exports

Original command form:

sed -i '/^export GPG_TTY/d' ~/.exports
echo "export GPG_TTY=\$TTY" >> ~/.exports

Additional settings

Cache GPG passphrase for 3 hours

Configure commit signature passphrase caching for 3 hours (10800 seconds):

source ~/.zshrc
mkdir -p ~/.gnupg
sed -i '/^pinentry-program/d' ~/.gnupg/gpg-agent.conf 2>/dev/null ||:
echo "pinentry-program $(whereis -q pinentry)" >> ~/.gnupg/gpg-agent.conf
sed -i '/^default-cache-ttl/d' ~/.gnupg/gpg-agent.conf
echo "default-cache-ttl 10800" >> ~/.gnupg/gpg-agent.conf
sed -i '/^max-cache-ttl/d' ~/.gnupg/gpg-agent.conf
echo "max-cache-ttl 10800" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

Portable (macOS/Linux) alternative for file editing:

grep -v '^pinentry-program ' ~/.gnupg/gpg-agent.conf > ~/.gnupg/gpg-agent.conf.tmp 2>/dev/null || true
mv ~/.gnupg/gpg-agent.conf.tmp ~/.gnupg/gpg-agent.conf 2>/dev/null || true
echo "pinentry-program $(whereis -q pinentry)" >> ~/.gnupg/gpg-agent.conf

grep -v '^default-cache-ttl ' ~/.gnupg/gpg-agent.conf > ~/.gnupg/gpg-agent.conf.tmp || true
mv ~/.gnupg/gpg-agent.conf.tmp ~/.gnupg/gpg-agent.conf
echo "default-cache-ttl 10800" >> ~/.gnupg/gpg-agent.conf

grep -v '^max-cache-ttl ' ~/.gnupg/gpg-agent.conf > ~/.gnupg/gpg-agent.conf.tmp || true
mv ~/.gnupg/gpg-agent.conf.tmp ~/.gnupg/gpg-agent.conf
echo "max-cache-ttl 10800" >> ~/.gnupg/gpg-agent.conf

gpgconf --kill gpg-agent

Please see assets/30-install-developer-tools.macos.sh, as this section is part of automated configuration.

Authenticate GitHub CLI

Authenticate to GitHub and set up your authorisation token:

$ gh auth login
? What account do you want to log into? GitHub.com
? What is your preferred protocol for Git operations? HTTPS
? Authenticate Git with your GitHub credentials? No
? How would you like to authenticate GitHub CLI? Paste an authentication token
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens
The minimum required scopes are 'repo', 'read:org'.
? Paste your authentication token: github_pat_**********************************************************************************
- gh config set -h github.com git_protocol https
✓ Configured git protocol
✓ Logged in as your-github-handle

Useful commands

Create and push a signed commit

git add .
git commit -S -m "Create a signed commit"
git pull
git push

Squash branch commits into one

git checkout your-branch-name
git reset $(git merge-base main $(git branch --show-current))
git add .
git commit -S -m "Create just one commit instead"
git push --force-with-lease

References