我的Git存储库在根目录下有两个子目录:
/finisht
/static
当这是在SVN中时,/finisht在一个地方签出,而/static在其他地方签出了,如下所示:
svn co svn+ssh://admin@domain.example/home/admin/repos/finisht/static static
有没有办法用Git做到这一点?
我的Git存储库在根目录下有两个子目录:
/finisht
/static
当这是在SVN中时,/finisht在一个地方签出,而/static在其他地方签出了,如下所示:
svn co svn+ssh://admin@domain.example/home/admin/repos/finisht/static static
有没有办法用Git做到这一点?
当前回答
编辑:从Git 2.19开始,这终于是可能的,从这个答案中可以看出。
考虑对这个答案投赞成票。
注意:在Git2.19中,只实现了客户端支持,服务器端支持仍然缺失,因此它只在克隆本地存储库时有效。还要注意,大型Git宿主(例如GitHub)实际上并不使用Git服务器,而是使用自己的实现,因此即使Git服务器中显示了支持,也不会自动表示它在Git宿主上运行。(OTOH,因为他们不使用Git服务器,所以在Git服务器出现之前,他们可以在自己的实现中更快地实现它。)
不,这在Git中是不可能的。
在Git中实现这样的东西将是一项巨大的努力,这意味着客户端存储库的完整性将无法再得到保证。如果您感兴趣,请在gitmailinglist上搜索有关“稀疏克隆”和“稀疏获取”的讨论。
一般来说,Git社区的共识是,如果您有几个目录总是独立检出,那么这是两个不同的项目,应该存在于两个不同存储库中。您可以使用Git子模块将它们粘在一起。
其他回答
虽然我讨厌在处理git repos时使用svn:/我一直使用这个;
function git-scp() (
URL="$1" && shift 1
svn export ${URL/blob\/master/trunk}
)
这允许您无需修改即可从github url中复制。用法
--- /tmp » git-scp https://github.com/dgraph-io/dgraph/blob/master/contrib/config/kubernetes/helm 1 ↵
A helm
A helm/Chart.yaml
A helm/README.md
A helm/values.yaml
Exported revision 6367.
--- /tmp » ls | grep helm
Permissions Size User Date Modified Name
drwxr-xr-x - anthony 2020-01-07 15:53 helm/
您正在尝试做的是所谓的稀疏签出,这一功能是在Git1.7.0(2012年2月)中添加的。执行稀疏克隆的步骤如下:
mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>
这将使用远程设备创建一个空的存储库,并获取所有对象,但不会检出它们。然后执行以下操作:
git config core.sparseCheckout true
现在,您需要定义要实际检出的文件/文件夹。这是通过在.git/info/spease checkout中列出它们来完成的,例如:
echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout
最后但同样重要的是,使用远程状态更新空回购:
git pull origin master
现在,文件系统上的一些/dir和另一个/sub/tree的文件将被“检出”(这些路径仍然存在),而没有其他路径。
您可能想看一下扩展教程,可能应该阅读有关稀疏签出和读取树的官方文档。
作为一项功能:
function git_sparse_clone() (
rurl="$1" localdir="$2" && shift 2
mkdir -p "$localdir"
cd "$localdir"
git init
git remote add -f origin "$rurl"
git config core.sparseCheckout true
# Loops over remaining args
for i; do
echo "$i" >> .git/info/sparse-checkout
done
git pull origin master
)
用法:
git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"
请注意,这仍然会从服务器下载整个存储库–只有签出的大小减小了。目前,仅克隆一个目录是不可能的。但如果您不需要存储库的历史记录,至少可以通过创建浅层克隆来节省带宽。有关如何结合浅层克隆和稀疏检出的信息,请参阅下面的udondan答案。
截至Git 2.25.0(2020年1月),Git中添加了一个实验性稀疏校验命令:
git sparse-checkout init
# same as:
# git config core.sparseCheckout true
git sparse-checkout set "A/B"
# same as:
# echo "A/B" >> .git/info/sparse-checkout
git sparse-checkout list
# same as:
# cat .git/info/sparse-checkout
这看起来简单得多:
git archive --remote=<repo_url> <branch> <path> | tar xvf -
我写了一个从GitHub下载子目录的脚本。
用法:
python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>
仅使用Git是不可能克隆子目录的,但以下是一些解决方法。
过滤器分支
您可能希望重写存储库,使其看起来像trunk/public_html/是它的项目根,并放弃所有其他历史记录(使用过滤器分支),尝试已经签出的分支:
git filter-branch --subdirectory-filter trunk/public_html -- --all
注意:--将筛选器分支选项与修订选项分开,--all用于重写所有分支和标记。将保留所有信息,包括原始提交时间或合并信息。此命令接受refs/replace/namespace中的.git/info/places文件和ref,因此如果定义了任何移植或替换ref,运行此命令将使其永久化。
警告重写的历史将对所有对象具有不同的对象名称,并且不会与原始分支汇合。您将无法在原始分支的顶部轻松推送和分发重写的分支。如果您不知道完整的含义,请不要使用此命令,如果一次简单的提交就足以解决您的问题,请避免使用它。
稀疏校验
以下是稀疏签出方法的简单步骤,它将稀疏地填充工作目录,因此您可以告诉Git工作目录中的哪个文件夹或文件值得签出。
照常克隆存储库(--不选择签出):gitclone--不签出git@foo/巴.吉特cd条如果已经克隆了存储库,则可以跳过此步骤。提示:对于大型回购,请考虑浅层克隆(--depth 1)以仅签出最新版本或/和--仅签出单个分支。启用spareCheckout选项:git-config-core.sparseCheckout true指定用于稀疏签出的文件夹(末尾没有空格):echo“trunk/public_html/*”>.git/info/s稀疏签出或edit.git/info/s稀疏签出。签出分支(例如主分支):切换到主分支
现在,您应该在当前目录中选择了文件夹。
如果有太多级别的目录或过滤分支,可以考虑使用符号链接。