Git server - ArchWiki

Jump to content

# Git server

2 languages

- 中文（简体）
- 日本語

From ArchWiki

This article gives an overview on how to host a Git server. For more information, refer to the Git on the Server chapter of the Pro Git book.

## Protocols

Refer to Git on the Server - The Protocols for a detailed description along with pros and cons.

### General

Step by Step Guide on Setting Up git Server describes setting up an unsecured server on Arch.

By default, the git user is expired ("Your account has expired; please contact your system administrator"). Use chage to remove the expiration condition, e.g. as follows:

    # chage -E -1 git

### SSH

You only need to set up an SSH server.

You are able to secure the SSH user account even more allowing only push and pull commands on this user account. This is done by replacing the default login shell by git-shell. Described in Setting Up the Server.

When securing the git server created using the instructions in #General with the instructions of this clause (#SSH), the following additional steps are needed on Arch:

1. Change the home directory: In order for ssh to be able to read `/srv/git/.ssh/authorized_keys`, the home directory for git in `/etc/passwd` needs to be changed from `/` to `/srv/git`.
2. Change the base path when home directory is corrected: In order for git to serve the repositories, the `--base-path` in `git-daemon\@.service` need to be changed to `/srv/git` if the repositories are served from git's home directory.

### Dumb HTTP

"Dumb" in this context means that only WebDAV is involved in pulls and pushes.

#### nginx

Follow the basic WebDAV instructions for nginx. Pushing via WebDAV also requires Locking. Here is an example location block:

    /etc/nginx/nginx.conf

    location /repos/ {
            auth_basic "Authorized Personnel Only!";
            auth_basic_user_file /etc/nginx/htpasswd;
            dav_methods PUT DELETE MKCOL COPY MOVE;
            dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
            dav_access user:rw group:rw all:r;
            dav_ext_lock zone=general;
            create_full_put_path on;
            client_body_temp_path /tmp;
        }

Note the `dav_ext_lock zone`. Add the specified locking zone to the http section of your config:

    /etc/nginx/nginx.conf

    dav_ext_lock_zone zone=general:10m;

Now do the ususal steps when preparing a git repo for the server:

- `git clone --bare /path/to/myrepo myrepo.git`
- copy the bare repo to the server
- run `git update-server-info` in the bare repo
- chown the repo to be owned by http:http

You might have noticed that I added HTTP Basic Authentication to have at lease some means of access control. Everyone who has an password entry in the htaccess file can push.

Now you can clone as usual:

    $ git clone https://www.example.com/repos/myrepo.git
    Cloning into 'myrepo'...
    $

Make some changes, add, commit, and push:

    $ git push origin main
    error: Cannot access URL https://www.example.com/repos/myrepo.git/, return code 22
    fatal: git-http-push failed
    error: failed to push some refs to 'https://www.example.com/repos/myrepo.git'

Oh noes! For some reason PROPFIND reports 401 Unauthorized and that's all. Nothing in the nginx error logs. Appearently the git client has a problem passing the username and password for all subsequent requests. Running a git credential cache does not help. The only solution that works so far is editing the ~/.netrc (obviously git uses curl for http):

    ~/.netrc

    machine www.example.com
    login git
    password topsecret

    $  > git push origin main
    Fetching remote heads...
     refs/
     refs/heads/
     refs/tags/
    updating 'refs/heads/main'
     from 03f8860418facfbecedd5e0a81b480131b31bcba
     to   ec5536091e31ebf172a34c6d1ebddfc36e3bd3a6
       sending 3 objects
       done
    Updating remote server info
    To https://www.example.com/repos/myrepo.git
      0318860..ec55560  main -> main

Don't even think to specify the clone URL as `https://username:password@www.example.com/repos/myrepo.git`. This works for the initial clone but for a subsequent push you get an error message in your error log stating that the destination URL is handled by a different repository.

### Smart HTTP

This article or section needs expansion.

Reason: There are many web servers with CGI support. (Discuss in Talk:Git server)

The git-http-backend(1) is a CGI program, allowing efficient cloning, pulling and pushing over HTTP(S).

#### Apache

The setup for this is rather simple as all you need to have installed is the Apache HTTP Server, with `mod_cgi`, `mod_alias`, and `mod_env` enabled) and of course, git.

Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at:

    /etc/httpd/conf/httpd.conf

    <Directory "/usr/lib/git-core">
        Require all granted
    </Directory>

    SetEnv GIT_PROJECT_ROOT /srv/git
    SetEnv GIT_HTTP_EXPORT_ALL
    ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

This assumes your Git repositories are located at `/srv/git` and that you want to access them via something like: `http(s)://your_address.tld/git/your_repo.git`.

Note: Make sure that Apache can read and write to your repositories.

For more detailed documentation, visit the following links:

- https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP
- https://git-scm.com/docs/git-http-backend

### Git

The Git protocol is not encrypted or authenticated, and only allows read access.

The Git daemon (git-daemon(1)) can be started with `git-daemon.socket`.

The service uses the `--export-all` and `--base-path` parameters to serve all repositories placed in `/srv/git/`.

## Access control

For fine-grained access control, the following solutions are available:

- Gitolite — An access control layer on top of Git, written in Perl.

  https://github.com/sitaramc/gitolite || gitolite

- Gitosis — Software for hosting Git repositories, written in Python.

  https://github.com/tv42/gitosis || gitosis-gitAUR

Note that if you are willing to create user accounts for all of the people that should have access to the repositories and do not need access control at the level of git objects (like branches), you can also use standard file permissions for access control.[1]

## Web interfaces

### Simple web applications

- Gitweb — the default web interface that comes with Git
- cgit — A web interface for git written in plain C.

  https://git.zx2c4.com/cgit/ || cgit

### Advanced web applications

- Forgejo — Self-hosted lightweight software forge. Community managed fork of Gitea.

  https://forgejo.org || forgejo

- Gitea — Painless self-hosted Git service. It was originally born as a community-managed fork of Gogs, but in 2022 it became owned by Gitea Limited with a commercial model.

  https://gitea.io || gitea

- GitLab — Project management and code hosting application, written in Ruby.

  https://gitlab.com/gitlab-org/gitlab-ce || gitlab

- Gogs — Self Hosted Git Service, written in Go.

  https://gogs.io || gogsAUR

Categories:

- Version control system
- Servers

Hidden category:

- Pages or sections flagged with Template:Expansion