git fetch - 从远程Git存储库中检索特定提交

有没有办法只从远程Git仓库检索一个特定的提交而不在我的PC上克隆它? 远程仓库的结构与我的结构完全相同,因此不会有任何冲突,但我不知道如何做到这一点,我不想克隆那个庞大的存储库。

我是git的新手,有什么办法吗?

Varun Chitre asked 2019-04-21T14:57:49Z
7个解决方案
92 votes

您只能克隆一次,因此如果您已经拥有远程存储库的克隆,则从中删除它将不会再次下载所有内容。 只需指出要提取的分支,或者获取更改并签出所需的提交。

从新存储库中获取带宽非常便宜,因为它只会下载您没有的更改。 考虑到Git以最小的负载做出正确的事情。

Git将所有内容存储在origin/foo-commit文件夹中。 提交不能被孤立地提取和存储,它需要它的所有祖先。 它们是相互关联的。


但是,为了减少下载大小,您可以要求git仅获取与特定分支或提交相关的对象:

git fetch origin refs/heads/branch:refs/remotes/origin/branch

这将仅下载远程分支origin/foo-commit中包含的提交(并且仅包含您错过的提交),并将其存储在origin/branch中。然后您可以合并或签出。

您还可以仅指定SHA1提交:

git fetch origin 96de5297df870:refs/remotes/origin/foo-commit

这将仅下载指定的SHA-1 96de5297df870(及其遗漏的祖先)的提交,并将其存储为(不存在的)远程分支origin/foo-commit

CharlesB answered 2019-04-21T15:06:24Z
91 votes

从Git版本2.5+开始(2015年第2季度),实际上可以获取单个提交(不克隆完整的回购)。

见Fredrik Medley的提交68ee628(upload-pack),2015年5月21日。
(Junio C Hamano合并 - upload-pack - 提交a9d3493,2015年6月1日)

你现在有了一个新的配置(在服务器端)

uploadpack.allowReachableSHA1InWant

允许upload-pack接受获取请求,该请求请求可从任何ref tip访问的对象。 但是,请注意,计算对象可达性在计算上是昂贵的。
默认为upload-pack

