Git: Difference between revisions
imported>Ikovnatsky Add git-credential-helper with libsecret |
Sohomdatta1 (talk | contribs) added a more complex command to show how that can be added |
||
| (33 intermediate revisions by 23 users not shown) | |||
| Line 1: | Line 1: | ||
[https://en.wikipedia.org/wiki/Git_(software) Git] is the version control system (VCS) designed | [https://en.wikipedia.org/wiki/Git_(software) Git] is the [[wikipedia:Version_control|version control system (VCS)]] developed by Junio C Hamano and designed by [[wikipedia:Linus_Torvalds|Linus Torvalds]] (Creator of the [[Linux kernel]]). Git is used to maintain NixOS packages, as well as many other projects, including sources for the Linux kernel. | ||
== | == Installing and configuring Git == | ||
On NixOS, Git can be installed and configured at either the system level with the NixOS module or the user level with [[Home Manager]]. | |||
=== | === System-wide installation === | ||
Git can be installed system-wide either by adding it to the list of system environment packages: | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | |||
environment.systemPackages = with pkgs; [ | |||
git | |||
]; | |||
</nowiki>}} | |||
Or by enabling the NixOS Git module: | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | |||
programs.git.enable = true; | |||
</nowiki>}} | |||
Additional Git module configuration options can be found at {{nixos:option|programs.git}}. | |||
{{note|Configuration options provided by this module are applied at the system level and therefore apply to all users on the system.}} | |||
=== User-level configuration with Home Manager === | |||
Git can be configured using [[Home Manager]]: | |||
<syntaxhighlight> | <syntaxhighlight lang="nix"> | ||
git | programs.git = { | ||
enable = true; | |||
settings.user = { | |||
name = "John Doe"; | |||
email = "johndoe@example.com"; | |||
}; | |||
}; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== | Aliases can be added with: | ||
<syntaxhighlight lang="nix">programs.git = { | |||
enable = true; | |||
settings.alias = { | |||
ci = "commit"; | |||
co = "checkout"; | |||
s = "status"; | |||
sync = "!git pull --rebase && git push"; | |||
}; | |||
};</syntaxhighlight> | |||
Git can be | Git [https://git-lfs.com/ LFS] can be enabled with: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
programs.git = { | |||
enable = true; | |||
lfs.enable = true; | |||
}; | |||
</syntaxhighlight> | |||
Configure git-credential-helper with <code>libsecret</code>: | |||
<syntaxhighlight lang="nix">{ pkgs, ... }: | |||
{ | |||
programs.git = { | programs.git = { | ||
enable = true; | enable = true; | ||
package = pkgs.git.override { withLibsecret = true; }; | |||
settings = { | |||
credential.helper = "libsecret"; | |||
}; | |||
}; | }; | ||
</syntaxhighlight> | }</syntaxhighlight> | ||
To add additional configuration you can specify options in an attribute set, so to add something like this: | |||
<syntaxhighlight lang="ini">[push] | |||
autoSetupRemote = true</syntaxhighlight> | |||
To your <code>~/.config/git/config</code>, you can add the below to <code>settings</code> | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
| Line 33: | Line 86: | ||
programs.git = { | programs.git = { | ||
enable = true; | enable = true; | ||
settings = { | |||
push = { autoSetupRemote = true; }; | |||
}; | |||
} | }; | ||
} | |||
</syntaxhighlight> | |||
==== Using your public SSH key as a signing key ==== | |||
To configure git to automatically sign your commits using your public SSH key like so: | |||
<syntaxhighlight lang="nix"> | |||
{ | |||
programs.git = { | |||
enable = true; | |||
signing = { | |||
key = "ssh-ed25519 AAAAAAAAAAAA...AA username@hostname"; | |||
signByDefault = true; | |||
}; | |||
settings = { | |||
gpg = { | |||
format = "ssh"; | |||
}; | |||
}; | }; | ||
}; | }; | ||
} | } | ||
</syntaxhighlight> | |||
However, note that this will also require Home Manager to manage your SSH configuration: | |||
<syntaxhighlight lang="nix">{ | |||
programs.ssh = { | |||
enable = true; | |||
addKeysToAgent = "yes"; | |||
}; | |||
}</syntaxhighlight> | |||
=== Enabling Git UI === | |||
Install <code>tk</code> to use the git gui: | |||
<syntaxhighlight lang=console> | |||
$ git citool | |||
</syntaxhighlight> | |||
Or you may wish to install the <code>gitFull</code> package, which includes <code>git gui</code>, <code>gitk</code>, etc. This can be installed either through system environment packages or by setting the package module option: | |||
<syntaxhighlight lang="nix"> | |||
programs.git = { | |||
enable = true; | |||
package = pkgs.gitFull; | |||
}; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== Management of the <code>nixpkgs</code> git repository == | == Management of the <code>nixpkgs</code> git repository == | ||
<code>nixpkgs</code> has become a git repository of quite substantial size with > | <code>nixpkgs</code> has become a git repository of quite substantial size with > 1M commits<ref>https://github.com/NixOS/nixpkgs</ref> (as of 2026). This brings many unoptimized tools to their limits, leading to long waiting times on certain operations. Here we’ll collect useful info on how to manage that. | ||
=== | === Garbage collecting === | ||
git | Normal <code>git gc</code> should work as usual, but you should force a full garbage collect every half a year or so. <code>git gc --aggressive</code> is the command for that. For the author it did not work on the first try, since their laptop’s memory was too small, and it went out of memory. According to [https://stackoverflow.com/a/4829883/1382925|this StackOverflow] answer it suffices to set some local repository config variables. | ||
==== <code>git- | <syntaxhighlight lang=console> | ||
$ git config pack.windowMemory 2g | |||
$ git config pack.packSizeLimit 1g | |||
</syntaxhighlight> | |||
This worked well on a machine with about 6–8 GB of free RAM and two processor threads, and reduced the size of the <code>nixpkgs</code> checkout from ~1.3 GB to ~0.95 GB. | |||
= Serve Git repos via SSH = | |||
This section implements [https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server Git on the Server - Setting Up the Server] on NixOS. | |||
See also: [[gitolite]]. | |||
== Configuration == | |||
<syntaxhighlight lang="nix"> | |||
{ config, pkgs, ... }: { | |||
users.users.git = { | |||
isSystemUser = true; | |||
group = "git"; | |||
home = "/var/lib/git-server"; | |||
createHome = true; | |||
shell = "${pkgs.git}/bin/git-shell"; | |||
openssh.authorizedKeys.keys = [ | |||
# FIXME: Add pubkeys of authorized users | |||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF38sHxXn/r7KzWL1BVCqcKqmZA/V76N/y5p52UQghw7 example" | |||
]; | |||
}; | |||
users.groups.git = {}; | |||
services.openssh = { | |||
enable = true; | |||
extraConfig = '' | |||
Match user git | |||
AllowTcpForwarding no | |||
AllowAgentForwarding no | |||
PasswordAuthentication no | |||
KbdInteractiveAuthentication no | |||
PermitTTY no | |||
X11Forwarding no | |||
''; | |||
}; | |||
} | |||
</syntaxhighlight> | |||
== Usage == | |||
1. Run this on the server to create repo <code>myproject</code> accessible by user <code>git</code> | |||
<syntaxhighlight lang="console"> | |||
$ sudo -u git bash -c "git init --bare ~/myproject.git" | |||
</syntaxhighlight> | |||
(<code>~</code> here is the home of the user <code>git</code>, which is <code>/var/lib/git-server</code>) | |||
2. Push to the server repo from another system | |||
<syntaxhighlight lang="console"> | |||
$ mkdir myproject | |||
$ cd myproject | |||
$ echo "hello" > a | |||
$ git init | |||
$ git add . | |||
$ git commit -m "init" | |||
$ git remote add origin git@myserver:myproject.git | |||
$ git push origin master | |||
</syntaxhighlight> | |||
3. Clone and edit the server repo from another system | |||
<syntaxhighlight lang="console"> | |||
$ git clone git@myserver:myproject.git | |||
$ cd myproject | |||
$ cat a | |||
$ echo "world" >> a | |||
$ git commit -am "hello" | |||
$ git push origin master | |||
</syntaxhighlight> | |||
== Bisecting Nix regressions == | |||
{{main|bisecting}} | |||
[[Category:Applications]] | |||
[[Category:CLI Applications]] | |||
[[Category:Version control]] | |||