DEV Community

Shrijith Venkatramana
Shrijith Venkatramana

Posted on

Understanding Git Push and Pull: How SSH Makes It Secure

Hello, I'm Shrijith Venkatramana. I’m building LiveReview, a private AI code review tool that runs on your LLM key (OpenAI, Gemini, etc.) with highly competitive pricing -- built for small teams. Do check it out and give it a try!

Git push and pull are everyday commands for developers, but under the hood, they rely on SSH to handle secure connections to remote repositories. This article dives into the mechanics, from key setup to data transfer, with practical examples to show how it all fits together.

SSH Basics: The Foundation for Git's Remote Operations

SSH, or Secure Shell, provides a secure way to connect to remote servers. In Git, it encrypts data and authenticates users during push and pull. You generate a private key (kept local) and a public key (uploaded to the server). The private key proves your identity without sending passwords over the network.

To set up, run this command to generate keys if you don't have them:

ssh-keygen -t ed25519 -C "your_email@example.com"
# Output: Generates id_ed25519 (private) and id_ed25519.pub (public) in ~/.ssh/
Enter fullscreen mode Exit fullscreen mode

Copy the public key to your clipboard (on Linux/Mac):

cat ~/.ssh/id_ed25519.pub | pbcopy
Enter fullscreen mode Exit fullscreen mode

Paste it into your Git provider's settings, like GitHub's SSH keys page. This allows passwordless access.

For more on key types, check GitHub's guide: Generating a new SSH key.

Decoding the Git Remote URL: Where SSH Starts

Your Git remote URL tells Git how to connect via SSH. A typical URL looks like git@github.com:user/repo.git.

  • git@: The SSH username on the remote server.
  • github.com: The hostname of the server.
  • :user/repo.git: The path to the repository.

To add or view remotes:

git remote add origin git@github.com:user/repo.git
git remote -v
# Output:
# origin  git@github.com:user/repo.git (fetch)
# origin  git@github.com:user/repo.git (push)
Enter fullscreen mode Exit fullscreen mode

This format triggers SSH. If it used https://, Git would prompt for credentials instead.

Establishing the SSH Connection: The Initial Handshake

When you run git push or git pull, Git initiates an SSH connection to the remote host. SSH uses TCP (port 22 by default) for reliable data transfer.

The handshake creates a secure channel:

  1. Your machine connects to the server.
  2. Both sides negotiate encryption methods.
  3. A temporary session key is generated for the connection (using Diffie-Hellman exchange to avoid eavesdropping).

No data is sent unencrypted. This happens automatically—no manual steps needed.

Authenticating the Server: Verifying You're Talking to the Right Host

SSH ensures you're connecting to the real server, not an imposter. The server sends its public host key during the first connection. Your SSH client prompts to verify and saves the fingerprint in ~/.ssh/known_hosts.

Example first-time connection:

ssh git@github.com
# Output (partial):
# The authenticity of host 'github.com (140.82.112.3)' can't be established.
# ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
# Are you sure you want to continue connecting (yes/no/[fingerprint])?
Enter fullscreen mode Exit fullscreen mode

On future connections, SSH checks the fingerprint. Mismatch triggers a warning (possible man-in-the-middle attack).

To manually verify fingerprints, see GitHub's list: GitHub's SSH key fingerprints.

Authenticating the Client: Proving Your Identity with Keys

Once the server is verified, you prove your identity. The server has your public key (from setup). It sends a challenge:

  1. Server generates random data.
  2. Your client signs it with your private key.
  3. Server verifies the signature using your public key.

If valid, access granted. This uses asymmetric cryptography: public key verifies what the private key signed.

No passwords if keys work. Test with:

ssh -T git@github.com
# Output: Hi username! You've successfully authenticated, but GitHub does not provide shell access.
Enter fullscreen mode Exit fullscreen mode

Failure falls back to password (see troubleshooting later).

Git's Role Over SSH: Running Remote Commands for Push and Pull

With the SSH tunnel open, Git runs commands on the remote server.

  • For push: Local Git executes git-receive-pack remotely to accept changes.
  • For pull: Local Git executes git-upload-pack remotely to send data.

Example under-the-hood view (use GIT_TRACE=1):

GIT_TRACE=1 git push origin main
# Output (partial):
# trace: run_command: ssh git@github.com "git-receive-pack 'user/repo.git'"
Enter fullscreen mode Exit fullscreen mode

Git communicates via text protocol over the tunnel, negotiating refs and objects.

Transferring Data: How Packfiles Handle Efficient Updates

Git doesn't send entire repos—it negotiates differences and uses packfiles (.pack) for compressed transfer.

Process:

  1. Sides exchange "have" and "want" lists (commits/objects).
  2. Local builds packfile with deltas.
  3. Sends over SSH.

For a simple push:

Clone a repo first:

git clone git@github.com:user/repo.git
cd repo
echo "New line" >> file.txt
git add .
git commit -m "Update"
git push
Enter fullscreen mode Exit fullscreen mode

Remote receives packfile, unpacks, updates refs.

Table of key Git objects in transfer:

Object Type Description Role in Push/Pull
Commit Snapshot with metadata Sent if new; points to trees/files
Tree Directory structure Included in packfile for changes
Blob File content Only deltas for efficiency
Packfile Compressed bundle Transferred over SSH tunnel

This keeps transfers small—even for large repos.

Handling Common Hiccups: Why You Might See a Password Prompt

If key auth fails, SSH prompts for a password. Common causes:

  • Private key not loaded: Run ssh-add ~/.ssh/id_ed25519.
  • Wrong permissions: Keys need chmod 600 ~/.ssh/id_ed25519.
  • Public key missing on server: Re-upload.
  • Config issues: Edit ~/.ssh/config for host-specific settings.

Example config file:

Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
Enter fullscreen mode Exit fullscreen mode

Test: ssh -v git@github.com (verbose mode shows auth attempts).

For debugging tips, refer to: GitHub's SSH connection troubleshooting.

Understanding these steps helps debug issues and appreciate Git's efficiency. When optimizing workflows, consider tools like SSH config for multiple accounts or agents for key management. Experiment with traces to see the protocol in action—it's a direct way to build intuition for real-world use.

Top comments (0)