Skip to content

protocol-http Git Command Guide

The Git HTTP protocol enables Git operations over HTTP and HTTPS, providing firewall-friendly access and supporting both smart and dumb HTTP transports. It includes authentication, SSL/TLS encryption, and performance optimizations for web-based Git hosting.

Smart HTTP (Modern):
├── Efficient pack-based transfers
├── Bidirectional communication
├── Authentication support
├── Progress reporting
└── Protocol v1/v2 support
Endpoints:
├── GET /repo.git/info/refs (reference discovery)
├── POST /repo.git/git-upload-pack (fetch/clone)
└── POST /repo.git/git-receive-pack (push)
Dumb HTTP (Legacy):
├── Static file serving
├── No server-side Git required
├── Read-only operations
├── Simple web server sufficient
└── Fallback for basic hosting
File Structure:
├── /repo.git/HEAD
├── /repo.git/info/refs
├── /repo.git/objects/info/packs
└── /repo.git/objects/??/*
HTTP Request Flow:
1. Client → Server: GET /repo.git/info/refs
2. Server → Client: Reference advertisement + capabilities
3. Client → Server: POST /repo.git/git-upload-pack (fetch)
4. Server → Client: Pack data stream
Terminal window
# Username/password authentication
git clone https://username:password@github.com/user/repo.git
# Prompt for credentials
git clone https://github.com/user/repo.git
# Username: your-username
# Password: your-token
# Store credentials
git config credential.helper store
Terminal window
# GitHub personal access token
git clone https://oauth-token@github.com/user/repo.git
# GitLab personal access token
git clone https://oauth2:token@gitlab.com/user/repo.git
# Bitbucket app password
git clone https://username:app-password@bitbucket.org/user/repo.git
Terminal window
# OAuth token authentication
curl -H "Authorization: Bearer <token>" \
https://api.github.com/user
# Git with OAuth
GIT_ASKPASS=/path/to/oauth-helper git clone <url>
Terminal window
# Client certificate authentication
git config http.sslCert /path/to/client.crt
git config http.sslKey /path/to/client.key
# Certificate authority
git config http.sslCAInfo /path/to/ca-bundle.crt
Terminal window
# Enable SSL verification (default)
git config http.sslVerify true
# Disable SSL verification (insecure)
git config http.sslVerify false
# Custom CA bundle
git config http.sslCAInfo /etc/ssl/certs/ca-certificates.crt
# Self-signed certificate
git config http.sslCAInfo /path/to/self-signed-ca.crt
Terminal window
# Configure client certificate
git config http.sslCert /path/to/client.pem
git config http.sslKey /path/to/client.key
# Certificate with passphrase
git config http.sslCertPasswordProtected true
Terminal window
# Force TLS version
git config http.sslVersion tlsv1.2
# Custom cipher list
git config http.sslCipherList HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA
# Disable weak ciphers
export GIT_SSL_CIPHER_LIST="HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5"
# Apache configuration for Git HTTP
<VirtualHost *:80>
ServerName git.example.com
# Redirect to HTTPS
Redirect permanent / https://git.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName git.example.com
DocumentRoot /var/www/git
# SSL configuration
SSLEngine on
SSLCertificateFile /etc/ssl/certs/git.crt
SSLCertificateKeyFile /etc/ssl/private/git.key
# Git HTTP backend
ScriptAlias / /usr/lib/git-core/git-http-backend/
# Repository access control
<Location />
AuthType Basic
AuthName "Git Repository"
AuthUserFile /etc/git/auth.passwd
Require valid-user
# Enable Git operations
SetEnv GIT_HTTP_EXPORT_ALL
SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER
</Location>
# Static file serving for dumb HTTP
<Directory /var/www/git>
Options +Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
# Nginx configuration for Git HTTP
server {
listen 443 ssl http2;
server_name git.example.com;
# SSL configuration
ssl_certificate /etc/ssl/certs/git.crt;
ssl_certificate_key /etc/ssl/private/git.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5;
# Root directory
root /var/www/git;
index index.html;
# Git HTTP backend
location ~ ^/(.*/(HEAD|info/refs|objects/info/.*|git-(upload|receive)-pack))$ {
# Authentication
auth_basic "Git Repository";
auth_basic_user_file /etc/git/auth.passwd;
# FastCGI to Git HTTP backend
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
fastcgi_param GIT_HTTP_EXPORT_ALL 1;
fastcgi_param GIT_PROJECT_ROOT /var/www/git;
fastcgi_param REMOTE_USER $remote_user;
include fastcgi_params;
}
# Static files for dumb HTTP
location ~ ^/.*\.git/(HEAD|info/refs|objects/.*)$ {
auth_basic off; # Public read access
try_files $uri =404;
}
# Deny access to .git directories
location ~ /\.git/ {
deny all;
}
}
Terminal window
# Configure Git HTTP backend
export GIT_HTTP_EXPORT_ALL=1
export GIT_PROJECT_ROOT=/var/www/git
# Repository permissions
find /var/www/git -type d -exec chmod 755 {} \;
find /var/www/git -type f -exec chmod 644 {} \;
# Update server info for dumb HTTP
git update-server-info
Terminal window
# Configure connection pooling
git config http.maxRequests 100
git config http.minSessions 10
# Connection timeout settings
git config http.lowSpeedLimit 1000
git config http.lowSpeedTime 60
# Post buffer size
git config http.postBuffer 524288000 # 500MB
Terminal window
# Enable compression
git config http.compression true
# Configure compression level
export GIT_HTTP_COMPRESSION_LEVEL=6
# HTTP caching headers
# Server-side: Add cache headers for static content
Terminal window
# Configure proxy settings
git config http.proxy http://proxy.company.com:8080
git config https.proxy https://proxy.company.com:8080
# Bypass proxy for local addresses
git config http.proxyBypass "localhost,127.0.0.1,.local"
# CDN configuration for large repositories
# Use bundle URIs for faster initial clones
Terminal window
# Store credentials securely
git config credential.helper store
git config credential.helper cache --timeout=3600
# Use credential manager
git config credential.helper manager
# Custom credential helper
git config credential.helper /path/to/custom-helper
Terminal window
# Repository-level permissions
# Configure server-side access control
# Branch-level restrictions
# Implement in pre-receive hooks
# Audit logging
# Enable server-side logging of Git operations
Terminal window
# Use HTTPS exclusively
git config url."https://".insteadOf git://
git config url."https://".insteadOf http://
# Enable SSL verification
git config http.sslVerify true
# Regular certificate updates
# Monitor certificate expiration dates
# Rate limiting
# Implement server-side rate limiting
Terminal window
# Enable HTTP tracing
export GIT_CURL_VERBOSE=1
export GIT_TRACE_CURL=1
# Debug SSL connections
openssl s_client -connect github.com:443 -servername github.com
# Check HTTP headers
curl -I https://github.com/user/repo.git/info/refs
Terminal window
# Trace Git protocol over HTTP
GIT_TRACE=1 git clone https://github.com/user/repo.git
# Debug packet exchange
GIT_TRACE_PACKET=1 git fetch origin
# Check capability negotiation
git ls-remote https://github.com/user/repo.git
Terminal window
# Test basic authentication
curl -u username:token https://api.github.com/user
# Debug credential helpers
git config --list | grep credential
# Test token validity
curl -H "Authorization: token YOUR_TOKEN" https://api.github.com/user
Terminal window
# Measure HTTP performance
time git clone --depth=1 https://github.com/user/repo.git
# Check transfer rates
git config --list | grep http
# Analyze network latency
ping github.com
traceroute github.com
# Load balancer configuration
upstream git_servers {
server git1.example.com:443;
server git2.example.com:443;
server git3.example.com:443;
}
server {
listen 443 ssl;
server_name git.example.com;
location / {
proxy_pass https://git_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Terminal window
# Multi-server setup with shared storage
# Configure NFS or similar for repository storage
# Database-backed authentication
# Use LDAP or database for user management
# Session persistence
# Ensure consistent server routing for operations
# Monitor Git HTTP performance
#!/bin/bash
# Git HTTP monitoring script
monitor_git_http() {
local git_url="$1"
local log_file="/var/log/git-http-monitor.log"
# Test basic connectivity
if curl -s --max-time 10 "$git_url/info/refs" > /dev/null; then
echo "$(date): ✓ Git HTTP accessible" >> "$log_file"
else
echo "$(date): ✗ Git HTTP unreachable" >> "$log_file"
# Send alert
fi
# Test clone performance
local clone_time=$(time git ls-remote "$git_url" > /dev/null 2>&1)
echo "$(date): Clone time: $clone_time" >> "$log_file"
# Check SSL certificate
local cert_expiry=$(openssl s_client -connect "${git_url#https://}:443" \
-servername "${git_url#https://}" 2>/dev/null | \
openssl x509 -noout -dates 2>/dev/null | \
grep notAfter | cut -d= -f2)
if [ -n "$cert_expiry" ]; then
local days_until_expiry=$(( ($(date -d "$cert_expiry" +%s) - $(date +%s)) / 86400 ))
if [ "$days_until_expiry" -lt 30 ]; then
echo "$(date): ⚠ SSL certificate expires in $days_until_expiry days" >> "$log_file"
fi
fi
}
monitor_git_http "https://git.company.com/repos/project.git"
Terminal window
# Certificate verification failed
git config http.sslVerify false # Temporary fix
# Update CA certificates
# Check certificate validity
# Self-signed certificate
git config http.sslCAInfo /path/to/ca-cert.pem
# Certificate chain issues
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /path/to/cert.pem
Terminal window
# Invalid credentials
git config --unset credential.helper
git credential reject
# Token expired
# Generate new personal access token
# Update stored credentials
# Two-factor authentication
# Use personal access tokens instead of passwords
Terminal window
# Configure proxy
git config http.proxy http://proxy.company.com:8080
git config https.proxy http://proxy.company.com:8080
# Test proxy connectivity
curl --proxy http://proxy.company.com:8080 https://github.com
# Bypass proxy for internal URLs
git config http.proxyBypass "internal.company.com,localhost"
Terminal window
# Slow clones/fetches
git config http.postBuffer 1048576000 # 1GB
git config http.maxRequests 100
# Connection timeouts
git config http.lowSpeedLimit 1000
git config http.lowSpeedTime 60
# Large repository handling
git clone --depth=1 <url> # Shallow clone first
git fetch --unshallow # Then fetch full history
Terminal window
# Port blocking
# Ensure ports 80/443 are open
telnet github.com 443
# Corporate firewall
# Configure proxy settings
# Use SSH instead of HTTPS if allowed
# DNS resolution
nslookup github.com
dig github.com
Terminal window
# Configure GitHub Enterprise access
git config --global credential.helper manager
git config --global credential.https://github.company.com.username your-username
# Clone from GitHub Enterprise
git clone https://github.company.com/user/repo.git
# Configure for large repositories
git config --global http.postBuffer 524288000
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999
# GitLab HTTP server configuration
server {
listen 80;
server_name gitlab.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name gitlab.example.com;
# SSL configuration
ssl_certificate /etc/gitlab/ssl/gitlab.crt;
ssl_certificate_key /etc/gitlab/ssl/gitlab.key;
# GitLab application
location / {
proxy_pass http://gitlab-workhorse;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Git HTTP backend
location ~ ^.*/(git-upload-pack|git-receive-pack)$ {
proxy_pass http://gitlab-workhorse;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeout settings for large operations
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
}
Terminal window
# Configure corporate proxy for Git
git config --global http.proxy http://proxy.company.com:8080
git config --global https.proxy http://proxy.company.com:8080
git config --global http.proxyAuthMethod basic
# Configure proxy credentials
git config --global http.proxyAuth "username:password"
# Test proxy configuration
curl --proxy http://proxy.company.com:8080 https://github.com
# Configure proxy bypass
git config --global http.proxyBypass "localhost,127.0.0.1,.local,internal.company.com"
Terminal window
# Optimize Git operations in CI/CD
ci_git_optimization() {
echo "Optimizing Git for CI/CD pipeline..."
# Configure shallow clones for faster builds
export GIT_SHALLOW=true
# Disable SSL verification for self-hosted GitLab
if [ "$CI_SERVER_HOST" = "gitlab.company.com" ]; then
git config --global http.sslVerify false
fi
# Configure authentication
if [ -n "$GIT_TOKEN" ]; then
git config --global credential.helper store
echo "https://oauth2:$GIT_TOKEN@$CI_SERVER_HOST" > ~/.git-credentials
fi
# Optimize for large repositories
git config --global http.postBuffer 524288000
git config --global http.lowSpeedLimit 1000
git config --global http.lowSpeedTime 300
# Configure fetch behavior
git config --global fetch.prune true
git config --global fetch.pruneTags true
echo "Git optimization complete"
}
ci_git_optimization
#!/bin/bash
# Custom Git HTTP server implementation
git_http_server() {
local repo_root="$1"
local port="${2:-8080}"
echo "Starting Git HTTP server on port $port"
echo "Repository root: $repo_root"
# Simple HTTP server for Git
while true; do
# Accept connection
read -r request
# Parse HTTP request
if [[ "$request" =~ GET\ (.+)\ HTTP ]]; then
local path="${BASH_REMATCH[1]}"
case "$path" in
*/info/refs)
# Reference discovery
handle_info_refs "$repo_root" "$path"
;;
*/HEAD)
# HEAD reference
handle_head "$repo_root" "$path"
;;
*/objects/*)
# Object serving
handle_object "$repo_root" "$path"
;;
*)
echo "HTTP/1.1 404 Not Found"
echo ""
;;
esac
elif [[ "$request" =~ POST\ (.+)\ HTTP ]]; then
local path="${BASH_REMATCH[1]}"
case "$path" in
*/git-upload-pack)
# Handle fetch/clone
handle_upload_pack "$repo_root" "$path"
;;
*/git-receive-pack)
# Handle push
handle_receive_pack "$repo_root" "$path"
;;
esac
fi
done < <(nc -l -p "$port")
}
handle_info_refs() {
local repo_root="$1"
local path="$2"
# Extract repository path
local repo_path="${path%/info/refs}"
repo_path="$repo_root$repo_path"
if [ -d "$repo_path" ]; then
echo "HTTP/1.1 200 OK"
echo "Content-Type: application/x-git-upload-pack-advertisement"
echo ""
# Advertise references
git -C "$repo_path" upload-pack --advertise-refs
else
echo "HTTP/1.1 404 Not Found"
echo ""
fi
}
handle_upload_pack() {
local repo_root="$1"
local path="$2"
local repo_path="${path%/git-upload-pack}"
repo_path="$repo_root$repo_path"
echo "HTTP/1.1 200 OK"
echo "Content-Type: application/x-git-upload-pack-result"
echo ""
# Handle the upload-pack request
git -C "$repo_path" upload-pack --stateless-rpc
}
# Usage
git_http_server "/var/git" 8080

