# Version control: git + delta + commitizen + lazygit. Committer identity comes # from the per-user `identity` arg (the registry). See README "Users". { pkgs, lib, identity, ... }: let ctp = import ../lib/catppuccin-mocha.nix; in { home.packages = [ pkgs.commitizen ]; programs.git = { enable = true; package = pkgs.gitFull; settings = { user.name = identity.fullName; # mkDefault so a host-specific module can still override it. user.email = lib.mkDefault identity.email; 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; }; fetch.prune = true; # drop deleted remote-tracking branches # Keep the commit-graph current (fast `git log --graph`, used by `lg`). fetch.writeCommitGraph = true; gc.writeCommitGraph = true; merge.conflictStyle = "zdiff3"; # show the common ancestor in conflicts diff = { algorithm = "histogram"; colorMoved = "default"; }; rerere.enabled = true; # remember + replay conflict resolutions # delta pager config (programs.delta is enabled below, with git # integration; these keys land under [delta] in the git config). # syntax-theme reuses the Catppuccin Mocha tmTheme vendored for bat in # shell.nix -- delta reads bat's theme directory. delta = { syntax-theme = "Catppuccin Mocha"; navigate = true; # n/N to jump between diff hunks line-numbers = true; side-by-side = true; }; 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 --"; amend = "commit --amend --no-edit"; # tack staged changes onto HEAD fixup = "commit --fixup"; # `git fixup ` -> autosquash on next rebase undo = "reset --soft HEAD~1"; # undo last commit, keep the changes staged 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"; # commitizen (Conventional Commits, its default ruleset): `git cz c` -> # `cz commit`, `git cz bump`, etc. `git cc` is a shortcut for the prompt. cz = "!cz"; cc = "!cz commit"; # Structural (syntax-aware) diff, on demand. Set per-invocation via the # environment rather than `diff.external`, which would also change what # `git show` and `git log -p --ext-diff` emit for every caller. # Takes the same arguments as `git diff`: `git dft HEAD~3 -- file`. dft = "!GIT_EXTERNAL_DIFF=difft git diff"; }; # SSH signing, key from the registry. mkDefault so a host lacking the key # in its agent can set gpgsign = false instead of failing every commit. gpg.format = "ssh"; user.signingkey = lib.mkDefault identity.signingKey; 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 = { enable = true; enableGitIntegration = true; }; # difftastic backs the `dft` alias above. git.enable stays off on purpose: # the module's git integration sets `diff.external`, which would displace # delta as the diff renderer everywhere instead of only where asked. programs.difftastic = { enable = true; git.enable = false; }; # lazygit: TUI for staging/rebasing, themed to Catppuccin Mocha to match. programs.lazygit = { enable = true; settings.gui.theme = { activeBorderColor = [ "#${ctp.blue}" "bold" ]; inactiveBorderColor = [ "#${ctp.surface1}" ]; selectedLineBgColor = [ "#${ctp.surface0}" ]; }; }; }