| '\" t |
| .\" Title: git-daemon |
| .\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author] |
| .\" Generator: DocBook XSL Stylesheets v1.79.2 <http://docbook.sf.net/> |
| .\" Date: 2025-09-23 |
| .\" Manual: Git Manual |
| .\" Source: Git 2.51.0.315.gbb69721404 |
| .\" Language: English |
| .\" |
| .TH "GIT\-DAEMON" "1" "2025-09-23" "Git 2\&.51\&.0\&.315\&.gbb6972" "Git Manual" |
| .\" ----------------------------------------------------------------- |
| .\" * Define some portability stuff |
| .\" ----------------------------------------------------------------- |
| .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| .\" http://bugs.debian.org/507673 |
| .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html |
| .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| .ie \n(.g .ds Aq \(aq |
| .el .ds Aq ' |
| .\" ----------------------------------------------------------------- |
| .\" * set default formatting |
| .\" ----------------------------------------------------------------- |
| .\" disable hyphenation |
| .nh |
| .\" disable justification (adjust text to left margin only) |
| .ad l |
| .\" ----------------------------------------------------------------- |
| .\" * MAIN CONTENT STARTS HERE * |
| .\" ----------------------------------------------------------------- |
| .SH "NAME" |
| git-daemon \- A really simple server for Git repositories |
| .SH "SYNOPSIS" |
| .sp |
| .nf |
| \fBgit\fR \fBdaemon\fR [\fB\-\-verbose\fR] [\fB\-\-syslog\fR] [\fB\-\-export\-all\fR] |
| [\fB\-\-timeout=\fR\fI<n>\fR] [\fB\-\-init\-timeout=\fR\fI<n>\fR] [\fB\-\-max\-connections=\fR\fI<n>\fR] |
| [\fB\-\-strict\-paths\fR] [\fB\-\-base\-path=\fR\fI<path>\fR] [\fB\-\-base\-path\-relaxed\fR] |
| [\fB\-\-user\-path\fR | \fB\-\-user\-path=\fR\fI<path>\fR] |
| [\fB\-\-interpolated\-path=\fR\fI<pathtemplate>\fR] |
| [\fB\-\-reuseaddr\fR] [\fB\-\-detach\fR] [\fB\-\-pid\-file=\fR\fI<file>\fR] |
| [\fB\-\-enable=\fR\fI<service>\fR] [\fB\-\-disable=\fR\fI<service>\fR] |
| [\fB\-\-allow\-override=\fR\fI<service>\fR] [\fB\-\-forbid\-override=\fR\fI<service>\fR] |
| [\fB\-\-access\-hook=\fR\fI<path>\fR] [\fB\-\-\fR[\fBno\-\fR]\fBinformative\-errors\fR] |
| [\fB\-\-inetd\fR | |
| [\fB\-\-listen=\fR\fI<host\-or\-ipaddr>\fR] [\fB\-\-port=\fR\fI<n>\fR] |
| [\fB\-\-user=\fR\fI<user>\fR [\fB\-\-group=\fR\fI<group>\fR]]] |
| [\fB\-\-log\-destination=\fR(\fBstderr\fR|\fBsyslog\fR|\fBnone\fR)] |
| [\fI<directory>\fR\&...\:] |
| .fi |
| .SH "DESCRIPTION" |
| .sp |
| A really simple TCP Git daemon that normally listens on port "DEFAULT_GIT_PORT" aka 9418\&. It waits for a connection asking for a service, and will serve that service if it is enabled\&. |
| .sp |
| It verifies that the directory has the magic file "git\-daemon\-export\-ok", and it will refuse to export any Git directory that hasn\(cqt explicitly been marked for export this way (unless the \fB\-\-export\-all\fR parameter is specified)\&. If you pass some directory paths as \fBgit\fR \fBdaemon\fR arguments, the offers are limited to repositories within those directories\&. |
| .sp |
| By default, only \fBupload\-pack\fR service is enabled, which serves \fBgit\fR \fBfetch\-pack\fR and \fBgit\fR \fBls\-remote\fR clients, which are invoked from \fBgit\fR \fBfetch\fR, \fBgit\fR \fBpull\fR, and \fBgit\fR \fBclone\fR\&. |
| .sp |
| This is ideally suited for read\-only updates, i\&.e\&., pulling from Git repositories\&. |
| .sp |
| An \fBupload\-archive\fR also exists to serve \fBgit\fR \fBarchive\fR\&. |
| .SH "OPTIONS" |
| .PP |
| \fB\-\-strict\-paths\fR |
| .RS 4 |
| Match paths exactly (i\&.e\&. don\(cqt allow "/foo/repo" when the real path is "/foo/repo\&.git" or "/foo/repo/\&.git") and don\(cqt do user\-relative paths\&. |
| \fBgit\fR |
| \fBdaemon\fR |
| will refuse to start when this option is enabled and no directory arguments are provided\&. |
| .RE |
| .PP |
| \fB\-\-base\-path=\fR\fI<path>\fR |
| .RS 4 |
| Remap all the path requests as relative to the given path\&. This is sort of "Git root" \- if you run |
| \fBgit\fR |
| \fBdaemon\fR |
| with |
| \fB\-\-base\-path=/srv/git\fR |
| on |
| \fBexample\&.com\fR, then if you later try to pull from |
| \fBgit://example\&.com/hello\&.git\fR, |
| \fBgit\fR |
| \fBdaemon\fR |
| will interpret the path as |
| \fB/srv/git/hello\&.git\fR\&. |
| .RE |
| .PP |
| \fB\-\-base\-path\-relaxed\fR |
| .RS 4 |
| If |
| \fB\-\-base\-path\fR |
| is enabled and repo lookup fails, with this option |
| \fBgit\fR |
| \fBdaemon\fR |
| will attempt to lookup without prefixing the base path\&. This is useful for switching to |
| \fB\-\-base\-path\fR |
| usage, while still allowing the old paths\&. |
| .RE |
| .PP |
| \fB\-\-interpolated\-path=\fR\fI<pathtemplate>\fR |
| .RS 4 |
| To support virtual hosting, an interpolated path template can be used to dynamically construct alternate paths\&. The template supports |
| \fB%H\fR |
| for the target hostname as supplied by the client but converted to all lowercase, |
| \fB%CH\fR |
| for the canonical hostname, |
| \fB%IP\fR |
| for the server\(cqs IP address, |
| \fB%P\fR |
| for the port number, and |
| \fB%D\fR |
| for the absolute path of the named repository\&. After interpolation, the path is validated against the directory list\&. |
| .RE |
| .PP |
| \fB\-\-export\-all\fR |
| .RS 4 |
| Allow pulling from all directories that look like Git repositories (have the |
| \fIobjects\fR |
| and |
| \fIrefs\fR |
| subdirectories), even if they do not have the |
| \fBgit\-daemon\-export\-ok\fR |
| file\&. |
| .RE |
| .PP |
| \fB\-\-inetd\fR |
| .RS 4 |
| Have the server run as an inetd service\&. Implies |
| \fB\-\-syslog\fR |
| (may be overridden with |
| \fB\-\-log\-destination=\fR)\&. Incompatible with |
| \fB\-\-detach\fR, |
| \fB\-\-port\fR, |
| \fB\-\-listen\fR, |
| \fB\-\-user\fR |
| and |
| \fB\-\-group\fR |
| options\&. |
| .RE |
| .PP |
| \fB\-\-listen=\fR\fI<host\-or\-ipaddr>\fR |
| .RS 4 |
| Listen on a specific IP address or hostname\&. IP addresses can be either an IPv4 address or an IPv6 address if supported\&. If IPv6 is not supported, then |
| \fB\-\-listen=\fR\fI<hostname>\fR |
| is also not supported and |
| \fB\-\-listen\fR |
| must be given an IPv4 address\&. Can be given more than once\&. Incompatible with |
| \fB\-\-inetd\fR |
| option\&. |
| .RE |
| .PP |
| \fB\-\-port=\fR\fI<n>\fR |
| .RS 4 |
| Listen on an alternative port\&. Incompatible with |
| \fB\-\-inetd\fR |
| option\&. |
| .RE |
| .PP |
| \fB\-\-init\-timeout=\fR\fI<n>\fR |
| .RS 4 |
| Timeout (in seconds) between the moment the connection is established and the client request is received (typically a rather low value, since that should be basically immediate)\&. |
| .RE |
| .PP |
| \fB\-\-timeout=\fR\fI<n>\fR |
| .RS 4 |
| Timeout (in seconds) for specific client sub\-requests\&. This includes the time it takes for the server to process the sub\-request and the time spent waiting for the next client\(cqs request\&. |
| .RE |
| .PP |
| \fB\-\-max\-connections=\fR\fI<n>\fR |
| .RS 4 |
| Maximum number of concurrent clients, defaults to 32\&. Set it to zero for no limit\&. |
| .RE |
| .PP |
| \fB\-\-syslog\fR |
| .RS 4 |
| Short for |
| \fB\-\-log\-destination=syslog\fR\&. |
| .RE |
| .PP |
| \fB\-\-log\-destination=\fR\fI<destination>\fR |
| .RS 4 |
| Send log messages to the specified destination\&. Note that this option does not imply |
| \fB\-\-verbose\fR, thus by default only error conditions will be logged\&. The |
| \fI<destination>\fR |
| must be one of: |
| .PP |
| \fBstderr\fR |
| .RS 4 |
| Write to standard error\&. Note that if |
| \fB\-\-detach\fR |
| is specified, the process disconnects from the real standard error, making this destination effectively equivalent to |
| \fBnone\fR\&. |
| .RE |
| .PP |
| \fBsyslog\fR |
| .RS 4 |
| Write to syslog, using the |
| \fBgit\-daemon\fR |
| identifier\&. |
| .RE |
| .PP |
| \fBnone\fR |
| .RS 4 |
| Disable all logging\&. |
| .RE |
| .sp |
| The default destination is |
| \fBsyslog\fR |
| if |
| \fB\-\-inetd\fR |
| or |
| \fB\-\-detach\fR |
| is specified, otherwise |
| \fBstderr\fR\&. |
| .RE |
| .PP |
| \fB\-\-user\-path\fR, \fB\-\-user\-path=\fR\fI<path>\fR |
| .RS 4 |
| Allow ~user notation to be used in requests\&. When specified with no parameter, a request to git://host/~alice/foo is taken as a request to access |
| \fIfoo\fR |
| repository in the home directory of user |
| \fBalice\fR\&. If |
| \fB\-\-user\-path=\fR\fI<path>\fR |
| is specified, the same request is taken as a request to access |
| \fI<path>\fR\fB/foo\fR |
| repository in the home directory of user |
| \fBalice\fR\&. |
| .RE |
| .PP |
| \fB\-\-verbose\fR |
| .RS 4 |
| Log details about the incoming connections and requested files\&. |
| .RE |
| .PP |
| \fB\-\-reuseaddr\fR |
| .RS 4 |
| Use |
| \fBSO_REUSEADDR\fR |
| when binding the listening socket\&. This allows the server to restart without waiting for old connections to time out\&. |
| .RE |
| .PP |
| \fB\-\-detach\fR |
| .RS 4 |
| Detach from the shell\&. Implies |
| \fB\-\-syslog\fR\&. |
| .RE |
| .PP |
| \fB\-\-pid\-file=\fR\fI<file>\fR |
| .RS 4 |
| Save the process id in |
| \fI<file>\fR\&. Ignored when the daemon is run under |
| \fB\-\-inetd\fR\&. |
| .RE |
| .PP |
| \fB\-\-user=\fR\fI<user>\fR, \fB\-\-group=\fR\fI<group>\fR |
| .RS 4 |
| Change daemon\(cqs uid and gid before entering the service loop\&. When only |
| \fB\-\-user\fR |
| is given without |
| \fB\-\-group\fR, the primary group ID for the user is used\&. The values of the option are given to |
| \fBgetpwnam\fR(\fB3\fR) and |
| \fBgetgrnam\fR(\fB3\fR) and numeric IDs are not supported\&. |
| .sp |
| Giving these options is an error when used with |
| \fB\-\-inetd\fR; use the facility of inet daemon to achieve the same before spawning |
| \fBgit\fR |
| \fBdaemon\fR |
| if needed\&. |
| .sp |
| Like many programs that switch user id, the daemon does not reset environment variables such as |
| \fBHOME\fR |
| when it runs git programs, e\&.g\&. |
| \fBupload\-pack\fR |
| and |
| \fBreceive\-pack\fR\&. When using this option, you may also want to set and export |
| \fBHOME\fR |
| to point at the home directory of |
| \fI<user>\fR |
| before starting the daemon, and make sure any Git configuration files in that directory are readable by |
| \fI<user>\fR\&. |
| .RE |
| .PP |
| \fB\-\-enable=\fR\fI<service>\fR, \fB\-\-disable=\fR\fI<service>\fR |
| .RS 4 |
| Enable/disable the service site\-wide per default\&. Note that a service disabled site\-wide can still be enabled per repository if it is marked overridable and the repository enables the service with a configuration item\&. |
| .RE |
| .PP |
| \fB\-\-allow\-override=\fR\fI<service>\fR, \fB\-\-forbid\-override=\fR\fI<service>\fR |
| .RS 4 |
| Allow/forbid overriding the site\-wide default with per repository configuration\&. By default, all the services may be overridden\&. |
| .RE |
| .PP |
| \fB\-\-informative\-errors\fR, \fB\-\-no\-informative\-errors\fR |
| .RS 4 |
| When informative errors are turned on, git\-daemon will report more verbose errors to the client, differentiating conditions like "no such repository" from "repository not exported"\&. This is more convenient for clients, but may leak information about the existence of unexported repositories\&. When informative errors are not enabled, all errors report "access denied" to the client\&. The default is |
| \fB\-\-no\-informative\-errors\fR\&. |
| .RE |
| .PP |
| \fB\-\-access\-hook=\fR\fI<path>\fR |
| .RS 4 |
| Every time a client connects, first run an external command specified by the <path> with service name (e\&.g\&. "upload\-pack"), path to the repository, hostname (\fB%H\fR), canonical hostname (\fB%CH\fR), IP address (\fB%IP\fR), and TCP port (\fB%P\fR) as its command\-line arguments\&. The external command can decide to decline the service by exiting with a non\-zero status (or to allow it by exiting with a zero status)\&. It can also look at the $REMOTE_ADDR and |
| \fB$REMOTE_PORT\fR |
| environment variables to learn about the requestor when making this decision\&. |
| .sp |
| The external command can optionally write a single line to its standard output to be sent to the requestor as an error message when it declines the service\&. |
| .RE |
| .PP |
| \fI<directory>\fR |
| .RS 4 |
| The remaining arguments provide a list of directories\&. If any directories are specified, then the |
| \fBgit\-daemon\fR |
| process will serve a requested directory only if it is contained in one of these directories\&. If |
| \fB\-\-strict\-paths\fR |
| is specified, then the requested directory must match one of these directories exactly\&. |
| .RE |
| .SH "SERVICES" |
| .sp |
| These services can be globally enabled/disabled using the command\-line options of this command\&. If finer\-grained control is desired (e\&.g\&. to allow \fBgit\fR \fBarchive\fR to be run against only in a few selected repositories the daemon serves), the per\-repository configuration file can be used to enable or disable them\&. |
| .PP |
| upload\-pack |
| .RS 4 |
| This serves |
| \fBgit\fR |
| \fBfetch\-pack\fR |
| and |
| \fBgit\fR |
| \fBls\-remote\fR |
| clients\&. It is enabled by default, but a repository can disable it by setting |
| \fBdaemon\&.uploadpack\fR |
| configuration item to |
| \fBfalse\fR\&. |
| .RE |
| .PP |
| upload\-archive |
| .RS 4 |
| This serves |
| \fBgit\fR |
| \fBarchive\fR |
| \fB\-\-remote\fR\&. It is disabled by default, but a repository can enable it by setting |
| \fBdaemon\&.uploadarch\fR |
| configuration item to |
| \fBtrue\fR\&. |
| .RE |
| .PP |
| receive\-pack |
| .RS 4 |
| This serves |
| \fBgit\fR |
| \fBsend\-pack\fR |
| clients, allowing anonymous push\&. It is disabled by default, as there is |
| \fIno\fR |
| authentication in the protocol (in other words, anybody can push anything into the repository, including removal of refs)\&. This is solely meant for a closed LAN setting where everybody is friendly\&. This service can be enabled by setting |
| \fBdaemon\&.receivepack\fR |
| configuration item to |
| \fBtrue\fR\&. |
| .RE |
| .SH "EXAMPLES" |
| .PP |
| We assume the following in /etc/services |
| .RS 4 |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ grep 9418 /etc/services |
| git 9418/tcp # Git Version Control System |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .RE |
| .PP |
| \fIgit daemon\fR as inetd server |
| .RS 4 |
| To set up |
| \fIgit daemon\fR |
| as an inetd service that handles any repository within |
| \fB/pub/foo\fR |
| or |
| \fB/pub/bar\fR, place an entry like the following into |
| \fB/etc/inetd\fR |
| all on one line: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| git stream tcp nowait nobody /usr/bin/git |
| git daemon \-\-inetd \-\-verbose \-\-export\-all |
| /pub/foo /pub/bar |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .RE |
| .PP |
| \fIgit daemon\fR as inetd server for virtual hosts |
| .RS 4 |
| To set up |
| \fIgit daemon\fR |
| as an inetd service that handles repositories for different virtual hosts, |
| \fBwww\&.example\&.com\fR |
| and |
| \fBwww\&.example\&.org\fR, place an entry like the following into |
| \fB/etc/inetd\fR |
| all on one line: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| git stream tcp nowait nobody /usr/bin/git |
| git daemon \-\-inetd \-\-verbose \-\-export\-all |
| \-\-interpolated\-path=/pub/%H%D |
| /pub/www\&.example\&.org/software |
| /pub/www\&.example\&.com/software |
| /software |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| In this example, the root\-level directory |
| \fB/pub\fR |
| will contain a subdirectory for each virtual host name supported\&. Further, both hosts advertise repositories simply as |
| \fBgit://www\&.example\&.com/software/repo\&.git\fR\&. For pre\-1\&.4\&.0 clients, a symlink from |
| \fB/software\fR |
| into the appropriate default repository could be made as well\&. |
| .RE |
| .PP |
| \fIgit daemon\fR as regular daemon for virtual hosts |
| .RS 4 |
| To set up |
| \fBgit\fR |
| \fBdaemon\fR |
| as a regular, non\-inetd service that handles repositories for multiple virtual hosts based on their IP addresses, start the daemon like this: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| git daemon \-\-verbose \-\-export\-all |
| \-\-interpolated\-path=/pub/%IP/%D |
| /pub/192\&.168\&.1\&.200/software |
| /pub/10\&.10\&.220\&.23/software |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| In this example, the root\-level directory |
| \fB/pub\fR |
| will contain a subdirectory for each virtual host IP address supported\&. Repositories can still be accessed by hostname though, assuming they correspond to these IP addresses\&. |
| .RE |
| .PP |
| selectively enable/disable services per repository |
| .RS 4 |
| To enable |
| \fBgit\fR |
| \fBarchive\fR |
| \fB\-\-remote\fR |
| and disable |
| \fBgit\fR |
| \fBfetch\fR |
| against a repository, have the following in the configuration file in the repository (that is the file |
| \fIconfig\fR |
| next to |
| \fBHEAD\fR, |
| \fIrefs\fR |
| and |
| \fIobjects\fR)\&. |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| [daemon] |
| uploadpack = false |
| uploadarch = true |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .RE |
| .SH "ENVIRONMENT" |
| .sp |
| \fBgit\fR \fBdaemon\fR will set \fBREMOTE_ADDR\fR to the IP address of the client that connected to it, if the IP address is available\&. \fBREMOTE_ADDR\fR will be available in the environment of hooks called when services are performed\&. |
| .SH "GIT" |
| .sp |
| Part of the \fBgit\fR(1) suite |