{ lib, pkgs, config, ... }: with lib; let cfg = config.programs.git.custom; in { options.programs.git.custom = { profiles = mkOption { type = types.attrsOf (types.submodule ({ name, config, ... }: { options = { name = mkOption { type = types.str; }; email = mkOption { type = types.str; }; signingKey = mkOption { type = types.str; }; dirs = mkOption { type = types.listOf types.str; }; }; })); }; defaultProfile = mkOption { type = types.str; }; }; config = let profiles = cfg.profiles; in { programs.git = { enable = true; userName = profiles."${cfg.defaultProfile}".name; userEmail = profiles."${cfg.defaultProfile}".email; ignores = [".direnv"]; signing = { key = profiles."${cfg.defaultProfile}".signingKey; signByDefault = true; }; extraConfig = { init = { defaultBranch = "main"; }; pull = { rebase = true; }; rebase = { autoStash = true; autoSquash = true; abbreviateCommands = true; missingCommitsCheck = "warn"; }; }; aliases = { mr = "!sh -c 'git fetch $1 merge-requests/$2/head:mr-$1-$2 && git checkout mr-$1-$2' -"; pr = "!sh -c 'git fetch $1 refs/pull/$2/head:pr/$1 && git checkout pr/$2'"; }; includes = flatten (mapAttrsToList (name: profile: map (dir: { condition = "gitdir:${dir}"; contents = { user = { name = profile.name; email = profile.email; signingKey = profile.signingKey; }; }; }) profile.dirs) profiles); }; }; }