有没有办法只从远程Git仓库检索一个特定的提交而不在我的PC上克隆它?远程仓库的结构与我的完全相同,因此不会有任何冲突,但我不知道如何做到这一点,我不想克隆那个庞大的仓库。
我是git的新手,有什么办法吗?
答案 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 cc118a6,Jeff 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 948bfa2,commit 00b293e(2015年11月5日),commit 78a766a,commit 92cab49,commit 92cab49,commit 92cab49(2015年11月3日), commit 00b293e,commit 00b293e(2015年11月5日),commit 92cab49,commit 92cab49,commit 92cab49,commit 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
模式,以匹配完整(未剥离的)引用。
要区分剥离匹配和完全匹配,这些新模式必须以旋律为前缀(^
)。
transfer.hideRefs:
如果正在使用名称空间,则在与
transfer.hiderefs
模式匹配之前,会从每个引用中删除名称空间前缀。
例如,如果在refs/heads/master
和transfer.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.allowAnySHA1InWant
见commit 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>