How to shallow clone a specific commit with depth 1?

不问归期 提交于 2019-11-27 11:26:04

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.

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 git@github.com:VENDOR/REPO.git --branch 1.23.0 --single-branch

1.23.0 - it can be either a commit hash or a branch.

Full example:

$ git clone --depth 1 git@github.com: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.

CodeWizard

The immediate answer is: You cant.
Why? detailed explain can be found here: Why Isn't There A Git Clone Specific Commit Option?

What else can you do?

How to clone repository to a specific commit? (full clone)

# Create empty repository to store your content
git clone <url>
git reset <sha-1> --hard

More info:

How to clone single branch?

git clone <url> --branch <branch_name> --single-branch <folder_name>

How to clone only latest commit from a given branch?

git clone <url> --depth=1 --branch <branch_name> --single-branch <folder_name>

How to shallow clone a specific commit with depth 1?

As @sschuberth commented out: --depth implies --single-branch.

Instead of clone use the fetch command:

# fetch a commit (or branch or tag) of interest
# In this case you will have the full history of this commit
git fetch origin <sha1>

Try using while in bash:

git clone --depth=1 $url
i=1; while ! git show $sha1; do git fetch --depth=$((i+=1)); done

This is pretty slow because it fetches each commit individually; you could increase the increment (to fetch commits in batches and improve performance over a network) but it's still a brute force approach.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!