如何在Git仓库中只稀疏地检出单个文件?

598

我该如何从git仓库中只检出一个文件?


10
"check out"是什么意思?是从远程代码库获取单个文件的副本吗? - Cascabel
2
如果相关的仓库正在使用gitweb,您可以直接从那里下载文件。正如我下面所解释的,您所要求的并不是标准的git操作。 - Cascabel
你可以使用Chrome扩展程序GitHub Mate,它使你能够点击文件图标来下载它。 - Cam Song
可能是从存储库检索单个文件的重复问题。 - Jacek Krysztofik
显示剩余4条评论
27个回答

16

非常简单:

git checkout from-branch-name -- path/to/the/file/you/want

这将不会检出from-branch-name分支。你会留在当前所在的分支,只有指定分支中的单个文件将被检出。

以下是git-checkout命令手册的相关部分:

git checkout [-p|--patch] [<tree-ish>] [--] <pathspec>...
       When <paths> or --patch are given, git checkout does not switch
       branches. It updates the named paths in the working tree from the
       index file or from a named <tree-ish> (most often a commit). In
       this case, the -b and --track options are meaningless and giving
       either of them results in an error. The <tree-ish> argument can be
       used to specify a specific tree-ish (i.e. commit, tag or tree) to
       update the index for the given paths before updating the working
       tree.

感谢 Ariejan de Vroom 从这篇博客文章中教会我这个技巧。


4
不错,只是你需要先克隆才行。 - Antoniossss

8

已有的两种变体:

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

并且:

git archive --format=zip --remote=git://git.foo.com/project.git HEAD:path/to/directory filename | funzip

这些语句将文件写入标准输出。


8

您可以通过以下方式实现:

git archive --format=tar --remote=origin HEAD | tar xf -
git archive --format=tar --remote=origin HEAD <file> | tar xf -

7

假设文件名为123.txt,以下方式适用于我:

git checkout --theirs  123.txt

如果文件在目录A中,请确保正确指定:
git checkout --theirs  "A/123.txt"

5
在Git中,您不需要在更新文件之前“checkout”文件 - 看起来这正是您想要的。
许多系统(如clearcase、csv等)要求您在对其进行更改之前“checkout”文件。但Git不需要这样做。您可以克隆存储库,然后在本地副本中进行更改。
一旦您更新了文件,您可以执行以下操作:
git status

为了查看哪些文件已被修改,你需要先将需要提交的文件添加到 index 中(index 就像一个待核对的列表):
git add .

或者

git add blah.c

接下来执行 git status 将会显示哪些文件被修改了,哪些处于 index 状态可以被提交或者检查。

将文件提交到您的代码库,请执行:

git commit -a -m "commit message here"

请访问git网站获取相关手册和指南。


1
如果你的目标是修补这个单一文件并将其提交回去,你需要推送(但可能你没有推送此项目的权限?)或使用 git format-patch 创建一个用于提交的补丁(git format-patch -1 将为你最近的提交创建一个补丁)。 - Cascabel
谢谢,这是一个很好的解释,从Clearcase转向Git。 - Kellen Stuart

3
这对我很有用。使用一些shell命令来使用git。
git clone --no-checkout --depth 1 git.example.com/project.git && cd project && git show HEAD:path/to/file_you_need > ../file_you_need && cd .. && rm -rf project

1
请将代码以正确的格式放置,例如 git clone --no-checkout --depth 1 git.example.com/project.git && cd project && git show HEAD:path/to/file_you_need > ../file_you_need && cd .. && rm -rf project,尝试在放置代码时使用 Ctrl+K。 - Vicky Dev

3
如果您需要从远程Git仓库中的特定分支获取特定文件,则命令如下:

git archive --remote=git://git.example.com/project.git refs/heads/mybranch path/to/myfile |tar xf -

其余内容可以参考@VonC的回答:
如果你需要从主分支获取特定文件,则为:
git archive --remote=git://git.example.com/project.git HEAD path/to/myfile |tar xf -

如果您需要从标签中获取特定文件,则为:
git archive --remote=git://git.example.com/project.git mytag path/to/myfile |tar xf -

母公司决定禁止自动化的HTTP/S访问!这种技术使我能够自动获取存储库中的单个文件,而无需检出整个存储库。谢谢和赞扬! - JS.

2
另一种解决方案,类似于使用 --filter=blob:none 的方法,是使用 --filter=tree:0(你可以在 这里 阅读有关差异的说明)。
这种方法通常比使用 blob 更快,因为它不会下载树形结构,但是它也有一个缺点。由于你延迟了树的检索,当你进入仓库目录时会受到惩罚(取决于你的仓库大小和结构,与简单的浅克隆相比可能会大几倍)。
如果你遇到这种情况,你可以通过不进入仓库来解决问题:
git clone -n --filter=tree:0 <repo_url> tgt_dir
git -C tgt_dir checkout <branch> -- <filename>
cat tgt_dir/<filename> # or move it to another place and delete tgt_dir ;)

请注意,如果您需要检出多个文件,则树的大小也会影响性能,因此我建议仅针对单个文件,并且仓库足够大才值得执行这些操作。

我不确定为什么tree:0blob:none在检出时似乎会下载不必要的树对象。测试仓库:https://github.com/cirosantilli/test-git-partial-clone-big-small,其中包含`big_tree`下的一些巨大树。如果您找到解决方案,请告诉我。 - Ciro Santilli OurBigBook.com

1
如果您有一个本地更改的文件(那个会干扰git pull的文件),只需执行以下操作:
git checkout origin/master filename
  1. git checkout - 切换分支或恢复工作树文件,(这里我们不切换任何东西,只是覆盖文件)
  2. origin/master - 您当前的分支,或者您可以使用特定的 revision-number,例如:cd0fa799c582e94e59e5b21e872f5ffe2ad0154b
  3. 从项目主目录中的路径和文件名(其中目录 .git 存在)
  4. 因此,如果您有以下结构:

`.git

public/index.html

public/css/style.css

供应商

composer.lock`

如果想要重新加载 index.html - 只需使用 public/index.html


1
在Amazon AWS的git版本codecommit中,您可以这样做:
aws codecommit \
  get-file --repository-name myrepo \
  --commit-specifier master \
  --file-path path/myfile \
  --output text \
  --query fileContent | 
base64 --decode > myfile

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