如果将服务器端配置与浅层克隆(upload-pack)结合使用,则可以请求单个提交(请参阅upload-pack

git fetch --depth=1 ../testrepo/.git $SHA1

您可以使用upload-pack命令查看已提取提交:

git cat-file commit $SHA1

服务“fetch”的“upload-pack”可以告知服务   只要它们是,那些不在任何参考文件尖端的提交   可以从ref到达,false   配置变量。


完整的文档是:

upload-pack:可选择允许获取可达的sha1

在服务器端设置了upload-pack配置选项后,“fetch”可以使用“want”行发出请求,该行命名一个尚未通告的对象(可能是在带外或从子模块指针获得的)。
只处理从分支提示可到达的对象,即由false隐藏的广告分支和分支的并集。
请注意,必须返回历史记录以检查可达性的相关成本。

获取某个提交的内容时可以使用此功能,   sha1是已知的,无需克隆整体   存储库,尤其是在使用浅提取时。

有用的案例是例如

  • 包含历史记录中的大文件的存储库,
  • 仅获取子模块结帐所需的数据,
  • 当共享一个sha1而不告诉它属于哪个精确的分支时,如果你在提交而不是改变数字的情况下考虑。
    (Gerrit案例已经通过upload-pack解决,因为每个Gerrit更改都有一个参考号。)

Git 2.6(2015年第3季度)将改进该模型。
请参阅提交2bc31d1,提交cc118a6(2015年7月28日)作者:Jeff King(upload-pack)。
(由Junio C Hamano合并 - upload-pack - 在提交824a0be,2015年8月19日)

upload-pack:支持负面fetch

如果使用upload-pack配置隐藏refs的层次结构,则无法稍后覆盖该配置以“取消隐藏”它。
这个补丁实现了一个“否定”隐藏,使得匹配立即被标记为未隐藏,即使另一个匹配会隐藏它。
我们注意以相反的顺序应用匹配顺序,从配置机制将它们传送给我们,因为这样可以让我们通常的“最后一个获胜”配置优先工作(例如,fetch中的条目将覆盖false)。

所以你现在可以这样做:

git config --system transfer.hideRefs refs/secret
git config transfer.hideRefs '!refs/secret/not-so-secret'

在所有回购中隐藏upload-pack,除了一个公共位   在一个特定的回购。


Git 2.7(2015年11月/ 12月)将再次改善:

请参阅commit 948bfa2,commit 00b293e(2015年11月5日),commit 78a766a,commit 92cab49,commit 92cab49,commit 92cab49(2015年11月3日),commit 00b293e,commit 00b293e(2015年11月5日),并提交92cab49,commit 92cab49,commit 92cab49, 由Lukas Fleischer(upload-pack)提交92cab49(2015年11月3日)。
帮助:Eric Sunshine(upload-pack)。
(由Jeff King合并 - upload-pack - 在提交dbba85e,2015年11月20日)

upload-pack:使用名称空间记录fetch的语义

目前,还没有明确的定义如何upload-pack   在设置命名空间时表现。
在这种情况下,解释fetch前缀匹配剥离的名称。 这就是目前false模式的方式   在receive-pack中处理。

hideRefs:添加对匹配完整引用的支持

除了匹配剥离的引用之外,现在可以添加upload-pack模式,以匹配完整(未剥离的)ref。
要区分剥离匹配和完全匹配,这些新模式必须以旋律为前缀(fetch)。

因此新的文件:

transfer.hideRefs:

如果正在使用名称空间,则在与upload-pack模式匹配之前,将从每个引用中去除名称空间前缀。
例如,如果在false中指定了fetch并且   当前命名空间是foo,然后是refs/namespaces/foo/refs/heads/master   在广告中省略但是refs/heads/master和   refs/namespaces/bar/refs/heads/master仍然被宣传为所谓的   “有”线。
为了在剥离前匹配refs,请在前面添加^   引用名称。 如果组合!^,则必须首先指定!


R ..在评论中提到配置upload-pack,它允许upload-pack接受要求任何对象的fetch请求。 (默认为false)。

请参阅David“novalis”Turner(upload-pack)提交f8edeaa(2016年11月,Git v2.11.1):

upload-pack:可选择允许获取任何sha1

在我们信任用户完全访问存储库中的所有内容的情况下,进行可访问性检查似乎有点愚蠢。

此外,它在分布式系统中很活跃 - 也许是一台服务器   广告一个参考,但另一个已经有一个力量推动该参考,   也许这两个HTTP请求最终会针对这些不同的  服务器。

VonC answered 2019-04-21T15:04:52Z
59 votes

我对我的git repo做了一个拉动:

git pull --rebase <repo> <branch>

允许git拉入分支的所有代码然后我去重置到我感兴趣的提交。

git reset --hard <commit-hash>

希望这可以帮助。

Piu Sharma answered 2019-04-21T15:07:19Z
46 votes

您只需使用即可获取远程仓库的单个提交

git fetch <repo> <commit>

哪里,

  • <commit>可以是远程仓库名称(例如origin)或甚至是远程仓库URL(例如https://git.foo.com/myrepo.git
  • <commit>可以是SHA1提交

例如

git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545

在您获取提交(和缺少的祖先)之后,您只需将其签出即可

git checkout FETCH_HEAD

请注意,这将使您处于“独立头”状态。

Flow answered 2019-04-21T15:08:40Z
14 votes

您只需使用以下命令获取远程仓库即可:

git fetch <repo>

哪里,

  • <commit>可以是远程仓库名称(例如origin)或甚至是远程仓库URL(例如https://git.foo.com/myrepo.git

例如:

git fetch https://git.foo.com/myrepo.git 

在您获取了repos后,您可以合并您想要的提交(因为问题是关于检索一个提交,而是合并您可以使用cherry-pick来选择一个提交):

git merge <commit>
  • <commit>可以是SHA1提交

例如:

git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545

要么

git merge 0a071603d87e0b89738599c160583a19a6d95545

如果是要合并的最新提交,您还可以使用FETCH_HEAD变量:

git cherry-pick (or merge) FETCH_HEAD
Sérgio answered 2019-04-21T15:10:17Z
1 votes

我认为'git ls-remote'([http://git-scm.com/docs/git-ls-remote])应该做你想要的。 没有强行取力或拉力。

Hubbitus answered 2019-04-21T15:10:57Z
1 votes

最后,我找到了一种使用git cherry-pick克隆特定提交的方法。假设您在本地没有任何存储库,并且您从远程提取特定提交,

1)在local和git init中创建空存储库

2)git remote add origin“url-of-repository”

3)git fetch origin [除非你合并,否则不会将文件移动到本地工作区]

4)git cherry-pick“Enter-long-commit-hash-that-you-need”

完成。这样,您将只拥有本地特定提交的文件。

进入长提交哈希:

你可以使用 - &gt; git log --pretty = oneline

surya deepak answered 2019-04-21T15:12:42Z
translate from https://stackoverflow.com:/questions/14872486/retrieve-specific-commit-from-a-remote-git-repository