如何使用稀疏检出和指定的分支检出一个巨大的Git仓库中的子目录?

5
例如,我想获取这个文件夹:https://github.com/python/cpython/tree/2.7/Tools/freeze 我运行的命令是:
mkdir python
cd python
git init
git remote add origin https://github.com/python/cpython.git
git config core.sparsecheckout true
echo "Tools/freeze/*" >> .git/info/sparse-checkout

# find remote branches
git remote show origin

# this works and pulls only that folder
git pull --depth=1 origin master

# but this doesn't, why?
git pull --depth=1 origin 2.7

# but how do I switch to remote 2.7 branch?
git checkout --track -b 2.7 origin/2.7
fatal: Cannot update paths and switch to branch '2.7' at the same time.
Did you intend to checkout 'origin/2.7' which can not be resolved as commit?

我在某处读到了,在切换分支前需要先运行git fetch,但这有点违反稀疏检出的目的,因为我的网络很慢而且存储库很大。我该如何只获取那个带有2.7分支的子目录?谢谢!
我的系统是Windows8和Git Bash。
编辑: 如果我运行git pull --depth=1 origin 2.7,它会拉取远程的2.7分支,但也会将其他所有文件都带到我的工作目录中;而如果我运行git pull --depth=1 origin master,它只会带入主分支中Tools/freeze目录,这是为什么呢?
另一个例子:
mkdir qt
cd qt
git init
git remote add origin https://github.com/qtproject/qt.git
git config core.sparsecheckout true
echo util/qlalr/examples/lambda/* >> .git/info/sparse-checkout
git pull --depth=1 origin 4.8

那个文件夹 util/qlalr/examples/lambda 很小,但当运行最后一个命令时,仍然很慢,这可以避免吗?

编辑2:我意识到目前的 git 不支持此功能。但我现在唯一剩下的问题是为什么 git pull --depth=1 origin 2.7 不遵守稀疏检出配置?

5个回答

4

您需要创建一个本地分支来参考。更新的步骤应该是:

git init <repo>
cd <repo>
git remote add origin <url>
git config core.sparsecheckout true
echo "finisht/*" >> .git/info/sparse-checkout
git branch -b <your branch>
git pull --depth=1 origin <your branch>

1
您的结账失败是因为拉取(因此获取)显式引用仅获取该引用,因此在初始拉取后,您的存储库只有refs/heads/master和refs/remotes/origin/master两个指向相同提交的引用。检出2.7未能工作,因为您的存储库没有以那个名称命名的任何内容。
拉取执行合并,而额外的内容git pull origin 2.7放在您的工作树中用于冲突解决,合并无法确定正确的结果,因此您必须进行解决。您会发现,在Tools目录之外的所有内容都没有被检出,只有冲突文件。我不确定带有浅抓取和稀疏检出的合并应该如何整体运行,但要求解决冲突肯定是唯一要做的事情。
进行浅层单引用抓取是git最轻量级的操作,如果一次性带宽使用真的很重要,您可以将其克隆到ec2实例并标记特定的树。

0

试试这个

mkdir 
cd 
git init
git remote add -f origin <url>

这将创建一个空的代码库并获取所有对象,但不会检出它们。然后执行:

git config core.sparseCheckout true

现在定义你想要的文件夹。这可以通过添加到 .git/info/sparse-checkout 文件来完成。

echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout

那么

git pull origin master

谢谢,但整个想法是不使用“fetch”?因为在我低速互联网上,“fetch”非常慢。它仍然会获取我不需要的所有数据对吗? - Shuman

0

首先设置配置参数:

# Enable sparse-checkout:
git config core.sparsecheckout true

在 .git/info/sparse-checkout 中配置稀疏检出路径:

# Add the relevant path to the sparse-checkout file
echo cpython/tree/2.7/Tools/freeze >> .git/info/sparse-checkout

更新您的工作树:

git read-tree -mu HEAD

git-read-tree
将树形信息读入索引

-m
执行合并操作,而不仅仅是读取

-u
成功合并后,使用合并结果更新工作树中的文件。


稀疏检出

使用稀疏检出,您可以告诉Git从工作树中排除某个文件集。 这些文件仍将是存储库的一部分,但它们不会显示在您的工作目录中。

在内部,稀疏检出使用skip-worktree标志将所有排除的文件标记为始终更新。

# enable sparse checkout in an existing repository:
git config core.sparseCheckout true

# Create a .git/info/sparse-checkout file containing the
# paths to include/exclude from your working directory. 

# Update your working directory with 
git read-tree -mu HEAD

enter image description here


你是说我应该运行这个?我刚试了一下,不起作用。你能给出完整的命令吗?http://pastebin.com/W4yiJhwe我明白你的意思,你一定是从这里复制的:http://blogs.atlassian.com/2014/05/handle-big-repositories-git/ 但整个想法是不要一开始就克隆,我已经提到我想避免克隆或获取整个repo。你可以在像qt这样的大型repo上尝试你的建议,它仍然会获取所有内容,选择任何小文件夹,应该在几秒钟内完成,对吧?不是10-20分钟。 - Shuman
我一开始就没有该仓库的克隆。 - Shuman
嗨,我没有从这个链接复制解决方案。但我在一个克隆的完整(fetched)仓库上运行过它。是的,它不应该需要10-20分钟才能运行。 - CodeWizard
谢谢!我想避免完全克隆(fetch),肯定有办法对吧?我在我的问题中发布的命令已经做到了这一点,唯一的问题是它只获取“master”分支,当我用“git pull --depth = 1 origin 2.7”替换“git pull --depth = 1 origin master”时,我不知道为什么它会拉取其他文件夹中的所有文件,似乎当我拉取除“master”以外的分支时,稀疏检出配置不起作用。 - Shuman
@Shuman请注意您要放入.git/info/sparse-checkout的内容。它以cpython/tree/2.7/......开头,这意味着您已经从分支2.7中拉取了内容。现在将其与--depth=1组合使用即可。它应该能工作。 - Khurshid Alam

0

我想从一个分支中下载特定的文件夹,而不需要下载整个主仓库的历史记录,因为该仓库有大量的历史记录和分支数量。

mkdir testFolder
cd testFolder
git init
git remote add origin <URL>

以下 git 命令将获取以 f_2 开头的分支,例如:f_23、f_24 等。
git config remote.origin.fetch +refs/heads/f_2*:refs/remotes/origin/f_2*
git fetch --depth=1

设置您想要检出的文件夹名称。

git sparse-checkout set <folderName>

以下命令将从f_23分支下载该特定文件夹

git checkout f_23

@Jean-François Fabre,我将我的答案从另一个问题中删除并发布在这里,因为我的解决方案似乎与该问题更相关。 - harshini gulipalli

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