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.
HTTP Protocol Architecture:
Section titled “HTTP Protocol Architecture:”Smart HTTP Transport:
Section titled “Smart HTTP Transport:”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 Transport:
Section titled “Dumb HTTP Transport:”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/??/*Protocol Negotiation:
Section titled “Protocol Negotiation:”HTTP Request Flow:1. Client → Server: GET /repo.git/info/refs2. Server → Client: Reference advertisement + capabilities3. Client → Server: POST /repo.git/git-upload-pack (fetch)4. Server → Client: Pack data streamAuthentication Methods:
Section titled “Authentication Methods:”HTTP Basic Authentication:
Section titled “HTTP Basic Authentication:”# Username/password authenticationgit clone https://username:password@github.com/user/repo.git
# Prompt for credentialsgit clone https://github.com/user/repo.git# Username: your-username# Password: your-token
# Store credentialsgit config credential.helper storePersonal Access Tokens:
Section titled “Personal Access Tokens:”# GitHub personal access tokengit clone https://oauth-token@github.com/user/repo.git
# GitLab personal access tokengit clone https://oauth2:token@gitlab.com/user/repo.git
# Bitbucket app passwordgit clone https://username:app-password@bitbucket.org/user/repo.gitOAuth and Bearer Tokens:
Section titled “OAuth and Bearer Tokens:”# OAuth token authenticationcurl -H "Authorization: Bearer <token>" \ https://api.github.com/user
# Git with OAuthGIT_ASKPASS=/path/to/oauth-helper git clone <url>Certificate-Based Authentication:
Section titled “Certificate-Based Authentication:”# Client certificate authenticationgit config http.sslCert /path/to/client.crtgit config http.sslKey /path/to/client.key
# Certificate authoritygit config http.sslCAInfo /path/to/ca-bundle.crtSSL/TLS Configuration:
Section titled “SSL/TLS Configuration:”Certificate Validation:
Section titled “Certificate Validation:”# Enable SSL verification (default)git config http.sslVerify true
# Disable SSL verification (insecure)git config http.sslVerify false
# Custom CA bundlegit config http.sslCAInfo /etc/ssl/certs/ca-certificates.crt
# Self-signed certificategit config http.sslCAInfo /path/to/self-signed-ca.crtClient Certificates:
Section titled “Client Certificates:”# Configure client certificategit config http.sslCert /path/to/client.pemgit config http.sslKey /path/to/client.key
# Certificate with passphrasegit config http.sslCertPasswordProtected trueSSL Version and Ciphers:
Section titled “SSL Version and Ciphers:”# Force TLS versiongit config http.sslVersion tlsv1.2
# Custom cipher listgit config http.sslCipherList HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA
# Disable weak ciphersexport GIT_SSL_CIPHER_LIST="HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5"Server-Side HTTP Configuration:
Section titled “Server-Side HTTP Configuration:”Apache HTTP Server Setup:
Section titled “Apache HTTP Server Setup:”# 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:
Section titled “Nginx Configuration:”# Nginx configuration for Git HTTPserver { 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; }}Git HTTP Backend Configuration:
Section titled “Git HTTP Backend Configuration:”# Configure Git HTTP backendexport GIT_HTTP_EXPORT_ALL=1export GIT_PROJECT_ROOT=/var/www/git
# Repository permissionsfind /var/www/git -type d -exec chmod 755 {} \;find /var/www/git -type f -exec chmod 644 {} \;
# Update server info for dumb HTTPgit update-server-infoPerformance Optimization:
Section titled “Performance Optimization:”HTTP Connection Management:
Section titled “HTTP Connection Management:”# Configure connection poolinggit config http.maxRequests 100git config http.minSessions 10
# Connection timeout settingsgit config http.lowSpeedLimit 1000git config http.lowSpeedTime 60
# Post buffer sizegit config http.postBuffer 524288000 # 500MBCompression and Caching:
Section titled “Compression and Caching:”# Enable compressiongit config http.compression true
# Configure compression levelexport GIT_HTTP_COMPRESSION_LEVEL=6
# HTTP caching headers# Server-side: Add cache headers for static contentCDN and Proxy Optimization:
Section titled “CDN and Proxy Optimization:”# Configure proxy settingsgit config http.proxy http://proxy.company.com:8080git config https.proxy https://proxy.company.com:8080
# Bypass proxy for local addressesgit config http.proxyBypass "localhost,127.0.0.1,.local"
# CDN configuration for large repositories# Use bundle URIs for faster initial clonesAuthentication and Security:
Section titled “Authentication and Security:”Credential Management:
Section titled “Credential Management:”# Store credentials securelygit config credential.helper storegit config credential.helper cache --timeout=3600
# Use credential managergit config credential.helper manager
# Custom credential helpergit config credential.helper /path/to/custom-helperAccess Control and Authorization:
Section titled “Access Control and Authorization:”# Repository-level permissions# Configure server-side access control
# Branch-level restrictions# Implement in pre-receive hooks
# Audit logging# Enable server-side logging of Git operationsSecurity Best Practices:
Section titled “Security Best Practices:”# Use HTTPS exclusivelygit config url."https://".insteadOf git://git config url."https://".insteadOf http://
# Enable SSL verificationgit config http.sslVerify true
# Regular certificate updates# Monitor certificate expiration dates
# Rate limiting# Implement server-side rate limitingDebugging HTTP Issues:
Section titled “Debugging HTTP Issues:”Network-Level Debugging:
Section titled “Network-Level Debugging:”# Enable HTTP tracingexport GIT_CURL_VERBOSE=1export GIT_TRACE_CURL=1
# Debug SSL connectionsopenssl s_client -connect github.com:443 -servername github.com
# Check HTTP headerscurl -I https://github.com/user/repo.git/info/refsProtocol-Level Debugging:
Section titled “Protocol-Level Debugging:”# Trace Git protocol over HTTPGIT_TRACE=1 git clone https://github.com/user/repo.git
# Debug packet exchangeGIT_TRACE_PACKET=1 git fetch origin
# Check capability negotiationgit ls-remote https://github.com/user/repo.gitAuthentication Debugging:
Section titled “Authentication Debugging:”# Test basic authenticationcurl -u username:token https://api.github.com/user
# Debug credential helpersgit config --list | grep credential
# Test token validitycurl -H "Authorization: token YOUR_TOKEN" https://api.github.com/userPerformance Analysis:
Section titled “Performance Analysis:”# Measure HTTP performancetime git clone --depth=1 https://github.com/user/repo.git
# Check transfer ratesgit config --list | grep http
# Analyze network latencyping github.comtraceroute github.comEnterprise HTTP Deployment:
Section titled “Enterprise HTTP Deployment:”Load Balancing Setup:
Section titled “Load Balancing Setup:”# Load balancer configurationupstream 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; }}High Availability Configuration:
Section titled “High Availability Configuration:”# 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 operationsMonitoring and Alerting:
Section titled “Monitoring and Alerting:”# 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"Troubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”SSL Certificate Problems:
Section titled “SSL Certificate Problems:”# Certificate verification failedgit config http.sslVerify false # Temporary fix# Update CA certificates# Check certificate validity
# Self-signed certificategit config http.sslCAInfo /path/to/ca-cert.pem
# Certificate chain issuesopenssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /path/to/cert.pemAuthentication Failures:
Section titled “Authentication Failures:”# Invalid credentialsgit config --unset credential.helpergit credential reject
# Token expired# Generate new personal access token# Update stored credentials
# Two-factor authentication# Use personal access tokens instead of passwordsProxy Configuration Issues:
Section titled “Proxy Configuration Issues:”# Configure proxygit config http.proxy http://proxy.company.com:8080git config https.proxy http://proxy.company.com:8080
# Test proxy connectivitycurl --proxy http://proxy.company.com:8080 https://github.com
# Bypass proxy for internal URLsgit config http.proxyBypass "internal.company.com,localhost"Performance Problems:
Section titled “Performance Problems:”# Slow clones/fetchesgit config http.postBuffer 1048576000 # 1GBgit config http.maxRequests 100
# Connection timeoutsgit config http.lowSpeedLimit 1000git config http.lowSpeedTime 60
# Large repository handlinggit clone --depth=1 <url> # Shallow clone firstgit fetch --unshallow # Then fetch full historyFirewall and Network Issues:
Section titled “Firewall and Network Issues:”# Port blocking# Ensure ports 80/443 are opentelnet github.com 443
# Corporate firewall# Configure proxy settings# Use SSH instead of HTTPS if allowed
# DNS resolutionnslookup github.comdig github.comReal-World Usage Examples:
Section titled “Real-World Usage Examples:”GitHub Enterprise Setup:
Section titled “GitHub Enterprise Setup:”# Configure GitHub Enterprise accessgit config --global credential.helper managergit config --global credential.https://github.company.com.username your-username
# Clone from GitHub Enterprisegit clone https://github.company.com/user/repo.git
# Configure for large repositoriesgit config --global http.postBuffer 524288000git config --global http.lowSpeedLimit 0git config --global http.lowSpeedTime 999999GitLab HTTP Configuration:
Section titled “GitLab HTTP Configuration:”# GitLab HTTP server configurationserver { 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; }}Corporate Proxy Setup:
Section titled “Corporate Proxy Setup:”# Configure corporate proxy for Gitgit config --global http.proxy http://proxy.company.com:8080git config --global https.proxy http://proxy.company.com:8080git config --global http.proxyAuthMethod basic
# Configure proxy credentialsgit config --global http.proxyAuth "username:password"
# Test proxy configurationcurl --proxy http://proxy.company.com:8080 https://github.com
# Configure proxy bypassgit config --global http.proxyBypass "localhost,127.0.0.1,.local,internal.company.com"CI/CD Pipeline Optimization:
Section titled “CI/CD Pipeline Optimization:”# Optimize Git operations in CI/CDci_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_optimizationCustom Git HTTP Server:
Section titled “Custom Git HTTP Server:”#!/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}
# Usagegit_http_server "/var/git" 8080What’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.
How do I configure Git to use a proxy?
Section titled “How do I configure Git to use a proxy?”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.
How do I fix SSL certificate errors?
Section titled “How do I fix SSL certificate errors?”Update CA certificates, add self-signed certificates to trusted store, or temporarily disable verification (not recommended for production).
Can I use Git over HTTP without SSL?
Section titled “Can I use Git over HTTP without SSL?”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.
How do I debug slow HTTP Git operations?
Section titled “How do I debug slow HTTP Git operations?”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.
Can I use Git LFS over HTTP?
Section titled “Can I use Git LFS over HTTP?”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.
What’s the role of Git HTTP backend?
Section titled “What’s the role of Git HTTP backend?”Server-side CGI script that handles Git HTTP requests, translating between HTTP and Git protocols.
Applications of Git HTTP protocol
Section titled “Applications of Git HTTP protocol”- Web-Based Git Hosting: Enable Git operations through web interfaces and APIs
- Firewall-Friendly Access: Provide Git access through corporate firewalls on standard ports
- Secure Authentication: Support various authentication methods including OAuth and certificates
- Enterprise Integration: Integrate with existing web infrastructure and SSO systems
- CDN Distribution: Use CDNs and proxies for faster repository access worldwide
- Mobile and Restricted Access: Enable Git operations on networks with limited connectivity options