如何使用git拉特定目录


193

我有一个带有git的项目,我只想克隆或提取特定的目录,就像myproject / javascript一样,就像subversion一样。
进行一些更改,提交并再次推回。
这是可能的?


3
稀疏结帐你可能感兴趣的(即使你仍然需要获取的一切):看到stackoverflow.com/questions/2416815/...
VonC

Answers:


205
  1. 进入您的回购副本顶部
  2. git fetch
  3. git checkout HEAD path/to/your/dir/or/file

    • 其中,“ path/...”(3)开始在目录略低于含回购根你的“ .../file

    • 注意,可以使用特定提交的哈希码代替“ HEAD”,然后您将获得该提交特定的修订(文件)或修订(目录)。


1
刚意识到我误解了这个问题。我的回复改为解决如何检出单个文件,然后可以对其进行修改和提交。
vergueishon 2011年

您回答了问题的标题,这已经足够了。就我而言,这才救了我,就我而言,这是正确的答案-尤其是因为这在Google上是该问题的热门话题。
Morgon

21
这仍然可以得到整个仓库。对于大小项目2GB,这并不节省很多时间..
Pithikos

5
对于那些阅读了这些注释并且不知道这不能解决问题的人,此解决方案的作用是只为您提供一个文件夹的副本,但它不是工作副本,这意味着您无法进行修改和重新创建-承诺。因此,正如@Morgon所说,它可以解决问题的标题(您只能拉一个目录),但不能回答问题的正文(“进行一些更改,再次提交并再次推回”)。
msb

@StanHolodnak --不是必需的。它强制将其后的位解释为路径。因此,是的,如果您有一个--help要检出名称的文件,则需要在这些文件前加上以下连字符:git checkout HEAD -- --help
TimVisée17年

105

在一个空目录中:

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory

如果您只想使用文件的远程版本来替换本地文件,则此方法有效,我认为
John John

这也拉文件夹,如何不不卸载文件夹,而仅卸载文件夹内的东西?
Al Kasih

不需要fetch或没有checkout命令,我们只需在remote add命令后发出pull请求即可获得整个master分支。
伊克拉。

2
正如Pithkos在接受的答案中指出的那样,此答案还将下载整个远程存储库到您的本地计算机。shingara的答案是最明确的-无法远程提取回购的一部分。但是,对于那些不介意整个抓取的带宽并且对制作局部缓存的一部分工作副本感兴趣的人,那么可以接受的答案向您展示了如何。但是我只是想弄清楚必须将回购的整个历史记录(以压缩格式)下载到您的计算机上。
·霍尔斯默

39

经过大量寻找答案,没有找到,放弃,再试一次等​​等之后,我终于在另一个SO线程中找到了解决方案:

如何git-pull除一个文件夹外的所有文件夹

要复制粘贴其中的内容:

git init
git remote add -f origin <url>
git config core.sparsecheckout true
echo <dir1>/ >> .git/info/sparse-checkout
echo <dir2>/ >> .git/info/sparse-checkout
echo <dir3>/ >> .git/info/sparse-checkout
git pull origin master

要执行OP想要的操作(仅在一个目录上工作),只需.git/info/sparse-checkout在执行上述步骤时将该目录添加到中即可。

非常感谢@cforbish!


2
我将其发布在这里主要是因为每当我尝试使用google进行操作时,这都是最高的结果,并且该线程甚至都无法显示。:(我觉得复制粘贴很糟糕,但是我认为这是最佳实践吗?
msb

1
这是唯一的清洁解决方案。尝试了以上答案。在用其他答案签出分支后,我无法拉动,并且有几个需要提交的新文件。使用此解决方案,一切看起来都很正确。但是请注意:不管已签出的分支,git都会认为您在 master。只要确保您确实git branch --set-upstream-to=origin/<branch>正确地拉扯
seebiscuit

12

这是不可能的。您只需要提取所有存储库或什么都不需要。


1
即使您需要获取所有内容,在这种情况下,拉稀疏检出工作树是否也会引起您的兴趣?见stackoverflow.com/questions/2416815/...
VonC

10
补充说明一下,您不能仅提取目录的原因是因为git使用数据语义跟踪,而不是文件语义跟踪,因此您可以无缝地将代码(或其他数据)移入或移出文件,而不必告诉源代码跟踪系统(当然,除非您进行更新。)因此,代码也可以无缝地移入和移出目录,因此仅抓取一个目录没有多大意义。希望这可以帮助。
OmnipotentEntity

12
@OmnipotentEntity对不起,但是恕我直言,它确实是有道理的。实现不应限制使用。Git确实知道什么目录(至少在创建本地工作副本时),因此没有理由它不能在服务器上执行某些类似的操作,而只是发送相关的输出。当然,当前尚未实现,但这是由于缺少功能,而不是根本不可能。我个人认为这是一个非常重要的功能,但是,这就是我尽可能避免使用git的原因之一。
基本

10

也许这个命令会有所帮助:

git archive --remote=MyRemoteGitRepo --format=tar BranchName_or_commit  path/to/your/dir/or/file > files.tar

“ Etvoilà”


2
这将下载文件的特定目录以供存档,这不会拉出您可以修改并推回的副本。
leetNightshade

很酷。可能不适合作为OP的解决方案,但这实际上是所追求的,因为我只需要在更大的存储库中搜索大文件夹的内容,我绝对不想获取,并且不需要修改/推。
奥利弗

7

如果要在不输入目录的情况下获取目录的最新更改,可以执行以下操作:

$ git -C <Path to directory> pull


1

尝试并测试了这个作品!

mkdir <directory name> ;  //Same directory name as the one you want to pull
cd <directory name>;
git remote add origin <GIT_URL>;
git checkout -b '<branch name>';
git config core.sparsecheckout true;
echo <directory name>/ >> .git/info/sparse-checkout;
git pull origin <pull branch name>

希望这对您有所帮助!


0

有时,您只想看看文件的先前副本,而无需经历差异。

在这种情况下,创建存储库的克隆并签出您感兴趣的特定提交并查看该克隆的存储库中的子目录就很容易了。由于所有内容都是本地的,因此您只需在完成后删除此克隆即可。


-1

对于像我一样的理论文件路径和示例所做的所有努力,下面是一个真实的示例:Microsoft在git hub上提供了他们的文档和示例,但不幸的是,他们确实为该存储库中的大量主题收集了所有示例文件:

https://github.com/microsoftarchive/msdn-code-gallery-community-s-z

我只对路径中的Microsoft Dynamics js文件感兴趣

msdn-code-gallery-community-s-z/Sdk.Soap.js/

所以我做了以下

创建一个

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

磁盘上我的存储库文件夹中的文件

git sparse-checkout init

在Windows上使用cmd在该目录中

文件内容

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

Sdk.Soap.js/*

终于做一个

git pull origin master
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.