如何浅克隆深度为1的特定提交?


79

是否可以在存储库中浅克隆一个特定的提交,即深度为1?就像是

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

获取存储库状态,就像在SHA提交时一样728a4d...

这样做的目的是避免克隆整个存储库,然后在我们只对特定提交时存储库的状态感兴趣时检查该特定提交。


Answers:


76

从Git 2.5.0(需要在客户端和服务器端可用)开始,您可以uploadpack.allowReachableSHA1InWant=true在服务器端进行设置以启用特定SHA1的获取:

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

请注意,我没有找到git clone直接执行此操作的语法。


3
至少它不适用于github。我无法获取 github.com/Seldaek/monolog/commit/…git fetch --depth 1 origin d6be96bc...fatal: Couldn't find remote ref d6be96bc...
柯比

9
正确的,GitHub上只启用了allowTipSHA1InWant,但既不allowReachableSHA1InWant也没有allowAnySHA1InWant
sschuberth

2
玩这个,我发现它仅适用于非常现代的git客户端版本。甚至git 2.17都不适合我。我在2.24重建了git并成功了。
Eyal

1
工作对我来说与2.27.0.windows.1上github.com/dotnet/aspnetcore @ 62c098bc170f50feca15916e81cb7f321ffc52ff
JJS

1
这似乎现在可以在GitHub上使用了。
伏尔蒂科

23

注意:我的示例无助于通过提交哈希进行克隆,但将有助于克隆标签并具有轻量级的存储库。

如果您在“克隆”中只需要提交一次,并且要使用提交哈希,则简短答案为 NO

我将以下命令构造(在v2.13.2.windows.1测试)用于标记:

git clone --depth 1 git@github.com:VENDOR/REPO.git --branch 1.23.0 --single-branch

完整示例:

$ 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目录大小(267K2.6M使用full clone):

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

我想表示的是,--branch可以带标签/分支。

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

--branch 也可以获取标签并在结果存储库中的提交时分离HEAD。

UPD

简而言之,它可以使用“引用”。您可以在这里阅读更多:git错误消息“服务器不允许请求未发布的对象”是什么意思?

此外,没有任何技巧,例如:

git fetch --depth 1 origin <COMMIT_HASH>

感谢@BenjiWiebe指出我的错误。


2
一百万票为此。太多人认为这是不可能的。
7'7

3
--branch支持提交,只有分行的名字......这完全不解决这个问题。事实并非如此。
abourget

1
柯比(Kirby)我现在正在尝试执行此操作,它不适用于commits,如@abourget所说。也许它适用于标签和分支,但是我正在尝试使用提交散列来实现,但这是行不通的。
BenjiWiebe

@BenjiWiebe,我明白了你的意思。是的,看来,GIT无法确定特定的提交。:-/我会深入研究。
柯比

@BenjiWiebe,因此,很遗憾,无法使用提交哈希。只是仔细检查。
柯比

6

直接的答案是:你不能。
为什么?可以在这里找到详细的解释:为什么没有Git克隆特定的提交选项?

你还能做什么?

如何将存储库克隆到特定提交?(完整克隆)

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

更多信息:

如何克隆单个分支?

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

如何从给定分支仅克隆最新提交?

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

如何浅克隆深度为1的特定提交?

正如@sschuberth所评论的:--depth暗含--single-branch

代替克隆使用fetch命令:

# 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>

4
这不能回答问题。发问者想知道如何检出单个提交,即使没有引用直接指向它。
约瑟夫·斯特劳斯

抱歉,错过了,我以某种方式了解他需要最新的提交。更新答案。谢谢
CodeWizard

--depth意味着--single-branch,因此您可以在这种情况下将其删除。
sschuberth '16

是否git fetch真正接受的SHA1 refspec
Phil Frost

不。它只是“下载”与分支名称匹配的数据
CodeWizard

5

尝试while在bash中使用:

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

这很慢,因为它会分别获取每个提交。您可以增加增量(以批量获取提交并提高网络性能),但这仍然是蛮力方法。


为什么要下票?...我实际上需要这样做,我的解决方案就完成了!
科林

如果您想要几年前提交的承诺或者已经不存在的承诺怎么办?
达恩·巴克

@DaanBakker,如果提交不再存在,那么确定该提交的唯一方法是获取整个远程存储库,如果它不存在并且没有其他克隆,那么很遗憾,您将陷入困境。
科林
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.