Overview
The upload-pack endpoint implements the Git Smart HTTP protocol for fetch operations. This endpoint allows you to clone and pull from repositories through gitGost, which proxies requests directly to GitHub.Upload-pack operations are read-only and do not modify repository state. They’re used for
git clone, git fetch, and git pull operations.Endpoints
Discovery: Get References
string
required
GitHub repository owner (user or organization)
string
required
Repository name
string
required
Must be
git-upload-packRequest Headers
string
gitGost sends
git/2.0 when proxying to GitHubResponse
string
application/x-git-upload-pack-advertisementstring
None - No authentication requiredinternal/http/handlers.go:409-435
Flow:
Data Transfer: Fetch Objects
string
required
GitHub repository owner
string
required
Repository name
Request Headers
string
required
application/x-git-upload-pack-requeststring
application/x-git-upload-pack-resultstring
gitGost sends
git/2.0 when proxyingRequest Body
The request body uses pkt-line format to specify: Example Request (decoded):Response
string
application/x-git-upload-pack-result- Signature:
PACK(4 bytes) - Version: 2 or 3 (4 bytes, network byte order)
- Object Count: Number of objects (4 bytes)
- Objects: Compressed object data
- Checksum: SHA-1 of the preceding data (20 bytes)
internal/http/handlers.go:437-476
Size Limits
To prevent abuse, gitGost enforces a size limit on upload-pack requests:internal/http/handlers.go:441-442
If exceeded, the server returns:
413 Request Entity Too Large
Proxy Architecture
gitGost acts as a transparent proxy for fetch operations:Why Proxy?
No Metadata Anonymization Needed
No Metadata Anonymization Needed
Fetch operations only read data - they don’t expose user identity. There’s no commit metadata to strip.
Performance
Performance
Direct proxying is faster than re-serving packfiles. GitHub’s CDN delivers optimal performance.
Compatibility
Compatibility
Ensures 100% Git protocol compatibility since GitHub is the authoritative source.
Consistency
Consistency
Users always get the exact same data whether they fetch via gitGost or directly from GitHub.
Use Cases
Clone a Repository
- Git sends
GET /info/refs?service=git-upload-packto discover refs - Git sends
POST /git-upload-packwith wants (all branch/tag tips) - gitGost proxies both requests to GitHub
- Git receives packfile and reconstructs repository
Fetch Updates
- Git sends wants (remote branch tips) and haves (local commits)
- gitGost proxies request to GitHub
- GitHub calculates minimal packfile (only new commits)
- Git receives and integrates new commits
Pull Changes
- Git performs a fetch (as above)
- Git merges fetched changes into current branch
Shallow Clone
deepen capability to GitHub.
Capabilities
GitHub (via gitGost) advertises these upload-pack capabilities:capability
Server can acknowledge multiple common commits during negotiation
capability
Enhanced version with detailed negotiation feedback
capability
Server can send thin packs (packs with delta references to objects not in the pack)
capability
Multiplexed communication (progress + data)
capability
Enhanced side-band with 64KB chunks
capability
Pack can use offset deltas
capability
Server supports shallow clones
capability
Client can request commits since a date
capability
Client can request commits not reachable from refs
capability
Client doesn’t need to send ‘done’ in some scenarios
Error Handling
Common Errors
Failed to reach GitHub (502 Bad Gateway)
Failed to reach GitHub (502 Bad Gateway)
Cause: GitHub is unreachable or returned an errorResolution:
- Check GitHub status: https://www.githubstatus.com/
- Verify repository exists and is public
- Try again in a few moments
internal/http/handlers.go:422-425 (discovery), internal/http/handlers.go:464-467 (data transfer)Request body too large (413)
Request body too large (413)
Cause: Request exceeds 50 MB limitResolution: This should rarely happen in practice. If it does, the repository may have unusual characteristics. Clone directly from GitHub instead.Code:
internal/http/handlers.go:445-447Failed to read body (400)
Failed to read body (400)
Cause: Malformed request or connection errorResolution: Check network connection, update Git clientCode:
internal/http/handlers.go:448-451Invalid repo name (400)
Invalid repo name (400)
Cause: Repository path contains invalid charactersResolution: Ensure owner and repo names only contain alphanumeric characters, hyphens, underscores, and dotsCode:
internal/http/router.go:78-92 (validation middleware)Comparison: Fetch vs Push
Implementation Details
Discovery Handler
internal/http/handlers.go:409-435
Data Transfer Handler
internal/http/handlers.go:437-476
HTTP Client Configuration
internal/http/handlers.go:31
The 30-second timeout is sufficient for most operations. Large repositories may occasionally time out - in such cases, clone directly from GitHub.
Examples
Clone via gitGost
Add as Remote
Shallow Clone for CI
When to Use gitGost for Fetching
Consistent Workflow
Use the same remote for both fetch and push operations
Testing
Test the full gitGost integration including fetch operations
Unified Interface
Build tools that interact with repositories exclusively through gitGost
Monitoring
Track all Git operations through a single endpoint
Related Resources
Git Smart HTTP
Learn about the protocol gitGost implements
Receive-Pack
Push operations (git push)
Quickstart
Get started with gitGost in 2 minutes
Architecture
System architecture overview