summaryrefslogtreecommitdiffstats
path: root/nixos/modules/programs/git.nix
blob: b9a4bb772df6e1d482f67a24270b3aed76a2dda0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{
  config,
  lib,
  pkgs,
  ...
}:

let
  cfg = config.programs.git;
in

{
  options = {
    programs.git = {
      enable = lib.mkEnableOption "git, a distributed version control system";

      package = lib.mkPackageOption pkgs "git" {
        example = "gitFull";
      };

      config = lib.mkOption {
        type =
          with lib.types;
          let
            gitini = attrsOf (attrsOf anything);
          in
          either gitini (listOf gitini)
          // {
            merge =
              loc: defs:
              let
                config =
                  builtins.foldl'
                    (
                      acc:
                      { value, ... }@x:
                      acc
                      // (
                        if builtins.isList value then
                          {
                            ordered = acc.ordered ++ value;
                          }
                        else
                          {
                            unordered = acc.unordered ++ [ x ];
                          }
                      )
                    )
                    {
                      ordered = [ ];
                      unordered = [ ];
                    }
                    defs;
              in
              [ (gitini.merge loc config.unordered) ] ++ config.ordered;
          };
        default = [ ];
        example = {
          init.defaultBranch = "main";
          url."https://github.com/".insteadOf = [
            "gh:"
            "github:"
          ];
        };
        description = ''
          Configuration to write to /etc/gitconfig. A list can also be
          specified to keep the configuration in order. For example, setting
          `config` to `[ { foo.x = 42; } { bar.y = 42; }]` will put the `foo`
          section before the `bar` section unlike the default alphabetical
          order, which can be helpful for sections such as `include` and
          `includeIf`. See the CONFIGURATION FILE section of {manpage}`git-config(1)` for
          more information.
        '';
      };

      prompt = {
        enable = lib.mkEnableOption "automatically sourcing git-prompt.sh. This does not change $PS1; it simply provides relevant utility functions";
      };

      lfs = {
        enable = lib.mkEnableOption "git-lfs (Large File Storage)";

        package = lib.mkPackageOption pkgs "git-lfs" { };

        enablePureSSHTransfer = lib.mkEnableOption "Enable pure SSH transfer in server side by adding git-lfs-transfer to environment.systemPackages";
      };

      attributes = lib.mkOption {
        type = lib.types.lines;
        default = "";
        example = "*.pdf diff=pdf";
        description = ''
          Assign git attributes to files (one pattern per line):

              PATTERN1 ATTR1 ATTR2 ...

          Blank lines and lines beginning with # are ignored. See
          {manpage}`gitattributes(5)` for more information.
        '';
      };
    };
  };

  config = lib.mkMerge [
    (lib.mkIf cfg.enable {
      environment.systemPackages = [ cfg.package ];
      environment.etc.gitconfig = lib.mkIf (cfg.config != [ ]) {
        text = lib.concatMapStringsSep "\n" lib.generators.toGitINI cfg.config;
      };

      environment.etc.gitattributes = lib.mkIf (cfg.attributes != "") {
        text = cfg.attributes + "\n";
      };
    })
    (lib.mkIf (cfg.enable && cfg.lfs.enable) {
      environment.systemPackages = lib.mkMerge [
        [ cfg.lfs.package ]
        (lib.mkIf cfg.lfs.enablePureSSHTransfer [ pkgs.git-lfs-transfer ])
      ];
      programs.git.config = {
        filter.lfs = {
          clean = "git-lfs clean -- %f";
          smudge = "git-lfs smudge -- %f";
          process = "git-lfs filter-process";
          required = true;
        };
      };
    })
    (lib.mkIf (cfg.enable && cfg.prompt.enable) {
      environment.interactiveShellInit = ''
        source ${cfg.package}/share/bash-completion/completions/git-prompt.sh
      '';
    })
  ];

  meta.maintainers = [ lib.maintainers.mushrowan ];
}