Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to shallow clone a specific commit with depth 1?

Is it possible to shallow clone a specific commit in a repository, i.e. with depth 1? Something like

git clone http://myrepo.git 728a4d --depth 1 

to get the repository state as it is at the commit with SHA 728a4d...?

The motivation is to avoid having to clone the whole repository, then check out that specific commit, when we're only interested in the state of the repository at that specific commit.

like image 626
Chin Avatar asked Jul 07 '15 20:07

Chin


People also ask

Can you commit with a shallow clone?

Shallow clone is very efficient for cloning only the files with no revision history. This can be beneficial for many continuous integration(CI) processes where we delete the repository at the end of the build. It can also be very useful for making quick commits into the repository.


2 Answers

Starting with Git 2.5.0 (which needs to be available at both the client and server side) you can set uploadpack.allowReachableSHA1InWant=true on the server side to enable fetching of specific SHA1s:

git init git remote add origin <url> git fetch --depth 1 origin <sha1> git checkout FETCH_HEAD 

Note that I did not find a syntax to do this with git clone directly.

like image 176
sschuberth Avatar answered Sep 22 '22 01:09

sschuberth


NOTE: My example doesn't help to clone to by a commit hash but it will help to clone a tag and have a lightweight repository.

If you have to have only one commit in your "clone" and you are going to use commit hash, short answer is NO.

I use this command construction (tested on v2.13.2.windows.1) for tags:

git clone --depth 1 [email protected]:VENDOR/REPO.git --branch 1.23.0 --single-branch 

Full example:

$ git clone --depth 1 [email protected]:Seldaek/monolog.git --branch 1.23.0 --single-branch Cloning into 'monolog'... remote: Counting objects: 201, done. remote: Compressing objects: 100% (188/188), done. remote: Total 201 (delta 42), reused 32 (delta 5), pack-reused 0 Receiving objects: 100% (201/201), 190.30 KiB | 0 bytes/s, done. Resolving deltas: 100% (42/42), done. Note: checking out 'fd8c787753b3a2ad11bc60c063cff1358a32a3b4'.  You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout.  If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example:    git checkout -b <new-branch-name>  $ cd monolog 

.git dir size (267K vs 2.6M by using full clone):

$ du -h --max-depth=0 .git 267K    .git 

I'd like to denote, --branch can take a tag/branch.

https://git-scm.com/docs/git-clone#git-clone---branchltnamegt

--branch can also take tags and detaches the HEAD at that commit in the resulting repository.

UPD

In a nutshell, it can take "refs". You may read more here: What does the git error message “Server does not allow request for unadvertised object” mean?

Also, there is no tricks like:

git fetch --depth 1 origin <COMMIT_HASH> 

Thanks @BenjiWiebe for pointing me in my mistake.

like image 23
Kirby Avatar answered Sep 22 '22 01:09

Kirby