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

时间:2013-02-14 10:18:08

标签: git git-fetch

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

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

10 个答案:

答案 0 :(得分:98)

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

2015年5月21日commit 68ee628旁边的Fredrik Medley (moroten) (由Junio C Hamano -- gitster --合并于commit a9d3493,2015年6月1日)

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

uploadpack.allowReachableSHA1InWant
  

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

如果将服务器端配置与浅层克隆(git fetch --depth=1)结合使用,则可以要求进行单次提交(请参阅t/t5516-fetch-push.sh

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

您可以使用git cat-file命令查看是否已提取提交:

git cat-file commit $SHA1
  

" git upload-pack"它提供了#34; git fetch"可以被告知服务   只要它们是,那些不在任何参考文件尖端的提交   可以通过uploadpack.allowReachableSHA1InWant从参考号到达   配置变量。

完整的文档是:

  

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

     

在服务器端设置uploadpack.allowReachableSHA1InWant配置选项," git fetch"可以使用"想要"用于命名尚未公布的对象的行(可能是通过带外或从子模块指针获得的)。
  只能处理从分支提示到达的对象,即transfer.hideRefs隐藏的广告分支和分支的并集。   请注意,必须返回历史记录以检查可达性是否存在相关成本。

     

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

     

有用的例子就是。

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

Git 2。6(2015年第3季度)将改进该模式 请commit 2bc31d1查看commit cc118a6Jeff King (peff)(2015年7月28日) (由Junio C Hamano -- gitster --合并于commit 824a0be,2015年8月19日)

  

refs:支持否定 transfer.hideRefs

     

如果使用transfer.hideRefs配置隐藏引用的层次结构,则无法稍后将该配置覆盖为"取消隐藏"它。
  这个补丁实现了一个"否定"隐藏哪个导致匹配立即被标记为未隐藏,即使另一个匹配会隐藏它   我们注意以相反的顺序应用匹配顺序,从配置机器给我们的方式,因为这可以让我们平常的#e;最后一个赢得"配置优先级工作(例如,.git/config中的条目将覆盖/etc/gitconfig)。

     

所以你现在可以做到:

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

隐藏refs/secret在所有回购中,除了一个公共位   在一个特定的回购中。

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

请参阅commit 948bfa2commit 00b293e(2015年11月5日),commit 78a766acommit 92cab49commit 92cab49commit 92cab49(2015年11月3日), commit 00b293ecommit 00b293e(2015年11月5日),commit 92cab49commit 92cab49commit 92cab49commit 92cab49(2015年11月3日){{3 }}。
帮助:Lukas Fleischer (lfos)
Eric Sunshine (sunshineco)合并于Jeff King -- peff --,2015年11月20日)

  

config.txt:记录带有名称空间

hideRefs的语义      

目前,transfer.hideRefs应该如何定义   在设置命名空间时表现   在这种情况下,解释hideRefs前缀与剥离的名称匹配。这就是目前hideRefs模式的方式   在receive-pack中处理。

     

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

     

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

因此commit dbba85e

transfer.hideRefs:
  

如果正在使用名称空间,则在与transfer.hiderefs模式匹配之前,会从每个引用中删除名称空间前缀。
  例如,如果在refs/heads/mastertransfer.hideRefs中指定了foo   当前命名空间为refs/namespaces/foo/refs/heads/master,然后是refs/heads/master   广告中省略了refs/namespaces/bar/refs/heads/master和。{   ^仍然被宣传为所谓的   "具有"线。
  为了在剥离前匹配引用,请在前面添加!   引用名称。如果您合并^!,则必须先指定upload-pack

new documentation提到R..配置in the comments,它允许fetch接受要求任何对象的false请求。 (默认为upload-pack)。

uploadpack.allowAnySHA1InWantcommit f8edeaa(2016年11月,Git v2.11.1):

  

{{1}}:可选择允许获取任何sha1

     

在我们的情况下进行重新检查似乎有点傻   信任用户绝对访问存储库中的所有内容。

     

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

答案 1 :(得分:93)

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

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

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


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

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

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

您也可以只指定SHA1提交:

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

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

答案 2 :(得分:59)

我拉了我的git repo:

git pull --rebase <repo> <branch>

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

git reset --hard <commit-hash>

希望这有帮助。

答案 3 :(得分:46)

您可以使用

简单地获取远程仓库的单个提交
git fetch <repo> <commit>

其中,

  • <repo>可以是远程回购名称(例如origin),甚至是远程回购网址(例如https://git.foo.com/myrepo.git
  • <commit>可以是SHA1提交

例如

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

获取提交(和缺少的祖先)之后,您只需使用

结帐即可
git checkout FETCH_HEAD

请注意,这将带您进入&#34;分离的头部&#34;状态。

答案 4 :(得分:16)

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

git fetch <repo>

其中,

  • <repo>可以是远程回购名称(例如origin),甚至是远程回购网址(例如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

答案 5 :(得分:1)

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

1)在本地和 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

答案 6 :(得分:0)

我认为&#39; git ls-remote&#39; (http://git-scm.com/docs/git-ls-remote)应该做你想做的事。没有强行取力或拉力。

答案 7 :(得分:0)

这最有效:

git fetch origin specific_commit
git checkout -b temp FETCH_HEAD

根据需要命名为“ temp” ...不过,这个分支可能被孤立了

答案 8 :(得分:0)

如果所请求的提交在远程仓库的拉取请求中,则可以通过其ID来获取它:

# Add the remote repo path, let's call it 'upstream':
git remote add upstream https://github.com/repo/project.git

# checkout the pull ID, for example ID '60':
git fetch upstream pull/60/head && git checkout FETCH_HEAD

答案 9 :(得分:0)

在一个项目中,我们遇到了问题,因此我们不得不恢复到某个提交。我们使用以下命令成功完成了此任务:

git reset --hard <commitID>