Data report"State of code review 2024" is now liveRead the full report

How to clone a specific commit using git

Greg Foster
Greg Foster
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


Cloning a specific commit in Git allows you to start your repository from the exact state of a project at a particular point in time. This guide explains how to clone a specific commit from a Git repository.

Stop wrestling with Git commands

The Graphite CLI takes all the pain out of Git, allowing you to ship faster and stop Googling Git commands.

Learn more

In order to understand how to clone a specific commit, it's helpful to understand how Git stores commits, and what it actually means to "clone" an object in Git.

  • Commit hash: A unique identifier for a commit. It's a long string created by the SHA-1 hashing algorithm, representing the state of a repository at the time of the commit.
  • Clone: To clone a repository means to make a complete local copy of that repository, including all the history, branches, tags, and commits.

To clone a specific commit, you first need to clone the repository as you would normally. Navigate to the directory where you want the copy repository to reside, then run:

Terminal
git clone <repository-url>

Replace <repository-url> with the URL of the Git repository. This command clones the repository to your local machine but checks out the main branch by default.

For a more detailed guide on the different methods of cloning (ssh/https) see this guide on Git cloning.

After cloning the repository, navigate into the directory:

Terminal
cd <repository-name>

To check out a specific commit, you need the commit hash. If you already know the commit hash, you can proceed to the next step. If not, you can list all of the commits with:

Terminal
git log --oneline

The commit hashes will be the string of 13 characters preceding each commit.

This will display a shortened list of commits. Locate the commit you are interested in and note its hash. To check out this specific commit, use:

Terminal
git checkout <commit-hash>

Replace <commit-hash> with the actual commit hash. This command points your working directory to the state of the repository at that commit, effectively detaching your HEAD (the pointer to the current commit) from the branch history.

The best engineers use Graphite to simplify Git

Engineers at Vercel, Snowflake & The Browser Company are shipping faster and staying unblocked with Graphite.

Git started for free
  • Detached HEAD state: Checking out a specific commit puts your repository in a "detached HEAD" state. In this state, any new commits you make will be orphaned when you switch back to a branch, unless you create a new branch starting from the detached HEAD.

  • Creating a New Branch: If you plan to make changes starting from this specific commit, it's a good idea to create a new branch:

    Terminal
    git checkout -b <new-branch-name> <commit-hash>

    This command creates a new branch named <new-branch-name> starting from <commit-hash>.

  • Fetching a specific commit without cloning: If you only need to fetch a specific commit without cloning the entire repository, you can use sparse-checkout:

    Terminal
    mkdir <repo-name>
    cd <repo-name>
    git init
    git remote add origin <repository-url>
    git fetch origin <commit-hash>
    git checkout FETCH_HEAD
    1. mkdir <repo-name>

      • This command creates a new directory with the name <repo-name>. This directory will serve as a local repository.
      • Example: mkdir myproject
    2. cd <repo-name>

      • This changes the current working directory to the newly created directory.
      • Example: cd myproject
    3. git init

      • This initializes a new Git repository in the current directory. This sets up all the necessary Git files and structures needed to begin tracking files and commits in the repository.
    4. git remote add origin <repository-url>

      • This command adds a new remote to your local Git repository. origin is a conventional name used for the primary or original repository. <repository-url> should be replaced with the URL of the Git repository from which you want to fetch data.
      • Example: git remote add origin https://github.com/user/repo.git
    5. git fetch origin <commit-hash>

      • This command retrieves the commit specified by <commit-hash> from the remote repository linked as origin. This does not fetch the entire branch or tags, just the specific commit and the history necessary to reach it.
      • Example: git fetch origin a1b2c3d4e5f6
    6. git checkout FETCH_HEAD

      • After fetching, FETCH_HEAD refers to the last fetched branch or commit from a remote repository. This command checks out the state of the repository at the fetched commit, putting the working directory in that state. You will be in a 'detached HEAD' state at this commit, meaning you're not working on any particular branch. For a more detailed guide on the 'detached HEAD state', including how to get out of it, see this guide on resolving a detached head state.

    This method is particularly useful in scenarios where bandwidth or storage is limited. It allows you to access a specific part of a repository, such as a particular commit, without downloading the history associated with other parts of the project.

  • Downloading files from a specific commit: To download specific files from a commit without checking out, run:

    Terminal
    git fetch origin
    git checkout origin/<branch-name> -- <file-path>

This fetches updates from the original repository and then checks out specific files from a particular branch at their state in the most recent commit.

For futher reading on cloning in Git, see the official documentation.

Stay unblocked. Ship faster.
Experience the new developer workflow - create, review, and merge code continuously. Get started with one command.
Learn more

Give your PR workflow
an upgrade today

Stack easier | Ship smaller | Review quicker

Or install our CLI.
Product Screenshot 1
Product Screenshot 2