How do you clone a repository and what happens internally when you clone?
Quick Answer
git clone copies a remote repository to your local machine, creating a new directory with the full project history, all branches as remote-tracking references, and a checkout of the default branch. It also automatically configures 'origin' as the remote pointing to the source URL.
Detailed Answer
Think of cloning like photocopying an entire filing cabinet. You don't just get the latest documents. You get every document ever filed, every folder label, and a complete index. Your photocopy is entirely independent: you can add, remove, and rearrange documents in your copy without affecting the original filing cabinet. The only connection is a sticky note reminding you where the original cabinet is (the 'origin' remote).
The git clone command creates a local copy of a remote Git repository. It performs several operations in sequence: it creates a new directory named after the repository, initializes a .git directory inside it, adds the source URL as a remote called 'origin', fetches all objects (commits, trees, blobs, tags) from the remote, creates remote-tracking branches for each remote branch, and checks out the default branch (usually main or master) into the working directory. The result is a fully functional repository with complete history.
Internally, the clone process involves network protocol negotiation. Git supports several transport protocols: HTTPS (most common), SSH (preferred for authenticated access), Git protocol (fast but no authentication), and local file paths. During the fetch phase, Git uses a packfile protocol where the server and client negotiate which objects the client needs. Since a fresh clone has no objects, the server sends everything as a compressed packfile (.pack file with a .idx index). These are stored in .git/objects/pack/. For large repositories, this initial transfer can be significant: the Linux kernel repository is over 4 GB.
In production, clone operations matter more than you might think. CI/CD pipelines clone repositories on every build, and for large repositories, this can become a bottleneck. Shallow clones (git clone --depth 1) fetch only the latest commit and its tree, dramatically reducing transfer size and time. GitHub Actions uses this approach by default with actions/checkout. Partial clones (git clone --filter=blob:none) skip downloading large blobs until they're needed, which is useful for monorepos with large assets. Mirror clones (git clone --mirror) create a bare repository that's an exact copy of the remote, used for backup servers and migration scenarios.
A common gotcha: cloning via HTTPS may prompt for credentials on every push, while SSH uses key-based authentication for a smoother experience. Many developers start with HTTPS and later switch to SSH using git remote set-url. Another trap: cloning a large repository with binary files (game assets, ML models) can be extremely slow. Such repositories should use Git LFS (Large File Storage) to keep binary files out of the main object database. Also, the default branch name after cloning depends on the remote's configuration, not local settings, so don't assume it will always be 'main'.