{
  nixosConfig,
  lib,
  config,
  sysLib,
  pkgs,
  ...
}: let
  gitIgnoreFile = ./git_ignore.git;
  gitTemplateFile = ./git_template.git;
  commit = sysLib.writeShellScript {
    name = "commit";
    src = ./scripts/commit;
    keepPath = true;
    dependencies = with pkgs; [
      git
      gnused
    ];
  };
in {
  programs.git = {
    enable = true;
    #package = pkgs.gitAndTools.gitFull; # TODO: for git send-email support
    aliases = {
      cm = "!${commit}/bin/commit";
      cmr = "commit --file .git/COMMIT_EDITMSG --edit --verbose";

      st = "status";
      sts = "status --short --branch";

      ds = "diff --staged";
      di = "diff";
      rs = "restore --staged";

      ## Logging:
      ls = "log --max-count=10 --color --format=format:'%C(bold red)%h%C(reset) %C(dim bold blue)%s%C(reset) %C(dim white)[%aN] %C(bold red)<%G?>%C(reset)%C(auto)%d%C(reset)'";

      # https://stackoverflow.com/a/61487052
      lg = "lg1";
      lg1 = "lg1-specific --all";
      lg2 = "lg2-specific --all";
      lg3 = "lg3-specific --all";

      lg1-specific = "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(bold cyan) [%G?]%C(reset)%C(auto)%d%C(reset)'";

      lg2-specific = "log --graph --abbrev-commit --decorate \
                      --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'";

      lg3-specific = "log --graph --abbrev-commit --decorate \
                      --format=format:'%C(bold blue)%h%C(reset)\
                      - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)\
                      %C(bold cyan)(committed: %cD)%C(reset) %C(auto)%d%C(reset)\
                      %C(bold red)(signature: %G? by %GS, trust: %GT)%C(reset)%n\
                      ''          %C(white)%s%C(reset)%n''\
                      %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)\
                      %C(bold white)- trailers: %(trailers) %C(reset)'";

      # hard reset with commit before (use reflog to recover)
      #    git wipe [<commit>]
      wipe = lib.strings.concatStringsSep " " [
        "!git"
        "add"
        "--all"
        "&&"
        "git"
        "commit"
        "--quiet"
        "--message='WIPE-SAVEPOINT'"
        "--no-gpg-sign"
        "&&"
        "git reset \${1:-HEAD~} --hard"
        "&&"
        "git clean -fd"
      ];
      branches = lib.strings.concatStringsSep " " [
        "!git"
        "for-each-ref"
        "--sort=-committerdate"
        "--color=always"
        "--format='${
          lib.strings.concatStringsSep "|" [
            "%(color:blue)%(authordate:relative)"
            "%(color:red)%(authorname)"
            "%(color:green)%(color:bold)%(refname:short)"
          ]
        }'"
        "refs/remotes"
        "|"
        "column -ts'|' -o '   '"
      ];
      tags = "tag --list";
      remotes = "remote --verbose";
      day = "!git log --stat --since '1 day ago' --author $(git config user.email)";
      unpush = "push --force-with-lease origin HEAD~1:${config.programs.git.extraConfig.init.defaultBranch}";
      wip = "!git add . && git commit --amend && git push --force-with-lease";
    };
    extraConfig = {
      core = {
        excludesFile = "${gitIgnoreFile}";
      };
      rebase = {
        autoStash = true;
        autoSquash = true;
      };
      init = {
        defaultBranch = "prime";
      };
      user = {
        email = "soispha@vhack.eu";
        name = "Soispha";
      };
      help = {
        autocorrect = 5;
      };
      push = {
        gpgSign = "if-asked";
      };
      commit = {
        template = "${gitTemplateFile}";
      };
      diff = {
        colorMoved = "default";
        # Usually leads to better results
        algorithm = "patience";
        bin = {
          textconv = "hexdump -v -C";
        };
      };
      # Makes it a bit more readable
      blame = {
        coloring = "repeatedLines";
        markIgnoredLines = true;
        markUnblamables = true;
      };
      merge = {
        conflictstyle = "diff3";
      };
      url = {
        "git@codeberg.org:" = {
          insteadOf = "@cb:";
        };
        "https://codeberg.org/" = {
          insteadOf = "cb://";
        };

        "git@github.com:" = {
          insteadOf = "@gh:";
        };
        "https://github.com/" = {
          insteadOf = "gh://";
        };

        "git@gitlab.com:" = {
          insteadOf = "@gl:";
        };
        "https://gitlab.com/" = {
          insteadOf = "gl://";
        };
      };
    };
    includes = [
      {
        condition = "gitdir:~/school/";
        contents = {
          user = {
            name = nixosConfig.soispha.secret.me.name;
            email = nixosConfig.soispha.secret.me.email;
            signingKey = nixosConfig.soispha.secret.me.gpgKey;
          };
        };
      }
    ];
    delta = {
      enable = true;
      options = {
        decorations = {
          commit-decoration-style = "bold yellow box ul";
          file-decoration-style = "none";
          file-style = "bold yellow ul";
        };
        keep-plus-minus-markers = true;
        features = "decorations";
        whitespace-error-style = "22 reverse";
      };
    };
    signing = {
      key = "9606FC749FCE16360723D4ADA5E94010C3A642AD!";
      signByDefault = true;
    };
  };
}