从代码库中检索单个文件

286

从远程git仓库获取单个文件的最有效机制是什么(就数据传输和磁盘空间使用而言)?

到目前为止,我想到的方法如下:

git clone --no-checkout --depth 1 git@github.com:foo/bar.git && cd bar && git show HEAD:path/to/file.txt

这仍然似乎有些过度。

从存储库中获取多个文件怎么样?


3
好的,我会尽力进行翻译。以下是需要翻译的内容:Aaw. I would love it if there was a built in way to do the equivalent of "cat-remote" and "tag-remote".啊。如果有一种内置的方法可以执行“cat-remote”和“tag-remote”的等效操作,那就太好了。 - conny
3
我有同样的问题,我想在两个代码库中使用相同的许可证文件;在一个代码库中编辑该文件,然后自动更新另一个代码库中的副本。 - GlassGhost
可能是如何从git仓库中仅检出一个文件?的重复问题。 - Ciro Santilli OurBigBook.com
24个回答

179

在Git版本1.7.9.5中,似乎可以使用以下方法从远程仓库中导出单个文件

git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar xO

这将会显示文件README.md的内容。


39
除了在 GitHub 上无法使用外,它并不起作用。 真可惜。 :( https://twitter.com/GitHubHelp/status/322818593748303873 - Rob Howard
17
似乎这不会生成原始文件,而是一个只包含单个文件的tar文件。 - Frerich Raabe
22
请给命令添加 | tar -x。 新的命令为:git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -x 另外需要翻译的内容是:cat README.md - renier
14
您可以使用tar -xO将输出定向到标准输出流,以便进行管道操作。例如:FILE=README.md && git archive --remote=ssh://host/pathto/repo.git HEAD "$FILE" | tar -xO "$FILE" - paulcm
4
正是我在寻找的答案,但是当我用 Git 命令时却得到了 "fatal: Operation not supported by protocol." 的错误响应。唉。 - mhvelplund
显示剩余11条评论

85

在跟进Jakub答案后,需要通过管道将git archive的输出传递给tar以获取文件内容:

git archive --remote=git://git.foo.com/project.git HEAD:path/to/directory filename | tar -x

将远程仓库HEAD版本的'filename'文件保存到当前目录。

:path/to/directory 部分是可选的。如果省略,则获取的文件将保存在 <current working dir>/path/to/directory/filename

此外,如果您想要在由git-daemon托管的Git仓库上启用git archive --remote使用,请启用daemon.uploadarch配置选项。参见https://kernel.org/pub/software/scm/git/docs/git-daemon.html


4
如果这是一个文本文件,我们想要将其保存到另一个地方,最好使用以下命令:| tar -xO > ~/destfile.ext - yucer
它能与特定的提交一起工作吗?(即指定特定文件和提交) - Alleo
1
是的。将“HEAD”替换为您想要使用的提交ID。“HEAD”是一个别名,它指向当前检出的提交(如果适用)或默认分支的末尾。我几年前写了上面的答案,并在今天早上得知GitHub不支持“git archive”,因此它变得不那么有用了。 - Robert Knight
1
对我来说,这似乎是最佳答案。在 tar -x 中添加 v 作为另一个选项不会有影响。 此外,值得注意的是,它也适用于特定文件夹,而不仅仅是单个文件: git archive --remote=git://git.foo.com/project.git HEAD path/to/folder/ | tar -xv - M-Jack
致命错误:协议不支持该操作 - gerrit

47
如果有已部署的Web界面(例如gitweb、cgit、Gitorious、ginatra),您可以使用它来下载单个文件('raw'或'plain'视图)。
如果对方启用了它,您可以使用git archive的'--remote=<URL>'选项(可能限制为给定文件所在的目录),例如:
$ git archive --remote=git@github.com:foo/bar.git --prefix=path/to/ HEAD:path/to/ |  tar xvf -

7
如果使用git-daemon(git://格式的URL)上传归档文件到您自己的存储库,您需要在远程存储库上使用git config daemon.uploadarch true命令来启用"upload-archive"。默认情况下,git-daemon禁用远程归档功能,并显示“fatal: remote error: access denied or repository not exported: …”错误信息。 - patthoyts
+1 git archive 方法是我第一次尝试的 - 但后来我注意到,在客户机上需要 tar 不太方便 Windows 用户。我们最终从本地的 cgit 服务器获取。它可以工作,但速度不如我所希望的快(并且仍然需要在 Windows 机器上运行 unix2dos 或类似程序,因为我们在 Git 存储库中存储具有 Unix 行结尾的文件)。 - Frerich Raabe
有没有一个GUI可以浏览远程Git,并且您可以在后台自动设置此“git archive…”命令,以便直接在GUI中查看单个文件? - rubo77
1
@FrerichRaabe 使用 -o fetched.zip。另外请参考 --format=<fmt> 选项。 - akhan
5
就目前情况而言,似乎这种方法无法用于 GitHub 托管的代码库。请参阅 https://help.github.com/articles/can-i-archive-a-repository 和 https://groups.google.com/forum/#!topic/github/z8vLHcX0HxY。 - vmrob
显示剩余2条评论

44

一般情况下不适用,但如果您正在使用Github:

对我来说,使用wget下载特定文件是最好、最简单的方法。

在浏览器中打开该文件并点击“Raw”按钮。现在刷新您的浏览器,复制URL并对其进行wgetcurl操作。

wget 示例:

wget 'https://github.abc.abc.com/raw/abc/folder1/master/folder2/myfile.py?token=DDDDnkl92Kw8829jhXXoxBaVJIYW-h7zks5Vy9I-wA%3D%3D' -O myfile.py

Curl示例:

curl 'https://example.com/raw.txt' > savedFile.txt

5
这是最简单的解决方案,适用于任何人可以找到的原始文本文件。curl https://example.com/raw.txt > savedFile.txt - JacobPariseau
wget 的示例无法工作,但 curl 的示例可以。 - Kyle Baker
对我而言运行得很好。你在命令行中是否将URL放在引号中? - Ankur Agarwal
这不会保留 Git 历史记录。 - crypdick
2
该解决方案要求使用Git,答案支持Github是git,但与git无关。它基于一家知名的Git解决方案提供商提供的额外API! - Ravinder Payal
如果您需要从Github获取原始文件内容,只需使用此URL运行curl,例如: curl 'https://raw.githubusercontent.com/SoliDry/api-generator/master/tests/functional/oas/openapi.yaml' > openapi_test.yaml 它也可以通过UI按钮“raw”轻松访问。 - Arthur Kushman

17

从远程导出单个文件:

git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -x

这将下载文件README.md到您当前的目录。

如果您想将文件内容导出为STDOUT:

git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -xO
您可以在命令的结尾提供多个路径。

10

如果其他回答都不适用(即受限的GitLab访问),您可以通过“selective-checkout”进行选择性检出:

  1. git clone --no-checkout --depth=1 --no-tags URL
  2. git restore --staged DIR-OR-FILE
  3. git checkout DIR-OR-FILE

虽然这种解决方案完全符合Git规范,而且可以检出目录,但与对文件进行wget/curl相比,它在磁盘和网络方面不够优化。


经过快速测试,看起来这是GitHub、GitLab和Forgejo的正确答案。 - undefined

8

我是这样解决的:


git archive --remote=ssh://git@gitlab.com/user/mi-repo.git BranchName /path-to-file/file_name | tar -xO /path-to-file/file_name > /path-to-save-the-file/file_name

如果您想的话,可以用“HEAD”替换“BranchName”。

8

请注意,'HEAD'和'4'之间不是'减号' '-',而是'波浪线' '~'。显然我没有好好阅读git文档,或者我的眼镜需要更新;-) - Dennis
23
这似乎无法从远程代码库获取文件,就像原帖中所需的那样。 - Mike Weller
如果文件不在您的根目录中,请使用以下命令:git show HEAD:./my_other_file > local_file - kenorb
或者:git show refs/remotes/my_remote/master:./my_file,其中refs路径是通过git show-ref获取的正确远程路径。 - kenorb
1
亲切请求所有的投票者 - 请解释和澄清哪里不对 - 我们在这里是为了学习和分享 :) - Mars Robertson
10
Mike Weller已经说得很清楚了,这段代码不能用于远程仓库。至少需要本地克隆一个仓库,即使你在它上面设置了远程仓库。 - Rob Howard

