By admin , 28 April 2026

Introduction

Git can transport data over four families of protocols. Each has different trade-offs in performance, authentication, and firewall friendliness.

Local / file

Cloning from a directory uses local file I/O. Two URL forms:

git clone /srv/git/widget.git
git clone file:///srv/git/widget.git

The first form may use hardlinks for objects when on the same filesystem (very fast, very space-efficient). The file:// form always copies via the smart protocol.

SSH

The default for authenticated workflows. Uses your SSH client and key:

git clone [email protected]:example/widget.git
git clone ssh://[email protected]/example/widget.git

Behind the scenes, the client invokes ssh and runs git-upload-pack or git-receive-pack on the server side. Configure keys via ~/.ssh/config and ssh-agent.

HTTP / HTTPS

Most firewall-friendly and the default for many hosts:

git clone https://github.com/example/widget.git

The smart HTTP protocol uses POST /info/refs?service=git-upload-pack and similar endpoints. Authentication is via Basic auth (deprecated in many providers) or token in the password field. A credential helper avoids prompts on every operation:

git config --global credential.helper cache
git config --global credential.helper osxkeychain   # macOS
git config --global credential.helper manager       # Windows

git:// (anonymous)

git clone git://example.com/widget.git

Port 9418, unauthenticated, plaintext. Mostly historical; not recommended for new deployments because it offers no integrity guarantees beyond Git's own hashes.

Protocol versions

The wire protocol has v0, v1, and v2. Protocol v2 (Git 2.18+, default 2.26+) is dramatically faster for repos with many refs, because the server only advertises refs the client asked for.

git -c protocol.version=2 ls-remote origin
git config --global protocol.version 2

Smart vs dumb

"Smart" protocols negotiate; "dumb" HTTP just exposes the .git/ directory. Dumb HTTP requires git update-server-info on every push and is slower; almost no one uses it today.

Choosing a protocol

  • HTTPS: easiest to set up, works everywhere, good for read-only and CI.
  • SSH: best for daily push/pull when you control your key.
  • file://: convenient for local mirrors and tests.
  • git://: avoid except for extremely permissive public mirrors.

Capability negotiation

At connection time, client and server exchange capabilities (multi-ack, side-band, ofs-delta, filter, partial clone, push-options, atomic, etc.). Supported capabilities determine which features the operation can use. Inspect with packet tracing:

GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote origin 2>&1 | head -40

Older servers may not support newer capabilities; the client falls back gracefully. If you see surprisingly slow clones or fetches, an old server lacking multi-ack-detailed or filter is often the cause.

Common mistakes

Mixing HTTPS and SSH URLs in the same repo; if a CI uses HTTPS but your dev uses SSH, scripts can confuse each other. Either stick to one or use insteadOf rewriting:

git config --global url."[email protected]:".insteadOf "https://github.com/"

Storing personal access tokens in plaintext config; use a credential helper instead. Forgetting to enable protocol.version=2 on old Git installs. Finally, exposing git:// on the open internet for write access; the protocol cannot authenticate. Use SSH or HTTPS.