What’s the difference between smart and dumb HTTP?

Section titled “What’s the difference between smart and dumb HTTP?”

Smart HTTP uses Git’s pack protocol over HTTP for efficient transfers; dumb HTTP serves static files like a web server, requiring no server-side Git but much less efficient.

Set http.proxy and https.proxy configuration, or use environment variables HTTP_PROXY and HTTPS_PROXY. Configure proxy bypass for local addresses.

What authentication methods does HTTP support?

Section titled “What authentication methods does HTTP support?”

HTTP Basic Auth with username/password, personal access tokens, OAuth tokens, and client certificates. SSH keys are not supported over HTTP.

Update CA certificates, add self-signed certificates to trusted store, or temporarily disable verification (not recommended for production).

Yes, but insecure. HTTP URLs work but should redirect to HTTPS. Never use in production without encryption.

What’s the impact of HTTP post buffer size?

Section titled “What’s the impact of HTTP post buffer size?”

Controls how much data Git sends in one HTTP request. Larger buffers improve performance for large pushes but may cause timeouts.

Check network latency, SSL handshake time, proxy configuration, and server response times. Use GIT_CURL_VERBOSE for detailed tracing.

Can HTTP Git work through corporate firewalls?

Section titled “Can HTTP Git work through corporate firewalls?”

