# Git module # # This module configures Git with Home Manager's programs.git options. # It supports both personal and work profiles with different signing keys # and includeIf paths for project-specific configurations. # # Based on the chezmoi configuration from dot_gitconfig.tmpl { config, pkgs, lib, ... }: with lib; let cfg = config.modules.git; in { options.modules.git = { enable = mkEnableOption "Git configuration"; userName = mkOption { type = types.str; default = "Morten Olsen"; description = "Git user name"; }; userEmail = mkOption { type = types.str; description = "Git user email address"; example = "alice@personal.example.com"; }; signingKey = mkOption { type = types.str; description = "SSH signing key (public key content)"; example = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..."; }; includes = mkOption { type = types.listOf (types.submodule { options = { condition = mkOption { type = types.str; description = "The includeIf condition (e.g., gitdir:~/Projects/)"; example = "gitdir:~/Projects/"; }; path = mkOption { type = types.str; description = "Path to the included gitconfig file"; example = "~/Projects/.gitconfig"; }; }; }); default = []; description = "List of conditional includes for project-specific git configurations"; }; }; config = mkIf cfg.enable { # Global gitignore file home.file.".gitignore_global".text = '' .envrc *._local.* .DS_Store *.tsbuildinfo .env ''; # Delta pager for better diffs (separate program in newer Home Manager) programs.delta = { enable = true; enableGitIntegration = true; options = { navigate = true; light = false; side-by-side = true; line-numbers = true; }; }; programs.git = { enable = true; # Signing configuration with 1Password signing = { key = cfg.signingKey; signByDefault = true; }; # Conditional includes for project-specific configurations includes = map (inc: { condition = inc.condition; path = inc.path; }) cfg.includes; # All git settings using the new unified settings option settings = { # User configuration user = { name = cfg.userName; email = cfg.userEmail; }; # Core settings (pager is set by programs.delta) core = { hooksPath = "/dev/null"; excludesfile = "~/.gitignore_global"; }; # Pull settings pull = { ff = "only"; }; # Init settings init = { defaultBranch = "main"; }; # Push settings push = { autoSetupRemote = true; }; # GPG/SSH signing settings gpg = { format = "ssh"; }; "gpg \"ssh\"" = { program = "/Applications/1Password.app/Contents/MacOS/op-ssh-sign"; }; # Commit settings (gpgsign is handled by signing.signByDefault) commit = { gpgsign = true; }; # URL rewrites "url \"https://\"" = { insteadOf = "git://"; }; # Git LFS filter.lfs = { clean = "git-lfs clean -- %f"; smudge = "git-lfs smudge -- %f"; process = "git-lfs filter-process"; required = true; }; # Difftool configuration "difftool \"nvimdiff\"" = { cmd = "nvim -d \"$LOCAL\" \"$REMOTE\""; }; # Aliases alias = { graph = "log --graph --color --pretty=format:\"%C(yellow)%H%C(green)%d%C(reset)%n%x20%cd%n%x20%cn%C(blue)%x20(%ce)%x20%C(cyan)[gpg:%GK%x20%G?]%C(reset)%n%x20%s%n\""; ll = "log --oneline"; st = "status -sb"; cm = "commit -m"; append = "commit --amend --no-edit"; sobmodules = "submodule update --init --recursive"; df = "difftool -t nvimdiff -y"; last = "log -1 --stat"; br = "branch --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]' --sort=-committerdate"; brr = "branch --remote --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]' --sort=-committerdate"; undo = "reset HEAD~1 --mixed"; unstage = "reset HEAD --"; }; }; }; }; }