如何在Git中只包含另一个存储库中的一个文件夹?

时间:2015-05-28 19:48:28

标签: python git git-submodules

我有一个看起来像这样的python模块。

|
|-- my_module/
|-- tests/
|-- .git/

我想在另一个项目中使用它。通常子模块就足够了,但是,我宁可直接插入实际模块,也不要在我的应用程序中包含任何其他东西。

|-- .git/
|-- my_app/
|-- my_module/

有没有办法只使用git子模块导入单个文件夹?

  

如果我不能或者它不切实际,我还能如何在保持版本控制的同时包含来自另一个git跟踪项目的单个文件夹?

2 个答案:

答案 0 :(得分:1)

如果您不想使用git submodule,只需签出所需的文件夹即可。

由于没有明确的方法只从repo中获取文件夹,因此您需要手动执行以下操作:

- create your desired repositories (you already have it)
- write a script that loop over range of commits
- extract the desired folder content from the current commit
- commit the current folder 

这个问题是你不会拥有原始的SHA-1,因为你只提交提交快照的部分部分。

代码示例

您的代码应该类似于:

for commit in $(git rev-list $branch)
do
    if git ls-tree --name-only -r $commit | grep '<your desired path>'; then
        // Process the commit content
        git checkout <path>
        git add ....
        git commit .... 
        exit 0
    fi
done

为什么我不能从git历史记录中提取文件夹?

原因很简单就是git存储其内容的方式。

  

Git是一个愚蠢的内容跟踪器(Linus Tovalds)

这意味着git不会以我们在工作目录中看到的方式存储内容。

Git只需要当前文件系统的快照(实际上它有点复杂,git使用blob,帅气,启发式等等),以便从历史中提取特定内容您必须checkout来自commit本身的具体内容。

答案 1 :(得分:1)

Git子树可能适用于这种情况。您可以子树将其他仓库添加到您的仓库中,然后删除您在第二次提交时不关心的文件夹。

但是,当您稍后子树更新以获取其他存储库的新版本时,如果删除的文件夹中有更改,则需要处理任何合并冲突。

如果您的其他项目经常更新,这可能不是一个好的解决方案。