繁体   English   中英

在Git 1.7.0中稀疏结账?

[英]Sparse checkout in Git 1.7.0?

使用Git 1.7.0中新的稀疏结账功能 ,是否可以像在SVN中一样获取子目录的内容? 我找到了这个例子 ,但它保留了完整的目录结构。 想象一下,我只想要'perl'目录的内容,而没有名为'perl'的实际目录。

- 编辑 -

例:

我的git存储库包含以下路径

repo/.git/
repo/perl/
repo/perl/script1.pl
repo/perl/script2.pl
repo/images/
repo/images/image1.jpg
repo/images/image2.jpg
repo/doc/
repo/doc/readme.txt
repo/doc/help.txt

我想要的是能够从上面的存储库中生成这种布局:

repo/.git/
repo/script1.pl
repo/script2.pl

然而,使用当前的稀疏结账功能,似乎只能获得

repo/.git/
repo/perl/script1.pl
repo/perl/script2.pl

这不是我想要的。

您仍然需要克隆整个存储库,该存储库将包含所有文件。 您可以使用--depth标志仅检索有限数量的历史记录。

克隆存储库后,读取树技巧将存储库的“视图”限制为仅包含.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,images和docs的单独一个。 如果您还需要维护uber repo样式,则可以创建由子模块组成的repo。

richq的答案很接近,但它错过了一步。 您需要显式启用稀疏结帐:

git config core.sparsecheckout是的

此博客文章清楚地概述了所有步骤:

http://blog.quilitz.de/2010/03/checkout-sub-directories-in-git-sparse-checkouts/comment-page-1/#comment-3146

现在没有详细说明为什么要这样做,你的问题可以(可能)通过符号链接/快捷方式轻松解决。

回答这个问题 - 不,并且有一个有意义的理由。 即使使用“稀疏结账”,也可以下载回购的整个历史记录。 澄清为什么这是必要的 - 否则跟踪重命名的文件将是一个痛苦的...脖子。 想象一下你将文件/repo_root/asd/file1.cpp移动到/repo_root/fgh/file1.cpp - 现在如果你只下载了/repo_root/fgh deltas,你就不会知道file1.cpp。 所以这意味着你必须下载所有的增量。 但是你有一个完整的存储库; 不仅仅是文件夹的剪切,因此/rero_root/fgh文件夹本身不是repo。 当你结账时,这可能听起来不重要,但是当你提交时,git可能不知道工作正常。

解决方法 :如果你真的想要,你可以创建一个以这种方式调用git-checkout的脚本(对于sh shell,不应该很难生成用于windows的批处理):

!/bin/sh
curDir=`pwd`
cd $2
git-checkout $1
cp -R $3/* $4
cd $curDir

这里第一个参数是checkout的分支,第二个参数是repo当前存在的文件夹,第三个参数是你想要真正使用的子目录,第四个参数是你想要复制的位置。

警告:我的shell技能几乎不存在,所以在测试后使用它。 重新创建此脚本的反向并不难,复制回来的东西,以便它可以提交到repo。

git filter-branch --subdirectory-filter是你需要的,请参见Detach(move)子目录到单独的Git存储库中

这是一个小的bash脚本来做到这一点。

这将首先制作原始仓库的工作副本,然后使用子目录过滤器过滤分支,以获得您想要的。

#!/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将起作用。

您可以尝试编织 - 它跟踪遥控器,同时将它们与路径匹配。 https://github.com/evilchelu/braid/wiki

您尝试执行的操作似乎是重命名目录树,以便您的文件最终位于不同的位置。 在我看来,你要做的是一个代码/项目管理的反模板,有两个方面:模块分类(java节点下的java位,perl节点下的perl),以及一个包含不同位置文件的项目从开发人员可视化的地方开始。 由于git维护目录内容的哈希以查看更改内容,因此这也会破坏git。

Daemeon Reiydelle

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM