有没有办法从远程 Git 存储库中检索特定的提交,而不必在我的计算机上克隆它?远程存储库的结构与我的完全相同,因此不会有任何冲突,但我不知道该如何做,并且我不想克隆那个庞大的存储库。
我是 Git 新手,有什么方法吗?
有没有办法从远程 Git 存储库中检索特定的提交,而不必在我的计算机上克隆它?远程存储库的结构与我的完全相同,因此不会有任何冲突,但我不知道该如何做,并且我不想克隆那个庞大的存储库。
我是 Git 新手,有什么方法吗?
从Git 2.5+(2015年第二季度)开始,实际上可以获取单个提交(而无需克隆完整仓库)。
参见 提交 68ee628 由 Fredrik Medley (moroten
) 于2015年5月21日提交。
(由 Junio C Hamano -- gitster
--在 提交a9d3493中合并,2015年6月1日)
现在你在服务器端有一个新的配置。
uploadpack.allowReachableSHA1InWant
upload-pack
接受一个获取请求,该请求要求可从任何参考端点到达的对象。但是请注意,计算对象可达性代价高昂。false
。git fetch --depth=1
) 结合使用,则可以请求单个提交(参见 t/t5516-fetch-push.sh
:git fetch --depth=1 ../testrepo/.git <full-length SHA1>
git cat-file
命令查看已获取的提交内容:git cat-file commit <full-length SHA1>
git fetch
"所使用的"git upload-pack
"可以通过uploadpack.allowReachableSHA1InWant
配置变量来服务于那些不在任何引用顶端但仍可从引用到达的提交。正如matt在评论中所指出的:请注意,SHA必须是完整的非缩写SHA,否则Git会声称找不到该提交。
当服务器端设置了
upload-pack
:可选择允许获取可达到的sha1
uploadpack.allowReachableSHA1InWant
配置选项时,"git fetch
"可以发出一个“want”行的请求,该行命名了一个未被广告(可能已经通过子模块指针或者其他方式获得)的对象。transfer.hideRefs
隐藏的分支的并集,将被处理。allowTipSHA1InWant
解决,因为每个Gerrit更改都有一个引用。)Git 2.6 (Q3 2015)将改进该模型。
请参考提交记录2bc31d1, 提交记录cc118a6(由Jeff King (peff
)于2015年7月28日提交)。
(由Junio C Hamano -- gitster
--在提交记录824a0be中合并,2015年8月19日)
refs
:支持负数transfer.hideRefs
If you hide a hierarchy of refs using the
transfer.hideRefs
config, there is no way to later override that config to "unhide" it.
This patch implements a "negative" hide which causes matches to immediately be marked as unhidden, even if another match would hide it.
We take care to apply the matches in reverse-order from how they are fed to us by the config machinery, as that lets our usual "last one wins" config precedence work (and entries in.git/config
, for example, will override/etc/gitconfig
).So you can now do:
git config --system transfer.hideRefs refs/secret git config transfer.hideRefs '!refs/secret/not-so-secret'
to hide
refs/secret
in all repos, except for one public bit in one specific repo.
Git 2.7 (2015年11月/12月) 将再次提升:
请查看提交 948bfa2,提交 00b293e(2015年11月5日),提交 78a766a,提交 92cab49,提交 92cab49,提交 92cab49(2015年11月3日),提交 00b293e,提交 00b293e(2015年11月5日)和提交 92cab49,提交 92cab49,提交 92cab49,提交 92cab49,由Lukas Fleischer (lfos
)完成。
协助者:Eric Sunshine (sunshineco
)。
(由Jeff King -- peff
--在提交 dbba85e中合并,2015年11月20日)
config.txt
:记录带有命名空间的hideRefs
的语义
目前,对于设置了命名空间时
transfer.hideRefs
应如何行为没有明确的定义。
解释在这种情况下hideRefs
前缀匹配被剥离名称的方式。这是当前在receive-pack中处理hideRefs
模式的方法。
hideRefs: 添加支持完全匹配引用的功能
除了匹配剥离的引用之外,现在可以添加
hideRefs
模式来匹配完整(未剥离)的引用。
为了区分剥离和完全匹配,这些新模式必须以插入符号(^
)作为前缀。
因此有了新文档:
transfer.hideRefs:
transfer.hiderefs
模式匹配之前,从每个引用中剥离命名空间前缀。transfer.hideRefs
中指定了refs/heads/master
,
并且当前命名空间为foo
,则refs/namespaces/foo/refs/heads/master
将被省略不在广告中,但refs/heads/master
和
refs/namespaces/bar/refs/heads/master
仍然作为所谓的“have”行进行广告。^
。如果结合使用!
和^
,则必须先指定!
。
R..提到在评论中配置uploadpack.allowAnySHA1InWant
,它允许upload-pack
接受一个请求fetch
,该请求可以获取任何对象。(默认值为false
)。
参见提交记录f8edeaa(2016年11月,Git v2.11.1),作者是David "novalis" Turner (novalis
):
在我们信任用户可以访问存储库中的所有内容的情况下进行可达性检查似乎有点愚蠢。此外,在分布式系统中,这是一种竞争条件——也许一个服务器广告了一个 ref,但另一个服务器已经对该 ref 进行了强制推送,而且也许这两个 HTTP 请求最终被定向到这些不同的服务器。
upload-pack
:可选地允许获取任何sha1
git fetch
(man)另一侧的 "git upload-pack
"(man) 在处理 want-ref 请求时忘记考虑 ref 命名空间。
查看 提交 53a66ec, 提交 3955140, 提交 bac01c6 (2021年8月13日) 由 Kim Altintop (kim
) 提交。
(由 Junio C Hamano -- gitster
-- 在 提交 1ab13eb 中合并,2021年9月10日)
请扩展
文档
: 澄清transfer.hideRefs和命名空间的交互签名:Kim Altintop
审核:Jonathan Tan
transfer.hideRefs
文档中关于命名空间的部分,以指出upload-pack
和receive-pack
之间微妙的区别。
3955140(“upload-pack.c
:将want-ref相对于命名空间处理”,2021年7月30日,Git v2.34.0 -- merge列在batch #5中)教会了upload-pack
拒绝隐藏引用的want-ref
,现在已经提到。git config
现在在其手册页面中包含:
在与
transfer.hiderefs
模式匹配之前引用。为了在剥离之前匹配引用,请在引用名称前面添加^
。如果结合使用!
和^
,则必须先指定!
。
git config
现在在其手册页面中包含:
uploadpack.allowRefInWant
,则在协议v2的fetch
命令中,upload-pack
会将want-ref refs/heads/master
视为不存在refs/namespaces/foo/refs/heads/master
。另一方面,receive-pack
仍会发布引用所指向的对象id,但不会提及其名称(所谓的“.hav
e”行)。
在Git 2.39(2022年第四季度)中, "git receive-pack
"(man) 用于检查 git push
(man) 发送的数据的连通性时,以前会使用所有本地引用作为边界,但现在它仅使用向推送者广告的引用。
在具有 .hideRefs
配置的存储库中,这减少了执行检查所需的资源。
请看提交 bcec678, 提交 5ff36c9, 提交 8c1bc2a, 提交 1e9f273, 提交 05b9425, 提交 9b67eb6, 提交 5eeb9aa (2022年11月17日),作者为Patrick Steinhardt (pks-t
)。
由Junio C Hamano -- gitster
--在提交 f8828f9中合并(2022年11月23日)。
修订版
:添加新参数以排除隐藏的引用签名作者:Patrick Steinhardt
签名作者:Taylor Blau
用户可以通过transfer.hideRefs
可选地隐藏git-upload-pack(1), git-receive-pack(1)和其他远程用户的引用,但目前还没有一种简单的方法来获取所有可见或隐藏的引用列表。
然而,为了提高连接性检查的性能,我们需要这样做。
添加一个新选项--exclude-hidden=
,它会从下一个伪引用(如--all
或--branches
)中排除任何隐藏的引用。
rev-list-options
现在包含以下内容在其手册页面中:
--exclude-hidden=[receive|uploadpack]
不要包括由
git-receive-pack
或git-upload-pack
隐藏的引用,通过查看适当的receive.hideRefs
或uploadpack.hideRefs
配置以及transfer.hideRefs
(参见git config
)。此选项影响下一个伪引用选项--all
或--glob
,并在处理它们后清除。
和:
rev-parse
: 添加 --exclude-hidden=
选项签署者: Patrick Steinhardt
签署者: Taylor Blau
添加一个新的
--exclude-hidden=
选项,与我们刚刚添加到 git-rev-list(1) 中的选项类似。
如果给定一个章节名称uploadpack
或receive
作为参数,则会导致我们排除所有受相应的$section.hideRefs
配置影响而被隐藏的引用。
git rev-parse
现在在其man页面中包含:
--exclude-hidden=[receive|uploadpack]
不包含被git-receive-pack
或者git-upload-pack
隐藏的引用,这是通过参考相应的receive.hideRefs
或者uploadpack.hideRefs
配置以及transfer.hideRefs
来实现的(请参阅git config
)。此选项会影响下一个伪引用选项--all
或--glob
,并在处理它们后被清除。
uploadpack.allowAnySHA1InWant
,就没有可达性计算惩罚(和DoS向量)了。 - R.. GitHub STOP HELPING ICE你只需要克隆一次,所以如果你已经有了远程仓库的克隆版本,从中pull不会重新下载所有内容。只需指定要pull的分支,或者获取更改并检出所需的提交。
从一个新的仓库fetch非常便宜,因为它只会下载你没有的更改。在Git中考虑做正确的事情,以最小的负载。
Git将所有内容存储在.git文件夹中。无法孤立地获取和存储提交,需要获取它的所有祖先。它们是互相关联的。
然而,为了减少下载量,你可以让 Git 只获取与特定分支或提交相关的对象:
git fetch origin refs/heads/branch:refs/remotes/origin/branch
这将仅下载远程分支 branch
包含的提交 (以及您错过的提交) 并将其存储在 origin/branch
中。然后您可以合并或检出。
您也可以指定一个 SHA1 提交 id -- 但请注意,您必须使用 完整的40个字符未缩写的 标识符:
git fetch origin 96de5297df87096de5297df87096de5297df8709:refs/remotes/origin/foo-commit
这将仅下载指定SHA-1 96de5297df87096de5297df87096de5297df8709的提交(以及您错过的其祖先),并将其存储为(不存在的)远程分支 origin/foo-commit
。
git fetch origin
只能使用 未缩写的 哈希值。在 Ubuntu 18.04 上测试过,适用于 gerrit 远程仓库。 - kubanczyk你可以使用以下命令从远程库中获取单个提交记录:
git fetch <repo> <commit-id>
其中,
<repo>
可以是远程仓库名称(例如origin
),甚至可以是远程仓库URL(例如https://git.foo.com/myrepo.git
)<commit-id>
是提交的ID例如:
git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545
在获取提交及其缺失的祖先后,您可以使用以下命令轻松切换到该提交:
git checkout FETCH_HEAD
请注意,这将使你进入“分离头”状态。
fetch
特定的版本时,git会失败并显示错误代码1和无输出。这在以前的版本中曾经有效吗?(我的版本是v2.0.2.) - Jack O'Connorgit checkout FETCH_HEAD
有所帮助。 - lzl124631x--depth=1
)一起使用! - kingmakerking我在我的git仓库上执行了一次pull操作:
git pull --rebase <repo> <branch>
允许git拉取所有分支代码,然后我去重置到我感兴趣的提交记录。
git reset --hard <commit-hash>
希望这有所帮助。
git reset --hard
的“破坏性”命令可能会使人们陷入困境,导致数据丢失(或在此情况下:处于恢复数据不易的状态)。为避免这种情况,请小心使用这些命令。 - Ry Biesemeyer您可以使用以下命令轻松获取远程存储库:
git fetch <repo>
其中,
<repo>
可以是远程仓库名称(例如origin
),甚至可以是远程仓库的URL(例如https://git.foo.com/myrepo.git
)。例如:
git fetch https://git.foo.com/myrepo.git
在获取完仓库后,您可以合并所需的提交(由于问题是检索一个提交,因此您可以使用 cherry-pick 仅选择一个提交):
git merge <commit>
<commit>
可以是SHA1提交记录例如:
git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545
或者git merge 0a071603d87e0b89738599c160583a19a6d95545
如果您想要合并的是最新的提交,您也可以使用FETCH_HEAD变量:
git cherry-pick (or merge) FETCH_HEAD
git config set uploadpack.allowReachableSHA1InWant
,对吧? - Alexander Mills这样做效果最佳:
git fetch origin specific_commit
git checkout -b temp FETCH_HEAD
名称为“temp”,可以随意更改...但此分支可能会成为孤立分支
最后我找到了使用git cherry-pick克隆特定提交的方法。假设您在本地没有任何存储库,并且要从远程拉取特定提交,
1)在本地创建空存储库并使用git init
2)git remote add origin "存储库的url"
3)git fetch origin [这不会将文件移动到本地工作区,除非您合并]
4)git cherry-pick "输入您需要的长提交哈希"
完成。这样,您只会在本地拥有来自该特定提交的文件。
您可以使用 -> git log --pretty=oneline 来获取此信息
# make sure you fetch from the origin first
$ git fetch origin
# view code at COMMIT_ID (abc123)
$ git checkout abc123
# bring only COMMIT_ID (abc123)
# to your branch
# assuming your branch is master
$ git checkout master
$ git cherry-pick abc123
# bring all changes up to
# COMMIT_ID (abc123) to your branch
# assuming your branch is master
$ git checkout master
$ git merge abc123
参考 - https://unfuddle.com/stack/tips-tricks/git-pull-specific-commit/
# 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