Git: Difference between revisions

From NixOS Wiki
imported>Ikovnatsky
Add git-credential-helper with libsecret
H7x4 (talk | contribs)
m Undo revision 17370 by H7x4 (talk), didn't read close enough that this was homemanager config
Tag: Undo
 
(14 intermediate revisions by 11 users not shown)
Line 9: Line 9:
Install <code>tk</code> to use the git gui:
Install <code>tk</code> to use the git gui:


<syntaxhighlight>
<syntaxhighlight lang=console>
git citool
$ git citool
</syntaxhighlight>
</syntaxhighlight>
Or you may wish to install the <code>gitFull</code> package, which includes <code>git gui</code>, <code>gitk</code>, etc.


== Configuration ==
== Configuration ==
Line 25: Line 27:
</syntaxhighlight>
</syntaxhighlight>


Aliases can be added with:
<syntaxhighlight lang="nix">
  programs.git = {
    enable = true;
    aliases = {
      ci = "commit";
      co = "checkout";
      s = "status";
    };
  };
</syntaxhighlight>
Git [https://git-lfs.com/ LFS] can be enabled with:
<syntaxhighlight lang="nix">
  programs.git = {
    enable = true;
    lfs.enable = true;
  };
</syntaxhighlight>
Configure git-credential-helper with libsecret:
Configure git-credential-helper with libsecret:


Line 37: Line 60:
           pkgs.git.override { withLibsecret = true; }
           pkgs.git.override { withLibsecret = true; }
         }/bin/git-credential-libsecret";
         }/bin/git-credential-libsecret";
    };
  };
}
</syntaxhighlight>
For example 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>extraConfig</code>
<syntaxhighlight lang="nix">
{ pkgs, ... }:
{
  programs.git = {
    enable = true;
    extraConfig = {
      push = { autoSetupRemote = true; };
     };
     };
   };
   };
Line 54: Line 99:
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.


git config pack.windowMemory 2g
<syntaxhighlight lang=console>
git config pack.packSizeLimit 1g
$ git config pack.windowMemory 2g
$ git config pack.packSizeLimit 1g
</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.
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
        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="bash">
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="bash">
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="bash">
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 ==
see [[bisecting]]
[[Category:Applications]]
[[Category:Version control]]

Latest revision as of 08:32, 12 September 2024

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.

Installation

Install the git package.

Additional features

Install tk to use the git gui:

$ git citool

Or you may wish to install the gitFull package, which includes git gui, gitk, etc.

Configuration

Git can be configured using Home Manager:

  programs.git = {
    enable = true;
    userName  = "John Doe";
    userEmail = "johndoe@example.com";
  };

Aliases can be added with:

  programs.git = {
    enable = true;
    aliases = {
      ci = "commit";
      co = "checkout";
      s = "status";
    };
  };

Git LFS can be enabled with:

  programs.git = {
    enable = true;
    lfs.enable = true;
  };

Configure git-credential-helper with libsecret:

{ pkgs, ... }:

{
  programs.git = {
    enable = true;
    extraConfig = {
      credential.helper = "${
          pkgs.git.override { withLibsecret = true; }
        }/bin/git-credential-libsecret";
    };
  };
}

For example to add additional configuration you can specify options in an attribute set, so to add something like this:

[push]
        autoSetupRemote = true

To your ~/.config/git/config, you can add the below to extraConfig

{ pkgs, ... }:

{
  programs.git = {
    enable = true;
    extraConfig = {
      push = { autoSetupRemote = true; };
    };
  };
}

Management of the nixpkgs git repository

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

git

git itself might not perform as usual with the default settings

git-gc

Normal git gc should work as usual, but you should force a full garbage collect every half a year or so. git gc --aggressive 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 StackOverflow answer it suffices to set some local repository config variables.

$ git config pack.windowMemory 2g
$ git config pack.packSizeLimit 1g

worked well on a machine with about 6–8 GB of free RAM and two processor threads, and reduced the size of the nixpkgs checkout from ~1.3 GB to ~0.95 GB.

Serve Git repos via SSH

This section implements Git on the Server - Setting Up the Server on NixOS.

See also: gitolite.

Configuration

{ 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
        PermitTTY no
        X11Forwarding no
    '';
  };
}

Usage

1. Run this on the server to create repo myproject accessible by user git

sudo -u git bash -c "git init --bare ~/myproject.git"

(~ here is the home of the user git, which is /var/lib/git-server)

2. Push to the server repo from another system

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

3. Clone and edit the server repo from another system

git clone git@myserver:myproject.git
cd myproject
cat a
echo world >> a
git commit -am hello
git push origin master

Bisecting Nix regressions

see bisecting