Yes, HTTP/HTTPS typically work through corporate firewalls on standard ports 80/443, unlike SSH (port 22) or Git protocol (port 9418).

What’s the difference between HTTP and HTTPS for Git?

Section titled “What’s the difference between HTTP and HTTPS for Git?”

HTTPS adds SSL/TLS encryption and authentication; HTTP is unencrypted. Always use HTTPS for security.

How do I configure Git to follow redirects?

Section titled “How do I configure Git to follow redirects?”

Git automatically follows HTTP redirects. Configure http.followRedirects if needed for specific behavior.

Yes, Git LFS works over HTTP/HTTPS. Configure LFS server endpoint separately from Git repository URL.

What’s the performance difference between HTTP and SSH?

Section titled “What’s the performance difference between HTTP and SSH?”

SSH often faster for small operations due to lower latency; HTTP better for large transfers due to better compression and connection reuse.

How do I handle large file uploads over HTTP?

Section titled “How do I handle large file uploads over HTTP?”

Increase http.postBuffer, configure timeouts, use resumable transfers if supported, and consider splitting large pushes.

Can HTTP Git work with self-signed certificates?

Section titled “Can HTTP Git work with self-signed certificates?”

Yes, add certificate to trusted store or use http.sslCAInfo to specify custom CA bundle.

Server-side CGI script that handles Git HTTP requests, translating between HTTP and Git protocols.

  1. Web-Based Git Hosting: Enable Git operations through web interfaces and APIs
  2. Firewall-Friendly Access: Provide Git access through corporate firewalls on standard ports
  3. Secure Authentication: Support various authentication methods including OAuth and certificates
  4. Enterprise Integration: Integrate with existing web infrastructure and SSO systems
  5. CDN Distribution: Use CDNs and proxies for faster repository access worldwide
  6. Mobile and Restricted Access: Enable Git operations on networks with limited connectivity options