7
这里有一个更为细致的答案,回答了提问者的问题:
git archive --remote=git@archive-accepting-git-server.com:foo/bar.git \
  HEAD path/to/file.txt | tar -xO path/to/file.txt > file.txt

这不起作用,github不支持git存档。 - Philipp
3
哦,Git 的用途不仅限于 GitHub。 - Willem van Ketwich
2
你在回答中明确将 --remote 设置为 github URL 了,哈哈。 - Philipp
1
感谢您的反馈。已经相应地修改了答案。 - Willem van Ketwich

6

我使用这个

$ cat ~/.wgetrc
check_certificate = off

$ wget https://raw.github.com/jquery/jquery/master/grunt.js
HTTP request sent, awaiting response... 200 OK
Length: 11339 (11K) [text/plain]
Saving to: `grunt.js'

即使没有进行wgetrc调整,这对我也有效:wget https://raw.github.com/bk322/bk_automates/master/bkubuntu/bkubuntu.bash - Adobe
1
我的信息更有帮助:错误:raw.github.com的证书验证错误:无法获取本地颁发者证书。 要不安全地连接到raw.github.com,请使用“--no-check-certificate”。 - Kos
4
这仅适用于公共存储库。对于私有存储库,您需要进行身份验证。 - rikas
Mac没有wget,所以我使用了curl,但是我不得不使用curl -H 'Cache-Control: no-cache, no-store' https://raw.githubusercontent.com/org/repo/master/file > outfile,否则如果文件已经被下载,它就不会下载。 - Arundale Ramanathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接