我该如何从git仓库中只检出一个文件?
我该如何从git仓库中只检出一个文件?
最初在2012年提到了git archive
(参见Jared Forsyth的answer和Robert Knight的answer),自从git1.7.9.5(2012年3月)以来,Paul Brannan的answer:
git archive --format=tar --remote=origin HEAD:path/to/directory -- filename | tar -O -xf -
但是在2013年,不再支持远程https://github.com URL的存档。
请查看旧页面"我可以存档一个仓库吗?"。
当前(2018年)页面"关于在GitHub上归档内容和数据"建议使用第三方服务,如GHTorrent或GH Archive。
所以您也可以处理本地副本/克隆:
如果您有裸仓库的本地副本,如此答案中所述,您也可以选择执行以下操作:
git --no-pager --git-dir /path/to/bar/repo.git show branch:path/to/file >file
或者你必须首先克隆仓库,这意味着你获取了完整的历史记录:
在.git仓库中
在工作树中。
但是,如果你使用Git1.7+,你可以进行稀疏检出:
git config core.sparsecheckout true
).git/info/sparse-checkout
文件中添加你想要查看的内容要重新读取工作树:
$ git read-tree -m -u HEAD
这样,你最终会得到一个工作树,其中包括你想要的精确内容(即使只有一个文件)。
Richard Gomes指出(在评论中)"如何从git仓库克隆、提取或稀疏检出单个目录或目录列表?"
一个Bash函数,避免下载历史记录,检索一个分支以及检索您需要的文件或目录列表。
从 Git 2.40(2023年第一季度)开始,通过检查稀疏模式来判断是否使用“cone”模式的逻辑已经被加强,以避免将命名单个文件的模式误认为是指定 cone 模式。
请参见 commit 5842710(由 William Sprent (williams-unity
) 于 2023 年 1 月 3 日提交)。
(由 Junio C Hamano -- gitster
-- 在 commit ab85a7d 中合并,于 2023 年 1 月 16 日)
dir
:检查单个文件 cone 模式签名作者:William Sprent
确认作者:Victoria Dye
The sparse checkout documentation states that the cone mode pattern set is limited to patterns that either recursively include directories or patterns that match all files in a directory.
In the sparse checkout file, the former manifest in the form:/A/B/C/
while the latter become a pair of patterns either in the form:
/A/B/ !/A/B/*/
or in the special case of matching the toplevel files:
/* !/*/
The '
add_pattern_to_hashsets()
' function contains checks which serve to disable cone-mode when non-cone patterns are encountered.
However, these do not catch when the pattern list attempts to match a single file or directory, e.g. a pattern in the form:/A/B/C
This causes sparse-checkout to exhibit unexpected behaviour when such a pattern is in the sparse-checkout file and cone mode is enabled.
Concretely, with the pattern like the above, sparse-checkout, in non-cone mode, will only include the directory or file located at '
/A/B/C
'.
However, with cone mode enabled, sparse-checkout will instead just manifest the toplevel files but not any file located at '/A/B/C
'.Relatedly, issues occur when supplying the same kind of filter when partial cloning with '
--filter=sparse:oid=<oid>
'.
'upload-pack
' will correctly just include the objects that match the non-cone pattern matching.
Which means that checking out the newly cloned repo with the same filter, but with cone mode enabled, fails due to missing objects.To fix these issues, add a cone mode pattern check that asserts that every pattern is either a directory match or the pattern '
/*
'.
Add a test to verify the new pattern check and modify another to reflect that non-directory patterns are caught earlier.
git archive
了。 - Jared Forsythgit show
命令可以从一个裸仓库中获取文件内容,正是我一直在寻找的。谢谢! - Gio首先使用 -n 选项克隆仓库,该选项抑制了所有文件的默认检出,并使用 --depth 1 选项,这意味着它只获取每个文件的最新修订版本。
git clone -n git://path/to/the_repo.git --depth 1
然后只需像这样检查您想要的文件:
cd the_repo
git checkout HEAD name_of_file
-n
选项后,工作树和索引将同步。也就是说,所有的内容都会显示为已删除。你需要使用git reset HEAD
或者git checkout HEAD file
命令来恢复文件。此时,如果你不真正了解git的工作原理,那么在操作这个代码库时会非常困难。 - Cascabelrm -rf .git
将清除所有克隆仓库的痕迹,或许可以缓解 Jefromi 对留下难以使用的仓库的担忧。这对我来说非常有用,可以用于多个应用,比如今天我的挑战是构建一个 post-receive 钩子来自动更新另一个 post-receive 钩子的版本。 - hobsgit
不适合这种工作)。这个答案也适用于这个问题,或者这个受欢迎的问题,以及许多其他问题:将name_of_file
改为name_of_folder
。现在(2014年),Git提供了子模块来为repo所有者提供一些友好的repo用户。 - Peter Krauss如果你已经拥有git代码库的副本,那么你可以使用git log
查找哈希ID(例如 3cdc61015724f9965575ba954c8cd4232c8b42e4)并使用以下命令检出文件的版本:
git checkout hash-id path-to-file
以下是一个实际的示例:
git checkout 3cdc61015724f9965575ba954c8cd4232c8b42e4 /var/www/css/page.css
path-to-file
是一个目录,并且当前的HEAD
包含某些文件而target
没有(或反之亦然),这将不能正确地更新文件。有没有一种处理方式? - MasterMind通常情况下,无法仅从 git
下载单个文件,而不像第一篇回答建议的那样下载整个存储库。这是因为 Git 不会像 CVS/SVN 一样存储文件,而是基于整个项目的历史记录来生成它们。
但特定情况下有一些解决方法。以下是示例,其中包含 user
、project
、branch
、filename
的占位符。
GitHub
wget https://raw.githubusercontent.com/user/project/branch/filename
GitLab
wget https://gitlab.com/user/project/raw/branch/filename
GitWeb
如果您正在使用Git on the Server - GitWeb,那么您可以尝试以下示例(将其更改为正确的路径):
wget "http://example.com/gitweb/?p=example;a=blob_plain;f=README.txt;hb=HEAD"
在drupalcode.org上的GitWeb
示例:
wget "http://drupalcode.org/project/ads.git/blob_plain/refs/heads/master:/README.md"
googlesource.com
有一个未记录的功能可以让您下载base64编码版本的原始文件:
curl "https://chromium.googlesource.com/chromium/src/net/+/master/http/transport_security_state_static.json?format=TEXT" | base64 --decode
在其他情况下,请检查您的Git代码库是否使用任何Web界面。
如果没有使用任何Web界面,您可以考虑将代码推送到外部服务,例如GitHub、Bitbucket、等等,并将其用作镜像。
如果您没有安装wget
,也可以尝试替代性地使用curl -O (url)
。
wget
答案,简单性和快乐也随之而来。谢谢你。 - pgrgit checkout 分支或版本 -- 路径/文件
示例:git checkout HEAD -- main.c
git checkout HEAD abcd.cpp
- veenus adiyodi现在我们可以了!由于这是谷歌上的第一个结果,我想将其更新至最新状态。随着 Git 1.7.9.5 的推出,我们现在可以使用 git archive
命令从远程主机检索单个文件。
git archive --remote=git://git.foo.com/project.git HEAD:path/in/repo filename | tar -x
github.com
。 - Jared ForsythHEAD
或master
而不是HEAD:directory
。 - stormbetagit archive --remote=git@bitbucket.org:user/repo branch:path/to file | tar -x
。 - Dave这里是关于如何在Git仓库中仅拉取和推送特定文件的完整解决方案:
git clone --no-checkout <git url>
git reset
git checkout origin/master <path to file>
git add <path to file>
git commit -m <message text>
git push
origin/master
:对于第三步,只需使用简单的 git checkout <文件路径>
即可。 - John我使用GIT 1.7.2.2版本。
例如,您有一个名为 some_remote 的远程仓库,其中包含分支 branch1 和 branch32。
要检出特定文件,请运行以下命令:
git checkout remote/branch path/to/file
举个例子,它会是这样的:
git checkout some_remote/branch32 conf/en/myscript.conf
git checkout some_remote/branch1 conf/fr/load.wav
假设您之前已经运行过git init,那么这个checkout命令会将整个文件结构conf/en和conf/fr复制到您调用这些命令的当前目录中。
git fetch some_remote
,是吗? - phihaggit clone --filter
从Git 2.19实际上跳过了下载额外的文件
这个选项实际上会跳过从服务器获取大部分不需要的对象。例如,要仅获取此测试存储库中的文件small/0000
:https://github.com/cirosantilli/test-git-partial-clone-big-small-no-bigtree,我们可以执行以下操作:
git clone --depth 1 --no-checkout --filter=blob:none \
https://github.com/cirosantilli/test-git-partial-clone-big-small-no-bigtree
cd test-git-partial-clone-big-small-no-bigtree
git checkout master -- small/0000
git checkout master -- small/0000 small/0001
ncdu
上的小目录大小}},我们根本没有下载这些大文件。
--filter
的格式在man git-rev-list
中有详细说明。Git远程协议已扩展以支持此功能。--depth 1 --no-checkout --filter=blob:none
时,所有文件都处于已删除/暂存状态。您需要首先运行 git reset
,如上面提到的 https://dev59.com/WHE95IYBdhLWcg3wE52C#54968394 - Martin Bagit checkout
命令因为文件被标记删除而无法创建该文件,会出现错误。如果没有添加重置,你的命令序列根本不起作用。 - Martin Ba