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) <noreply@anthropic.com>
This commit is contained in:
Emma Thorpe
2026-06-10 11:08:49 +01:00
parent 0c4f555dec
commit b806359fd6
+55 -5
View File
@@ -1,6 +1,11 @@
# Version control: git + delta pager + commitizen. The work host layers # Version control: git + delta pager + commitizen. The work host layers
# commit signing and an email override on top (see work/default.nix). # commit signing and an email override on top (see work/default.nix).
{ pkgs, fullName, ... }: {
pkgs,
lib,
fullName,
...
}:
{ {
home.packages = [ home.packages = [
pkgs.commitizen pkgs.commitizen
@@ -11,13 +16,58 @@
package = pkgs.gitFull; package = pkgs.gitFull;
settings = { settings = {
user.name = fullName; user.name = fullName;
push = { push.autoSetupRemote = true;
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 = { programs.delta = {