mauvehed's dotfiles for personal and work environments
at main 259 lines 10 kB view raw view rendered
1# Git Usage and Best Practices 2 3This document outlines Git configuration, best practices for commit signing with GPG and 1Password, and useful Git commands relevant to this dotfiles setup. 4 5## Table of Contents 6 7- [Git Usage and Best Practices](#git-usage-and-best-practices) 8 - [Table of Contents](#table-of-contents) 9 - [Core Git Configuration](#core-git-configuration) 10 - [Commit Signing with GPG and 1Password](#commit-signing-with-gpg-and-1password) 11 - [1. Generating or Importing Your GPG Key](#1-generating-or-importing-your-gpg-key) 12 - [2. Adding Your GPG Key ID to 1Password](#2-adding-your-gpg-key-id-to-1password) 13 - [3. Configuring Git to Use the GPG Key (via `chezmoi` and 1Password)](#3-configuring-git-to-use-the-gpg-key-via-chezmoi-and-1password) 14 - [4. Adding GPG Public Key to GitHub](#4-adding-gpg-public-key-to-github) 15 - [5. GPG Agent Configuration](#5-gpg-agent-configuration) 16 - [6. Troubleshooting GPG Signing](#6-troubleshooting-gpg-signing) 17 - [GitHub CLI Authentication (`gh auth login`)](#github-cli-authentication-gh-auth-login) 18 - [Common Git Workflows and Useful Commands](#common-git-workflows-and-useful-commands) 19 - [Basic Workflow](#basic-workflow) 20 - [Branching](#branching) 21 - [Stashing Changes](#stashing-changes) 22 - [Viewing History](#viewing-history) 23 - [Squashing Commits](#squashing-commits) 24 - [Tags](#tags) 25 - [Resources](#resources) 26 27## Core Git Configuration 28 29Key Git settings are managed by `chezmoi` via the `dot_gitconfig.tmpl` template file, which generates `~/.gitconfig`. 30This configuration generally promotes trunk-based development and a linear Git history. 31 32Common global settings include: 33 34```ini 35# Example from dot_gitconfig.tmpl (values are templated) 36[user] 37 name = {{ .name | quote }} 38 email = {{ .email | quote }} 39 signingkey = {{ (onepasswordRead "op://Personal/Git GPG Key/key_id").stdout | trim | quote }} # Fetched from 1Password 40[commit] 41 gpgsign = true # Sign all commits by default 42[pull] 43 rebase = true # Prefer rebase over merge on pull 44[rebase] 45 autoStash = true # Automatically stash changes before rebase 46[push] 47 default = current # Push the current branch to a branch of the same name 48 followTags = true # Push tags that point to commits being pushed 49[branch] 50 autosetupmerge = false # Do not automatically set up merge configurations 51 autosetuprebase = always # Always rebase when pulling on new branches 52[core] 53 autocrlf = input # Handle line endings correctly 54 # ... other settings ... 55[remote "origin"] 56 prune = true # Remove remote-tracking branches that no longer exist on the remote 57``` 58 59* The specific template is located at: `{{ .chezmoi.sourceDir }}/dot_gitconfig.tmpl`. 60* Refer to the [Git Reference documentation](https://git-scm.com/docs) for details on these settings. 61 62## Commit Signing with GPG and 1Password 63 64Signing Git commits cryptographically verifies the committer's identity. This setup uses GPG for signing, with the GPG key ID managed via 1Password. 65 66### 1. Generating or Importing Your GPG Key 67 68If you don't have a GPG key, generate one: 69 70```sh 71gpg --full-gen-key 72``` 73Follow the prompts. An `ECDSA` key with `nistp256` curve is a good modern choice. Ensure you use a strong passphrase and store it securely (e.g., in 1Password). 74 75If you have an existing GPG key, ensure it's in your GPG keyring. 76 77### 2. Adding Your GPG Key ID to 1Password 78 79Once you have a GPG key, get its Key ID: 80 81```sh 82gpg --list-secret-keys --keyid-format LONG "Your Name" # Or your email 83``` 84Output will look like: 85``` 86sec nistp256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX YYYY-MM-DD [SCA] 87 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 88uid [ultimate] Your Name <your.email@example.com> 89ssb nistp256/YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY YYYY-MM-DD [E] 90``` 91The long Key ID is `XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` (the 40-character string). 92 93Store this Key ID in 1Password. For example, create a "Secure Note" or "Login" item named "Git GPG Key" and add a field/label (e.g., `key_id`) with your GPG Key ID as the value. 94 95See `docs/1password-usage.md` for more on storing items in 1Password. 96 97### 3. Configuring Git to Use the GPG Key (via `chezmoi` and 1Password) 98 99As shown in the "Core Git Configuration" section, `dot_gitconfig.tmpl` is set up to fetch the `user.signingkey` from 1Password: 100 101```ini 102[user] 103 signingkey = {{ (onepasswordRead "op://Personal/Git GPG Key/key_id").stdout | trim | quote }} 104``` 105Ensure the 1Password item path (`op://Personal/Git GPG Key/key_id`) in your `dot_gitconfig.tmpl` matches where you stored the key ID in 1Password. 106`chezmoi apply` will populate your `~/.gitconfig` with this signing key. 107 108### 4. Adding GPG Public Key to GitHub 109 110To have GitHub show your commits as "Verified": 111 1121. Export your GPG public key: 113 ```sh 114 gpg --armor --export XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Use your Key ID 115 ``` 1162. Copy the entire output (starting with `-----BEGIN PGP PUBLIC KEY BLOCK-----`). 1173. Go to [GitHub GPG keys settings](https://github.com/settings/keys) and add the new GPG key. 118 119### 5. GPG Agent Configuration 120 121To avoid entering your GPG passphrase for every commit, configure the `gpg-agent` to cache it. `chezmoi` manages `~/.gnupg/gpg-agent.conf`: 122 123``` 124# Example content for gpg-agent.conf.tmpl 125# Managed by chezmoi 126 127pinentry-program {{ .pinentryProgram | quote }} # Path to pinentry, templated by chezmoi 128default-cache-ttl 10800 # Cache passphrase for 3 hours 129max-cache-ttl 10800 # Max cache time 130``` 131`chezmoi` templates can determine the correct `pinentry-program` path based on your OS. 132After changes, you might need to restart the agent: `gpgconf --kill gpg-agent`. 133 134### 6. Troubleshooting GPG Signing 135 136* **Error: `gpg failed to sign the data` or `Inappropriate ioctl for device`**: 137 Ensure `export GPG_TTY=$(tty)` is in your shell configuration (e.g., `~/.exports` or `~/.zshrc`, managed by `chezmoi`). This allows GPG to prompt for a passphrase in the current terminal. 138 ```sh 139 # Ensure this line is in a chezmoi-managed shell startup file: 140 # export GPG_TTY=$(tty) 141 ``` 142 Restart your shell or source the updated file. 143* **No Pinentry Program Found**: Ensure `pinentry` is installed (e.g., `brew install pinentry-mac` on macOS) and `gpg-agent.conf` points to the correct program. 144* **Secret Key Not Available**: Verify the key ID in `~/.gitconfig` matches a private key in your `gpg --list-secret-keys` output. 145 146## GitHub CLI Authentication (`gh auth login`) 147 148While Git uses SSH or HTTPS (often with a credential helper) for repository access, the GitHub CLI (`gh`) requires its own authentication. 149 150```sh 151gh auth login 152``` 153Follow the prompts. Authenticating with a web browser (HTTPS) is often simplest. 154Refer to `docs/github-usage.md` for more on using `gh`. 155 156## Common Git Workflows and Useful Commands 157 158### Basic Workflow 159 160```sh 161git pull # Fetch and integrate changes from remote 162git add . # Stage all changes in the current directory 163# Or git add <file1> <file2> ... to stage specific files 164git commit -S -m "Your descriptive commit message" # Create a signed commit 165git push # Push changes to the remote repository 166``` 167 168### Branching 169 170* Create a new branch and switch to it: 171 ```sh 172 git checkout -b new-feature-branch 173 ``` 174* Switch to an existing branch: 175 ```sh 176 git checkout main 177 ``` 178* Delete a local branch (after merging): 179 ```sh 180 git branch -d feature-branch # Safe delete (only if merged) 181 git branch -D feature-branch # Force delete 182 ``` 183* Push a new local branch to remote and set up tracking: 184 ```sh 185 git push -u origin new-feature-branch 186 ``` 187 188### Stashing Changes 189 190Temporarily save uncommitted changes: 191 192```sh 193git stash push -m "WIP: some changes for later" 194git stash list 195git stash apply stash@{0} # Apply a specific stash 196git stash pop # Apply the latest stash and remove it from the list 197git stash drop stash@{0} # Remove a specific stash 198``` 199 200### Viewing History 201 202* Compact log view: 203 ```sh 204 git log --oneline --graph --decorate --all 205 ``` 206 (Consider creating a Git alias like `git la` for this.) 207* View changes for a specific commit: 208 ```sh 209 git show <commit_hash> 210 ``` 211* View changes for a specific file: 212 ```sh 213 git log -p -- <file_path> 214 ``` 215 216### Squashing Commits 217 218Combine multiple commits into a single one, often done before merging a feature branch. 219 220* Interactively rebase onto `main` (or your target branch), squashing commits from your current feature branch: 221 ```sh 222 # Assuming you are on your feature branch that branched off main 223 git rebase -i main 224 ``` 225 In the interactive editor, change `pick` to `s` (squash) or `f` (fixup) for commits you want to merge into the preceding one. Edit commit messages as needed. 226* Force push (with lease) if you've rewritten history on a shared branch (use with caution): 227 ```sh 228 git push --force-with-lease 229 ``` 230 231Alternatively, the example from the previous version for squashing all commits on a branch into one based on `main`: 232```sh 233# git checkout your-feature-branch 234# git reset $(git merge-base main $(git branch --show-current)) 235# git add . 236# git commit -S -m "New single commit message for the feature" 237# git push --force-with-lease origin your-feature-branch 238``` 239 240### Tags 241 242Create lightweight or annotated tags for releases: 243 244```sh 245git tag v1.0.0 # Lightweight tag 246git tag -a v1.0.1 -m "Version 1.0.1 release" # Annotated tag (signed if gpgsign=true) 247git push origin v1.0.1 # Push a specific tag 248git push --tags # Push all tags 249``` 250 251## Resources 252 253* **Pro Git Book**: [https://git-scm.com/book/en/v2](https://git-scm.com/book/en/v2) (Excellent, comprehensive guide) 254* **Git Reference Documentation**: [https://git-scm.com/docs](https://git-scm.com/docs) 255* **GitHub GPG Signing Documentation**: [https://docs.github.com/en/authentication/managing-commit-signature-verification](https://docs.github.com/en/authentication/managing-commit-signature-verification) 256* **1Password Documentation**: See `docs/1password-usage.md` 257* **GitHub CLI Documentation**: See `docs/github-usage.md` 258 259This guide covers key Git practices for this dotfiles setup. Consistent use of signed commits and a clean history are encouraged.