How to clone a specific git commit
Clone a specific Git commit
There is no single command that enables a developer to clone a specific Git commit. In Git, developers can only clone branches, not commits.
But there is a workaround. To achieve the equivalent result of performing a git clone of a specific Git commit, follow these two steps:
- Clone the branch that contains the specific Git commit.
- Reset the state of your workspace back to that specific Git commit.
An alternative approach is to clone the repository that contains the specific Git commit, and then create a new branch from that specific commit point.
Benefits and drawbacks to each approach
The advantage of the clone-and-reset approach is that you remain on a single branch throughout the process. The downside is that pushing changes back to the original repository can cause issues, particularly when working with a shared repo.
With the clone-and-branch approach, a new branch is created. This isn’t much of a drawback, since local branches are simple to delete. If your updates need to be pushed back to the remote repository, the new branch can be merged into the original branch and then pushed without disturbing the commit history.
For that reason, the clone-and-branch method is generally the safer choice when you plan to push changes back after cloning a specific commit.
Steps to git clone a specific commit
Follow these steps to clone a specific Git commit:
- Obtain the URL of the remote repository.
- Perform a git clone of the remote repo.
- Switch to the branch that contains the commit.
- Obtain the seven-digit SHA id of the commit to clone.
- Issue a hard git reset that points to the commit id.
Specific git commit clone example
I have a GitHub repository where the third last commit on the master branch has the id of fcbd92b.
Here is the code to clone this specific Git commit:
clone-specific@commit:~$ git clone https://github.com/cameronmcnz/rock-paper-scissors.git Cloning into 'rock-paper-scissors'... remotes/origin/development
A look at the git log confirms the third commit back has the id of fcbd92b:
clone-specific@commit:~$ git log -n 5 --oneline 3ab3c6f (HEAD) Added stage to Jenkinsfile 1d1bbfc Fixed Jenkinsfile fcbd92b Update Jenkinsfile 326f527 Merge remote-tracking branch 'origin/master' 84ff492 Create rita.txt
Reset clone to specific Git commit id
To reset HEAD, the working directory and the commit history back to the specific Git commit with the id of fcbd92b, you’ll need to perform a hard git reset.
clone-specific@commit:~$ git reset --hard fcbd92b
HEAD is now at fcbd92b Update Jenkinsfile
When this command completes, the final result is equivalent to a git clone of specific commit.
Alternate Git commit id clone strategy
An alternate strategy is to follow these three steps:
- Clone the remote repository.
- Create a new branch based on the specific commit id.
- Switch to the new branch.
Commands to clone a single Git commit id
The result of running the following commands is equivalent to the clone of a single Git commit.
clone-specific@commit:~$ git clone https://github.com/cameronmcnz/rock-paper-scissors.git
Cloning into 'rock-paper-scissors'...
clone-specific@commit:~$ git branch specific-commit-branch fcbd92b
specific-commit-branch created
clone-specific@commit:~$ git switch specific-commit-branch
Switched to branch 'specific-commit-branch'
An inspection of the git log after the branch was created and checked out shows the local repository’s state points to the commit of interest:
clone-specific@commit:~$ git log --all --decorate --oneline --graph * 3ab3c6f (origin/master, origin/HEAD, master) Update Jenkinsfile * 1d1bbfc Update Jenkinsfile * fcbd92b (HEAD -> specific-commit-branch) Update Jenkinsfile
How to minimize clone depth
There are many reasons why a developer might want to clone a specific Git commit.
One of those reasons is to minimize the amount of data returned from the server. After all, a repository with a rich commit history pulls down a significant amount of data.
Shallow git clone for a specific commit id
One way to avoid deep clones is to set a clone depth. This strategy is also known as doing a shallow copy.
clone-specific@commit:~$ git clone --depth 5 https://github.com/cameronmcnz/rock-paper-scissors.git
Cloning into 'rock-paper-scissors'...
The result of issuing this command is that it pulls down only five commits.
If the specific Git commit to clone is included in this shallow copy, the reset and branch commands listed above can be performed on it.
Cameron McKenzie is an AWS Certified AI Practitioner, Machine Learning Engineer, Solutions Architect and author of many popular books in the software development and Cloud Computing space. His growing YouTube channel training devs in Java, Spring, AI and ML has well over 30,000 subscribers.