git-daemon
Provide unauthenticated Git repository access
TLDR
Launch a Git daemon with a whitelisted set of directories
Launch a Git daemon with a specific base directory and allow pulling from all sub-directories that look like Git repositories
Launch a Git daemon for the specified directory, verbosely printing log messages and allowing Git clients to write to it
SYNOPSIS
git daemon [--verbose] [--strict-paths] [--base-path=<path>] [--export-all] [--[no-]informative-errors] [--inetd | --port=<n>] [--[no-]reuseaddr] [--[no-]fork] [--detach] [--pid-file=<file>] [--user=<user> [--group=<group>]] [--syslog] [--log-destination=<dest>] [<directory>...] [-- <cmd> -- <args>]
PARAMETERS
--advertise-ports=advertise
Use specified format to advertise ports in info/refs
--base-path=<path>
Prepend <path> to exported repository paths
--bidirectional
Allow bidirectional operations (e.g., push)
--detach
Daemonize process after startup
--enable=<service>
Enable specific services like 'upload-archive'
--export-all
Expose all repositories under base-path
--forbid-overwrite
Refuse <ref> updates overwriting existing refs
--fork
Fork on incoming connections (default)
--group=<group>
Set group for daemon process
--inetd
Run from inetd/xinetd
--informative-errors
Report detailed errors to clients
--interpolated-path=<path>
Path with %s,%H,%SP placeholders
--ipv4 | --ipv6 | --listen=<host> | --port=<n>
IP version, listen address, or TCP port (default 9418)
--log-destination=<file>
Log to stderr, file, or syslog
--max-connections=<n>
Limit concurrent connections
--pid-file=<file>
Write PID to file
--reuseaddr | --no-reuseaddr
Reuse port in TIME_WAIT
--serve-objects[=<path>]
Serve loose objects directly
--strict-paths
Disallow '~user' or relative paths
--syslog
Log to syslog
--user=<user>
Run as specified user
--user-path | --validate
Use ~/public_git or validate paths
--verbose
Log details
--version-weight=<n>
Prioritize refs by version sort weight
DESCRIPTION
The git daemon command runs a lightweight server to provide access to Git repositories over the native git:// protocol on TCP port 9418 by default. It is designed for read-only anonymous access, making it ideal for public mirrors or internal read-only sharing without authentication overhead. Users invoke it by specifying one or more directories containing bare repositories (e.g., /pub/git), which become accessible as git://hostname/pub/git/repo.git. With --export-all, it serves all repositories under the base path.
Key features include support for inetd/xinetd integration, foreground/detached modes, PID file management, syslog logging, and IPv4/IPv6 listening. Security options like --strict-paths prevent access outside specified directories, and --forbid-overwrite blocks pushes. It handles multiple connections, with limits configurable via --max-connections. While efficient for clones and fetches, it lacks built-in authentication, HTTPS, or push support unless extended with hooks or alternatives like Gitolite.
Common use cases: hosting public repos on a VPS, testing Git servers, or legacy setups before smart HTTP. Not recommended for production without firewall restrictions due to unauthenticated access risks.
CAVEATS
Insecure by default: no authentication; restrict with firewalls. Bare repos required. Pushes need --bidirectional and hooks. Not for production HTTPS/Smart-HTTP use.
COMMON INVOCATION
git daemon --reuseaddr --verbose --base-path=/srv/git/ /srv/git &
Starts serving repos under /srv/git on port 9418.
SECURITY NOTE
Use --strict-paths --prohibit-empty --forbid-overwrite to mitigate risks. Prefer Git over SSH/HTTP for authenticated access.
HISTORY
Introduced in Git 1.4.0 (2007) as simple git:// server. Evolved with IPv6, logging, and security options in later releases (e.g., 1.7+). Usage declined with HTTP/SSH rise but remains for mirrors.
SEE ALSO
git(1), git-upload-pack(1), git-http-backend(1), inetd(8), xinetd(8), systemd.socket(5)


