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
GitHub repository owner (user or organization)
Repository name
Must be
git-upload-packRequest Headers
gitGost sends
git/2.0 when proxying to GitHubResponse
application/x-git-upload-pack-advertisementNone - No authentication requiredinternal/http/handlers.go:409-435
Flow:
Data Transfer: Fetch Objects
GitHub repository owner
Repository name
Request Headers
application/x-git-upload-pack-requestapplication/x-git-upload-pack-resultgitGost sends
git/2.0 when proxyingRequest Body
The request body uses pkt-line format to specify: Example Request (decoded):Response
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:Server can acknowledge multiple common commits during negotiation
Enhanced version with detailed negotiation feedback
Server can send thin packs (packs with delta references to objects not in the pack)
Multiplexed communication (progress + data)
Enhanced side-band with 64KB chunks
Pack can use offset deltas
Server supports shallow clones
Client can request commits since a date
Client can request commits not reachable from refs
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
| Aspect | Upload-Pack (Fetch) | Receive-Pack (Push) |
|---|---|---|
| Direction | Server → Client | Client → Server |
| Operation | Read-only | Write (creates PR) |
| Anonymization | None needed | Full metadata stripping |
| gitGost Role | Transparent proxy | Active processor |
| GitHub Auth | None | gitGost bot account |
| Rate Limiting | None | 5 PRs/hour/IP |
| Use Cases | Clone, fetch, pull | Push for PR creation |
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