From b806359fd60d3dbea8b29860e629a24139bb5f30 Mon Sep 17 00:00:00 2001 From: Emma Thorpe Date: Wed, 10 Jun 2026 11:08:49 +0100 Subject: [PATCH] feat(git): rebase pulls, better diffs/merges, aliases, ignores, signing settings: pull.rebase + rebase autostash/autosquash, fetch.prune, merge.conflictStyle=zdiff3, diff histogram + colorMoved, rerere, commit.verbose, branch.sort, column.ui, help.autocorrect, and a small alias set (st/co/sw/br/ci/last/unstage/lg). Global ignore file (result, .direnv, *.swp, .DS_Store). SSH commit/tag signing on personal hosts too, reusing the existing key (the work module already signs on the work host). gpgsign is mkDefault so a host lacking the key in its ssh-agent can disable it -- otherwise commits there would fail. No personal user.email is set (unknown); signing does not require one, but author email still falls back to user@host until set. Co-Authored-By: Claude Opus 4.8 (1M context) --- lyrathorpe/home/git.nix | 60 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/lyrathorpe/home/git.nix b/lyrathorpe/home/git.nix index 8aca636..7e557b9 100644 --- a/lyrathorpe/home/git.nix +++ b/lyrathorpe/home/git.nix @@ -1,6 +1,11 @@ # Version control: git + delta pager + commitizen. The work host layers # commit signing and an email override on top (see work/default.nix). -{ pkgs, fullName, ... }: +{ + pkgs, + lib, + fullName, + ... +}: { home.packages = [ pkgs.commitizen @@ -11,13 +16,58 @@ package = pkgs.gitFull; settings = { user.name = fullName; - push = { - autoSetupRemote = true; + push.autoSetupRemote = true; + init.defaultBranch = "main"; + + # Rebase-centric pulls (matches the "always a branch, linear history" + # workflow); stash/restore and reorder fixups automatically. + pull.rebase = true; + rebase = { + autoStash = true; + autoSquash = true; }; - init = { - defaultBranch = "main"; + + fetch.prune = true; # drop deleted remote-tracking branches + merge.conflictStyle = "zdiff3"; # show the common ancestor in conflicts + diff = { + algorithm = "histogram"; + colorMoved = "default"; }; + rerere.enabled = true; # remember + replay conflict resolutions + commit.verbose = true; # full diff in the commit-message editor + branch.sort = "-committerdate"; # most-recent branches first + column.ui = "auto"; + help.autocorrect = "prompt"; + + alias = { + st = "status"; + co = "checkout"; + sw = "switch"; + br = "branch"; + ci = "commit"; + last = "log -1 HEAD"; + unstage = "reset HEAD --"; + lg = "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' --all"; + }; + + # SSH commit signing on personal hosts too (the work module sets the same + # on the work host). mkDefault so a host without the key in its ssh-agent + # can override to false -- otherwise commits there would fail. Reuses the + # existing ssh key; a dedicated personal key can be swapped in later. + gpg.format = "ssh"; + user.signingkey = "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJMVgeRKnfX1G8coU3nAobI485aeUpGTMqH7+zbKI8o emma.thorpe@cloud.com"; + commit.gpgsign = lib.mkDefault true; + tag.gpgsign = lib.mkDefault true; }; + + # Global ignore file (~/.config/git/ignore). + ignores = [ + "result" + "result-*" + ".direnv" + "*.swp" + ".DS_Store" + ]; }; programs.delta = {