如何克隆仅Git存储库的子目录?
我有我的Git仓库,在根,有两个子目录:
/finisht /static
当这是在SVN中 , /finisht
被检出在一个地方,而/static
被检出在其他地方,如下所示:
svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static
有没有办法与Git做到这一点?
这被称为稀疏结帐 ,从版本1.7.0开始。
“稀疏结帐”允许稀疏地填充工作目录。 它使用
skip-worktree
位(请参阅git-update-index
)告诉Git工作目录中的文件是否值得一看。虽然
$GIT_DIR/info/sparse-checkout
通常用于指定文件所在的位置,但您也可以使用取反模式来指定不在的文件。 例如,要删除unwanted
的文件:/* !unwanted
有关详细信息,请参阅相关答案和手册 。
你所要做的就是称为稀疏结帐 ,而这个function是在git 1.7.0(2012年2月)中添加的。 执行稀疏克隆的步骤如下所示:
mkdir <repo> cd <repo> git init git remote add -f origin <url>
这将为您的远程创build一个空的存储库,并获取所有对象,但不检查它们。 然后做:
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
现在,您将在文件系统上为some/dir
和another/sub/tree
“签出”文件(这些path仍然存在),并且不存在其他path。
你可能想看看扩展教程 ,你应该阅读稀疏结帐的官方文档 。
请注意,这仍将从服务器下载整个存储库 – 只有结账尺寸减小。 目前,只克隆一个目录是不可能的。 但是,如果您不需要存储库的历史logging,则至less可以通过创build浅度克隆来节省带宽。 请参阅下面的udondan的答案 ,了解如何将浅克隆和稀疏结帐相结合的信息。
您可以组合稀疏结帐和浅层克隆function。 浅层克隆切断了历史logging,而稀疏结帐只会拉取与您的模式相匹配的文件。
git init <repo> cd <repo> git remote add origin <url> git config core.sparsecheckout true echo "finisht/*" >> .git/info/sparse-checkout git pull --depth=1 origin master
你需要最低的git 1.9才能工作。 我自己只用2.2.0和2.2.2来testing它。
这样,你仍然可以推 ,这是不可能的与git archive
。
Git 1.7.0有“稀疏结账”。 请参阅git config手册页中的“core.sparseCheckout”, git read-tree手册页中的“Sparse checkout”以及git update-index手册页中的“Skip-worktree bit”。
这个接口并不像SVN那样方便(例如,在初始化克隆的时候没有办法做一个稀疏的检出),但是现在可以构build简单接口的基本function。
如果你从来没有计划与你克隆的仓库进行交互,你可以做一个完整的git克隆,并使用git filter-branch –subdirectory-filter重写你的仓库。 这样,至less历史将被保留下来。
这看起来简单得多:
git archive --remote=<repo_url> <branch> <path> | tar xvf -
对于只想从github 下载文件/文件夹的其他用户
简单地使用
svn export <repo>/trunk/<folder>
例如
svn export https://github.com/lodash/lodash/trunk/docs
(是的,这里是svn,显然在2016年,你仍然需要svn来简单地下载一些github文件)
礼貌从GitHub仓库下载单个文件夹或目录
重要! 确保你更新了github的URL,用'/ trunk /'取代'/ tree / master /'。
只有使用Git才能克隆子目录,但下面几个解决方法是不可能的。
筛选分支
您可能需要重写存储库,使其看起来像是trunk/public_html/
作为其项目根目录,并放弃所有其他历史logging(使用filter-branch
),试试已经签出的分支:
git filter-branch --subdirectory-filter trunk/public_html -- --all
注意: --
将过滤分支选项与修订选项分开,并且 – 全部重写所有分支和标记。 包括原始提交时间或合并信息的所有信息将被保留 。 这个命令可以使用.git/info/grafts
文件,并且在refs/replace/
命名空间中refs/replace/
,所以如果你有任何移植或replace参数,运行这个命令将会使它们成为永久的。
警告! 重写后的历史logging将为所有对象设置不同的对象名称,并且不会与原始分支会聚。 您将无法轻松地将重写的分支推送并分发到原始分支之上。 如果您不知道全部含义,请不要使用这个命令,如果简单的单一提交就足以解决您的问题,请避免使用它。
稀疏结帐
这里有一些简单的步骤,使用稀疏的检出方法,这将稀疏地填充工作目录,所以你可以告诉Git工作目录中的文件夹或文件是值得检查的。
-
像往常一样克隆存储库(
--no-checkout
是可选的):git clone --no-checkout git@foo/bar.git cd bar
如果您的存储库已经被克隆,您可以跳过这一步。
提示:对于大的回购,考虑浅克隆 ( –
--depth 1
)只签出最新版本或/和--single-branch
。 -
启用
sparseCheckout
选项:git config core.sparseCheckout true
-
指定稀疏结帐的文件夹(最后没有空格):
echo "trunk/public_html/*"> .git/info/sparse-checkout
或编辑
.git/info/sparse-checkout
。 -
检出分支(如
master
):git checkout master
现在你应该select当前目录中的文件夹。
如果您的目录层次过多,或者过滤分支,您可以考虑使用符号链接。
我刚刚为GitHub 写了一个脚本 。
用法:
python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>
为什么不只是以下内容 – 初始化回购之后,请执行:git checkout
这适用于文件和文件夹,我一直这样做,当我想清理结帐的东西。