{ lib, config, namespace, pkgs, ... }: let inherit (lib) mkIf; inherit (lib.${namespace}) mkEnableModule; cfg = config.${namespace}.programs.git; in { options = mkEnableModule "programs.git"; config = mkIf cfg.enable { imports = [ ./aliases.nix ]; home.packages = with pkgs; [ gum clipboard-jh ]; # ██████╗ ██╗████████╗ # ██╔════╝ ██║╚══██╔══╝ # ██║ ███╗██║ ██║ # ██║ ██║██║ ██║ # ╚██████╔╝██║ ██║ # ╚═════╝ ╚═╝ ╚═╝ programs.git = { enable = true; userName = "punkfairie"; userEmail = "marley@punkfairie.net"; signing = { signByDefault = true; key = null; }; lfs.enable = true; ignores = [ "tags*" "gems.tags" ]; attributes = [ # Auto-normalize line endings. "* text=auto" "*.png binary" "*.jpg binary" "*.jpeg binary" "*.bmp binary" ]; # ██████╗ ███████╗██╗ ████████╗ █████╗ # ██╔══██╗██╔════╝██║ ╚══██╔══╝██╔══██╗ # ██║ ██║█████╗ ██║ ██║ ███████║ # ██║ ██║██╔══╝ ██║ ██║ ██╔══██║ # ██████╔╝███████╗███████╗██║ ██║ ██║ # ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ # delta = { # enable = true; # # options = { # navigate = true; # # TODO: Add to rose-pine-nix # syntax-theme = "${theme.colors.base}"; # features = "mellow-barbet"; # true-color = "always"; # hyperlinks = true; # }; # }; # ██████╗ ██╗███████╗███████╗████████╗ █████╗ ███████╗████████╗██╗ ██████╗ # ██╔══██╗██║██╔════╝██╔════╝╚══██╔══╝██╔══██╗██╔════╝╚══██╔══╝██║██╔════╝ # ██║ ██║██║█████╗ █████╗ ██║ ███████║███████╗ ██║ ██║██║ # ██║ ██║██║██╔══╝ ██╔══╝ ██║ ██╔══██║╚════██║ ██║ ██║██║ # ██████╔╝██║██║ ██║ ██║ ██║ ██║███████║ ██║ ██║╚██████╗ # ╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝ difftastic = { enable = true; }; # ██████╗ ██████╗ ███╗ ██╗███████╗██╗ ██████╗ # ██╔════╝██╔═══██╗████╗ ██║██╔════╝██║██╔════╝ # ██║ ██║ ██║██╔██╗ ██║█████╗ ██║██║ ███╗ # ██║ ██║ ██║██║╚██╗██║██╔══╝ ██║██║ ██║ # ╚██████╗╚██████╔╝██║ ╚████║██║ ██║╚██████╔╝ # ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝ extraConfig = { core = { # Whitespace types to treat as errors. # blank-at-eol: looks for spaces at EOL. # -blank-at-eof: allows blank lines at EOF. # space-before-tab: looks for spaces immediately before tabs at the # beginning of the line. whitespace = "blank-at-eol,-blank-at-eof,space-before-tab"; # Prevent showing files whose names contain non-ASCII symbols as # unversioned. precomposeunicode = false; # Speed up commands involving untracked files such as `git status`. untrackedCache = true; }; # Do not guess the user's identity. user.useConfigOnly = true; color.diff = "always"; pretty = { lo = "tformat:%C(auto)%h%C(reset)%C(auto)%d%C(reset) %s %C(italic blue)%ad%C(reset) %C(241)%aN%C(reset)"; lc = "format:%C(auto)%h%C(reset) %C(white)-%C(reset) %C(italic blue)%ad%C(reset) %C(italic cyan)(%ar)%C(reset)%C(auto)%d%C(reset)%n %C(white)⤷%C(reset) %s %C(241)- %aN <%aE>%C(reset)%n"; lt = "format:%C(auto)%h%C(reset) %C(white)-%C(reset) %C(italic blue)%ad%C(reset) %C(italic cyan)(%ar)%C(reset)%C(auto)%d%C(reset)%n %C(white)⤷%C(reset) %s %C(241)- %aN <%aE>%C(reset)%n%w(0,7,7)%+(trailers:only,unfold)"; lf = "format:%C(auto)%h%C(reset)%C(auto)%d%C(reset) %C(italic 239)[P: %p] [T: %t]%C(reset)%n%C(white)Author:%C(reset) %aN %C(241)<%aE>%C(reset)%n %C(italic blue)%ad%C(reset) %C(italic cyan)(%ar)%C(reset)%n%C(white)Commit:%C(reset) %cN %C(241)<%cE>%C(reset) %C(italic 239)[GPG: %G?% GK]%C(reset)%n %C(italic blue)%cd%C(reset) %C(italic cyan)(%cr)%C(reset)%w(0,4,4)%n%n%C(bold)%s%C(reset)%n%n%-b%n%n%-N%n"; rlo = "tformat:%C(auto)%h%C(reset) %C(bold yellow)(%C(magenta)%gd%C(bold yellow))%C(reset)%C(auto)%d%C(reset) %gs %C(italic blue)%ad%C(reset) %C(241)%aN%C(reset)"; rlc = "format:%C(auto)%h%C(reset) %C(white)-%C(reset) %C(italic blue)%ad%C(reset) %C(italic cyan)(%ar)%C(reset)%C(auto)%d%C(reset)%n %C(white)⤷%C(reset) %s %C(241)- %aN <%aE>%C(reset)%n %C(white)⤷%C(reset) %C(bold yellow)(%C(magenta)%gd%C(bold yellow))%C(reset) %gs %C(241)- %gN <%gE>%C(reset)%n"; rlt = "format:%C(auto)%h%C(reset) %C(white)-%C(reset) %C(italic blue)%ad%C(reset) %C(italic cyan)(%ar)%C(reset)%C(auto)%d%C(reset)%n %C(white)⤷%C(reset) %s %C(241)- %aN <%aE>%C(reset)%n %C(white)⤷%C(reset) %C(bold yellow)(%C(magenta)%gd%C(bold yellow))%C(reset) %gs %C(241)- %gN <%gE>%C(reset)%n%w(0,7,7)%+(trailers:only,unfold)"; rlf = "format:%C(auto)%h%C(reset) %C(bold yellow)(%C(magenta)%gd%C(bold yellow))%C(reset)%C(auto)%d%C(reset) %C(italic 239)[P: %p] [T: %t]%C(reset)%n%C(white)Author:%C(reset) %aN %C(241)<%aE>%C(reset)%n %C(italic blue)%ad%C(reset) %C(italic cyan)(%ar)%C(reset)%n%C(white)Commit:%C(reset) %cN %C(241)<%cE>%C(reset) %C(italic 239)[GPG: %G?% GK]%C(reset)%n %C(italic blue)%cd%C(reset) %C(italic cyan)(%cr)%C(reset)%n%C(white)Reflog:%C(reset) %gN %C(241)<%gE>%C(reset)%n %C(italic)%gs%C(reset)%w(0,4,4)%n%n%C(bold)%s%C(reset)%n%n%-b%n%n%-N%n"; }; init.defaultBranch = "main"; status.showstash = true; push = { autoSetupRemote = true; # Push tags automatically. followTags = true; }; rebase.autosquash = true; merge = { # Use nvim for merging, specifically the view showing LOCAL, MERGED, # REMOTE. tool = "nvimdiff2"; # Include summaries of merged commits in merge commit messages. log = true; # delta. conflictstyle = "diff3"; }; mergetool = { keepBackup = false; hideResolved = true; }; diff = { # Detect when files are copied as well as renamed. renames = "copies"; # delta colorMoved = "default"; }; # Fix whitespace errors when applying a patch, as specified in # core.whitespace. apply.whitespace = "fix"; branch = { # Show most recently changed branches first. sort = "-committerdate"; autoSetupMerge = "simple"; }; credential.helper = "store"; }; # ███╗ ███╗██╗███████╗ ██████╗ # ████╗ ████║██║██╔════╝██╔════╝ # ██╔████╔██║██║███████╗██║ # ██║╚██╔╝██║██║╚════██║██║ # ██║ ╚═╝ ██║██║███████║╚██████╗ # ╚═╝ ╚═╝╚═╝╚══════╝ ╚═════╝ home.shellAbbrs = { g = "git"; }; programs.fish.functions = lib.mkIf config.programs.fish.enable { git_develop_branch = # fish '' command git rev-parse --git-dir &>/dev/null || return set -l branch for branch in dev devel develop development if command git show-ref -q --verify refs/heads/$branch echo $branch return 0 end end echo develop return 1 ''; git_main_branch = # fish '' command git rev-parse --git-dir &>/dev/null || return set -l ref for ref in refs/{heads,remotes/{origin,upstream}}/{main,trunk,mainline,default,master} if command git show-ref -q --verify $ref echo (basename $ref) return 0 end end echo main return 1 ''; git_current_branch = # fish '' set -l ref (git symbolic-ref --quiet HEAD 2>/dev/null) set -l ret $status if [ $ret -ne 0 ] [ $ret -eq 128 ] && return # no git repo set ref (git rev-parse --short HEAD 2>/dev/null) || return end echo (string replace "refs/heads/" "" $ref) ''; git_open = # fish '' set -f origin "$(git remote get-url origin)" switch "$origin" case "*github*" if command -v gh &>/dev/null gh repo view --web &>/dev/null else set_color red echo "[ERROR] Install gh-cli to open Github repos." >&2 set_color normal return 1 end case "https://*" open '$origin' >/dev/null & case "*" set_color red printf "[ERROR] Unrecognized origin %s" "$origin" >&2 return 1 end ''; }; }; }; } # ███╗ ██╗ ██████╗ ████████╗███████╗███████╗ # ████╗ ██║██╔═══██╗╚══██╔══╝██╔════╝██╔════╝ # ██╔██╗ ██║██║ ██║ ██║ █████╗ ███████╗ # ██║╚██╗██║██║ ██║ ██║ ██╔══╝ ╚════██║ # ██║ ╚████║╚██████╔╝ ██║ ███████╗███████║ # ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚══════╝╚══════╝ # PATH VALUES: # :/ - all files within the root of the working tree, so all files in the # repo, a la git add's --all option. # A note on reset, restore, and revert, paraphrased from `man git`, plus my # own on `rm`: # # revert - make a new commit that reverts a previous commit. # restore - undo uncommitted changes in the working tree. # reset - update the branch and change commit history. # rm - same as system rm; remove files, either from git's knowledge, the # working directory, or both. # # These are not a description of the *possible* uses, rather a narrowing of # the *intended* uses.