{ config, pkgs, lib, ... }: let cfg = config.programs.git; github-uri-prefixes = [ # Preferred "github:" # Alternative "https://github.com/" "ssh://git@github.com:" "git@github.com:" "github.com:" ]; in { imports = [ ./maintenance-timers.nix ]; # TODO: convert to template once nix-sops supports it in hm module sops.secrets."git/nordicsemi-config" = { }; programs.git = lib.mkMerge [ { enable = true; package = pkgs.gitFull; userName = "h7x4"; userEmail = "h7x4@nani.wtf"; signing = { key = "46B9228E814A2AAC"; signByDefault = true; }; lfs.enable = true; delta = { enable = true; options = { line-numbers = true; side-by-side = true; theme = "Monokai Extended Origin"; }; }; aliases = { aliases = "!git config --get-regexp alias | sed -re 's/alias\\.(\\S*)\\s(.*)$/\\1 = \\2/g'"; delete-merged = "!git branch --merged | grep -v '\\*' | xargs -n 1 git branch -d"; forcepush = "push --force-with-lease --force-if-includes"; authors = "shortlog --summary --numbered --email"; si = "switch-interactive"; ff = "fixup-fixup"; rf = "rebase-fixups"; pp = "post-pr"; subs = "submodule update --init --recursive"; rebase-author = "rebase -i -x \"git commit --amend --reset-author -CHEAD\""; git = "!git"; } // (let c = c: s: "%C(${c})${s}%C(reset)"; in { graph = let fmt = lib.concatStringsSep "" [ " - " (c "bold blue" "%h") " - " (c "bold green" "(%ar)") " " (c "white" "> %s") " " (c "dim white" "- %an") (c "bold yellow" "%d") ]; in "log --graph --abbrev-commit --decorate --format=format:'${fmt}' --all"; graphv = let fmt = lib.concatStringsSep "" [ (c "bold blue" "%h") " - " (c "bold cyan" "%aD") " " (c "bold green" "(%ar)") (c "bold yellow" "%d") "%n" " " (c "white" "%s") " " (c "dim white" "- %an") ]; in "log --graph --abbrev-commit --decorate --format=format:'${fmt}' --all"; l = let fmt = lib.concatStringsSep "%n" (map (x: if builtins.isList x then lib.concatStringsSep " " x else x) [ [ (c "bold yellow" "%H") (c "auto" "%d") ] [ (c "bold white" "Author:") (c "bold cyan" "%aN <%aE>") (c "bold green" "(%ah)") ] [ (c "bold white" "Committer:") (c "bold cyan" "%cN <%cE>") (c "bold green" "(%ah)") ] [ (c "bold white" "GPG: (%G?)") (c "bold magenta" "%GF") "-" (c "bold cyan" "%GS") (c "bold blue" "(%GT) ") ] "" (c "bold white" "# %s") "%+b" (c "dim yellow" "%+N") ]); # sedExpressions = let # colorExpr = "\\x1B\\[([0-9]{1,3}(;[0-9]{1,2};?)?)?[mGK]"; # colorEndExpr = "\\x1B\\[m"; # colored = x: "${colorExpr}${x}${colorEndExpr}"; # in lib.concatMapStringsSep " " (x: "-e '${x}'") [ # "s|${colored "GPG: \\(N\\)"} ${colored "F3CDA86CC55A9F10D7A069819F2F7D8250F35146"} - ${colored "h7x4 "} ${colored "\\(ultimate\\)"}|GPG: h7x4|" # "s|${colored "GPG: \\(N\\)"} ${colored ""} - ${colored ""} ${colored "\\(undefined\\)"}||" # ]; in "log --decorate --format=tformat:'${fmt}'"; # in "!git log --color=always --format=format:'${fmt}' | sed -E ${sedExpressions} | $PAGER"; }); extraConfig = { core = { whitespace = "space-before-tab,-indent-with-non-tab,trailing-space"; untrackedCache = true; editor = "nvim"; }; safe.directory = "*"; interactive.singleKey = true; advice.detachedHead = false; rerere.enabled = true; branch = { sort = "-committerdate"; autoSetupRebase = "always"; }; "color \"branch\"".upstream = "cyan"; color.ui = "auto"; init.defaultBranch = "main"; fetch = { prune = true; fsckObjects = true; }; maintenance.strategy = "incremental"; scalar = { repo = [ "${config.home.homeDirectory}/nixpkgs" ]; }; transfer.fsckObjects = true; receive.fsckObjects = true; pull.rebase = true; rebase = { autoStash = true; autoSquash = true; abbreviateCommands = true; updateRefs = true; }; push = { default = "current"; autoSetupRemote = true; followTags = true; }; merge = { tool = "nvimdiff"; conflictstyle = "diff3"; colorMoved = "zebra"; }; mergetool.keepBackup = false; "mergetool \"nvimdiff\"".cmd = "nvim -d $BASE $LOCAL $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J'"; diff = { mnemonicPrefix = true; renames = true; tool = "nvimdiff"; submodule = "log"; }; pager.show = lib.getExe pkgs.bat; status = { showUntrackedFiles = "all"; relativePaths = true; submoduleSummary = true; }; log.date = "iso"; submodule.recurse = true; grep = { break = true; heading= true; lineNumber = true; extendedRegexp = true; }; "notes \"rewrite\"" = { amend = true; rebase = true; }; versionsort = { prereleaseSuffix = lib.mapCartesianProduct ({ binding, suffix }: "${binding}${suffix}") { binding = [ "-" "." "/" ]; suffix = [ "pre" "alpha" "beta" "rc" ]; }; }; # Run autocorrected command after 3 seconds help.autocorrect = "30"; github.user = "h7x4"; "url \"${lib.head github-uri-prefixes}\"".insteadOf = lib.tail github-uri-prefixes; web.browser = "google-chrome-stable"; "filter \"lfs\"" = { required = true; smudge = "git-lfs smudge -- %f"; process = "git-lfs filter-process"; clean = "git-lfs clean -- %f"; }; }; ignores = [ ".vscode" ".direnv" ".envrc" "shell.nix" ]; } (let uri-prefixes = [ # Preferred "pvv-git:" # Alternative "https://git.pvv.org/" "ssh://gitea@git.pvv.ntnu.no:2222/" "gitea@git.pvv.ntnu.no:2222/" "gitea@git.pvv.ntnu.no:" "git.pvv.ntnu.no:" ]; prefixes-per-org = let organizations = [ "Drift" "Projects" ]; in lib.genAttrs organizations (org: map (uri-prefix: "${uri-prefix}${org}") uri-prefixes); in { extraConfig."url \"${lib.head uri-prefixes}\"".insteadOf = lib.tail uri-prefixes; includes = map (x: { contentSuffix = "pvv.gitconfig"; condition = "hasconfig:remote.*.url:${x}**"; contents = { user = { email = "oysteikt@pvv.ntnu.no"; name = "Øystein Tveit"; }; }; }) (lib.flatten (lib.attrValues prefixes-per-org)); }) (let bitbucket-uri-prefixes = [ # Preferred "bitbucket-nordicsemi:" # Alternative "ssh://git@bitbucket.nordicsemi.no:7999" "https://projecttools.nordicsemi.no/bitbucket/scm" ]; prefixes-per-org = let organizations = [ "NordicSemiconductor" "NordicPlayground" "nrfconnect" "oysteintveit-nordicsemi" ]; in lib.genAttrs organizations (org: map (uri-prefix: "${uri-prefix}${org}") github-uri-prefixes); in { extraConfig = lib.mergeAttrs { "url \"${lib.head bitbucket-uri-prefixes}\"".insteadOf = lib.tail bitbucket-uri-prefixes; } (lib.mapAttrs' (org: uri-prefixes: { name = "url \"github-nordicsemi:${org}\""; value.insteadOf = uri-prefixes; }) prefixes-per-org) ; includes = map (x: { contentSuffix = "nordicsemi.gitconfig"; condition = "hasconfig:remote.*.url:${x}/**"; path = config.sops.secrets."git/nordicsemi-config".path; }) (bitbucket-uri-prefixes ++ (lib.flatten (lib.attrValues prefixes-per-org))); }) ]; home.packages = [ (pkgs.writeShellApplication { name = "git-tcommit"; runtimeInputs = with pkgs; [ cfg.package coreutils ]; text = lib.fileContents ./scripts/git-tcommit.sh; }) (pkgs.writeShellApplication { name = "git-tmcommit"; runtimeInputs = with pkgs; [ cfg.package coreutils ]; text = lib.pipe ./scripts/git-tcommit.sh [ lib.fileContents (builtins.replaceStrings ["hours" "tcommit"] ["minutes" "tmcommit"]) ]; }) (pkgs.writeShellApplication { name = "git-fixup-fixup"; runtimeInputs = with pkgs; [ cfg.package ]; text = lib.fileContents ./scripts/git-fixup-fixup.sh; }) (pkgs.writeShellApplication { name = "git-rebase-fixups"; runtimeInputs = with pkgs; [ cfg.package gnused ]; text = lib.fileContents ./scripts/git-rebase-fixups.sh; }) (pkgs.writeShellApplication { name = "git-switch-interactive"; runtimeInputs = with pkgs; [ cfg.package fzf gnused coreutils ]; text = lib.fileContents ./scripts/git-switch-interactive.sh; excludeShellChecks = [ "SC2001" # (style): See if you can use ${variable//search/replace} instead. (sed invocation) ]; }) ((pkgs.writers.writePython3Bin "git-post-pr" { libraries = with pkgs.python3Packages; [ tkinter ]; flakeIgnore = [ "E501" # I like long lines grr ]; } (lib.fileContents ./scripts/git-post-pr.py)).overrideAttrs (_: { postFixup = '' wrapProgram $out/bin/git-post-pr \ --prefix PATH : ${lib.makeBinPath [ pkgs.github-cli ]} ''; })) pkgs.git-absorb ]; }