1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 cfg = config.programs.git;
10in
11
12{
13 options = {
14 programs.git = {
15 enable = lib.mkEnableOption "git, a distributed version control system";
16
17 package = lib.mkPackageOption pkgs "git" {
18 example = "gitFull";
19 };
20
21 config = lib.mkOption {
22 type =
23 with lib.types;
24 let
25 gitini = attrsOf (attrsOf anything);
26 in
27 either gitini (listOf gitini)
28 // {
29 merge =
30 loc: defs:
31 let
32 config =
33 builtins.foldl'
34 (
35 acc:
36 { value, ... }@x:
37 acc
38 // (
39 if builtins.isList value then
40 {
41 ordered = acc.ordered ++ value;
42 }
43 else
44 {
45 unordered = acc.unordered ++ [ x ];
46 }
47 )
48 )
49 {
50 ordered = [ ];
51 unordered = [ ];
52 }
53 defs;
54 in
55 [ (gitini.merge loc config.unordered) ] ++ config.ordered;
56 };
57 default = [ ];
58 example = {
59 init.defaultBranch = "main";
60 url."https://github.com/".insteadOf = [
61 "gh:"
62 "github:"
63 ];
64 };
65 description = ''
66 Configuration to write to /etc/gitconfig. A list can also be
67 specified to keep the configuration in order. For example, setting
68 `config` to `[ { foo.x = 42; } { bar.y = 42; }]` will put the `foo`
69 section before the `bar` section unlike the default alphabetical
70 order, which can be helpful for sections such as `include` and
71 `includeIf`. See the CONFIGURATION FILE section of {manpage}`git-config(1)` for
72 more information.
73 '';
74 };
75
76 prompt = {
77 enable = lib.mkEnableOption "automatically sourcing git-prompt.sh. This does not change $PS1; it simply provides relevant utility functions";
78 };
79
80 lfs = {
81 enable = lib.mkEnableOption "git-lfs (Large File Storage)";
82
83 package = lib.mkPackageOption pkgs "git-lfs" { };
84
85 enablePureSSHTransfer = lib.mkEnableOption "Enable pure SSH transfer in server side by adding git-lfs-transfer to environment.systemPackages";
86 };
87 };
88 };
89
90 config = lib.mkMerge [
91 (lib.mkIf cfg.enable {
92 environment.systemPackages = [ cfg.package ];
93 environment.etc.gitconfig = lib.mkIf (cfg.config != [ ]) {
94 text = lib.concatMapStringsSep "\n" lib.generators.toGitINI cfg.config;
95 };
96 })
97 (lib.mkIf (cfg.enable && cfg.lfs.enable) {
98 environment.systemPackages = lib.mkMerge [
99 [ cfg.lfs.package ]
100 (lib.mkIf cfg.lfs.enablePureSSHTransfer [ pkgs.git-lfs-transfer ])
101 ];
102 programs.git.config = {
103 filter.lfs = {
104 clean = "git-lfs clean -- %f";
105 smudge = "git-lfs smudge -- %f";
106 process = "git-lfs filter-process";
107 required = true;
108 };
109 };
110 })
111 (lib.mkIf (cfg.enable && cfg.prompt.enable) {
112 environment.interactiveShellInit = ''
113 source ${cfg.package}/share/bash-completion/completions/git-prompt.sh
114 '';
115 })
116 ];
117
118 meta.maintainers = with lib.maintainers; [ figsoda ];
119}