Git: Difference between revisions

imported>Erikarvstedt
m add reference to gitolite
added a more complex command to show how that can be added
 
(24 intermediate revisions by 17 users not shown)
Line 1: Line 1:
[https://en.wikipedia.org/wiki/Git_(software) Git] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is used to maintain NixOS packages, as well as many other projects, including sources for the Linux kernel.  
[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.  


== Installation ==
== Installing and configuring Git ==


Install the <code>git</code> package.  
On NixOS, Git can be installed and configured at either the system level with the NixOS module or the user level with [[Home Manager]].


=== Additional features ===
=== System-wide installation ===


Install <code>tk</code> to use the git gui:
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>}}


<syntaxhighlight lang=console>
Additional Git module configuration options can be found at {{nixos:option|programs.git}}.
$ git citool
</syntaxhighlight>


Or you may wish to install the <code>gitFull</code> package, which includes <code>git gui</code>, <code>gitk</code>, etc.
{{note|Configuration options provided by this module are applied at the system level and therefore apply to all users on the system.}}


== Configuration ==
=== User-level configuration with Home Manager ===


Git can be configured using [[Home Manager]]:
Git can be configured using [[Home Manager]]:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
  programs.git = {
programs.git = {
    enable = true;
  enable = true;
     userName = "John Doe";
  settings.user = {
     userEmail = "johndoe@example.com";
     name = "John Doe";
     email = "johndoe@example.com";
   };
   };
};
</syntaxhighlight>
</syntaxhighlight>


Aliases can be added with:
Aliases can be added with:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">programs.git = {
  programs.git = {
  enable = true;
    enable = true;
  settings.alias = {
    aliases = {
    ci = "commit";
      ci = "commit";
    co = "checkout";
      co = "checkout";
    s = "status";
      s = "status";
     sync = "!git pull --rebase && git push";
     };
   };
   };
</syntaxhighlight>
};</syntaxhighlight>


Git [https://git-lfs.com/ LFS] can be enabled with:
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;
     lfs.enable = true;
     package = pkgs.git.override { withLibsecret = true; };
    settings = {
      credential.helper = "libsecret";
    };
   };
   };
</syntaxhighlight>
}</syntaxhighlight>
Configure git-credential-helper with libsecret:
 
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 56: Line 86:
   programs.git = {
   programs.git = {
     enable = true;
     enable = true;
     extraConfig = {
     settings = {
       credential.helper = "${
       push = { autoSetupRemote = true; };
          pkgs.git.override { withLibsecret = true; }
        }/bin/git-credential-libsecret";
     };
     };
   };
   };
Line 65: Line 93:
</syntaxhighlight>
</syntaxhighlight>


For example to add additional configuration you can specify options in an attribute set, so to add something like this:
==== Using your public SSH key as a signing key ====
 
<syntaxhighlight lang="ini">
[push]
        autoSetupRemote = true
</syntaxhighlight>


To your <code>~/.config/git/config</code>, you can add the below to <code>extraConfig</code>
To configure git to automatically sign your commits using your public SSH key like so:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ pkgs, ... }:
{
{
   programs.git = {
   programs.git = {
     enable = true;
     enable = true;
     extraConfig = {
     signing = {
       push = { autoSetupRemote = true; };
       key = "ssh-ed25519 AAAAAAAAAAAA...AA username@hostname";
      signByDefault = true;
    };
    settings = {
      gpg = {
        format = "ssh";
      };
     };
     };
   };
   };
Line 87: Line 114:
</syntaxhighlight>
</syntaxhighlight>


== Management of the <code>nixpkgs</code> git repository ==
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:


<code>nixpkgs</code> has become a git repository of quite substantial size with > 160 000 commits (as of early 2019). 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.
<syntaxhighlight lang="nix">
programs.git = {
  enable = true;
  package = pkgs.gitFull;
};
</syntaxhighlight>


=== git ===
== Management of the <code>nixpkgs</code> git repository ==


git itself might not perform as usual with the default settings
<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.


==== <code>git-gc</code> ====
=== Garbage collecting ===


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.
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.


<syntaxhighlight lang=console>
<syntaxhighlight lang=console>
Line 104: Line 153:
</syntaxhighlight>
</syntaxhighlight>


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.
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 =
= Serve Git repos via SSH =
Line 137: Line 186:
         AllowAgentForwarding no
         AllowAgentForwarding no
         PasswordAuthentication no
         PasswordAuthentication no
        KbdInteractiveAuthentication no
         PermitTTY no
         PermitTTY no
         X11Forwarding no
         X11Forwarding no
Line 148: Line 198:
1. Run this on the server to create repo <code>myproject</code> accessible by user <code>git</code>
1. Run this on the server to create repo <code>myproject</code> accessible by user <code>git</code>


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
sudo -u git bash -c '
$ sudo -u git bash -c "git init --bare ~/myproject.git"
  cd /var/lib/git-server
  mkdir myproject.git
  cd myproject.git
  git init --bare
'
</syntaxhighlight>
</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  
2. Push to the server repo from another system  


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
mkdir myproject1
$ mkdir myproject
cd myproject1
$ cd myproject
echo hello > a
$ echo "hello" > a
git init
$ git init
git add .
$ git add .
git commit -m init
$ git commit -m "init"
git remote add origin git@myserver:myproject.git
$ git remote add origin git@myserver:myproject.git
git push origin master
$ git push origin master
</syntaxhighlight>
</syntaxhighlight>


3. Clone and edit the server repo from another system
3. Clone and edit the server repo from another system


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
git clone git@myserver:myproject.git
$ git clone git@myserver:myproject.git
cd myproject
$ cd myproject
cat a
$ cat a
echo world >> a
$ echo "world" >> a
git commit -am hello
$ git commit -am "hello"
git push origin master
$ git push origin master
</syntaxhighlight>
</syntaxhighlight>
== Bisecting Nix regressions ==
{{main|bisecting}}


[[Category:Applications]]
[[Category:Applications]]
[[Category:CLI Applications]]
[[Category:Version control]]