Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git子树和多个目录_Git_Git Subtree - Fatal编程技术网

Git子树和多个目录

Git子树和多个目录,git,git-subtree,Git,Git Subtree,我有一个相当大的git存储库,它有一个我维护库代码的目录。该目录包含多个子目录 repo +--- lib | +--- A | +--- B ... | +--- Z 现在让我们假设我想要开放源代码子目录A,…,M,并保持子目录N,…,Z的封闭源代码。让我们也假设我想: 将A,…,M保存在单个开源存储库中。这样做的原因是目录A,…,M具有相互依赖性,将它们拆分为单独的存储库会让人感到困惑 保持我的封闭源代码存储库的结构完好无损。例如,我可以创建子目录lib/pub和lib

我有一个相当大的git存储库,它有一个我维护库代码的目录。该目录包含多个子目录

repo
+--- lib
|    +--- A
|    +--- B
...
|    +--- Z
现在让我们假设我想要开放源代码子目录
A,…,M
,并保持子目录
N,…,Z
的封闭源代码。让我们也假设我想:

  • A,…,M
    保存在单个开源存储库中。这样做的原因是目录
    A,…,M
    具有相互依赖性,将它们拆分为单独的存储库会让人感到困惑
  • 保持我的封闭源代码存储库的结构完好无损。例如,我可以创建子目录
    lib/pub
    lib/pvt
    ,但这会产生级联效应,需要在其他地方更改引用,或者需要大量符号链接(
    lib/a->lib/pub/a
  • 有一个类似于
    git子树的解决方案
    ,我可以在封闭源代码存储库或开放源代码存储库中修改代码,并且可以轻松地在两个存储库之间同步更改
我已经在stackoverflow和google中搜索了一个解决方案,但似乎没有一个明显的解决方案。从概念上讲,
git子树
应该能够做到这一点,但它只适用于单个子目录

我研究了
git子树
脚本,希望对其进行修改

我觉得,如果我要修改<代码>子TreEyFuxPin()/代码>,我应该能够说服<代码> Git子树分裂< /C> >考虑多于一个目录来进行拆分。但是我对git的了解还不足以理解脚本在做什么,并在不破坏东西的情况下修改它

如果您在修改
git子树
时有任何上述问题的解决方案或任何其他指针,请告诉我。

拆分与父项目中的文件混合的子树 这似乎是一个常见的请求,但是当文件夹像这样混合在一起时,我不认为有一个简单的答案

我建议将库与其他文件夹混合使用的一般方法如下:

  • 使用库目录的新根创建分支:

    git subtree split -P lib/ -b temp-br
    git checkout temp-br
    
  • 然后使用一些东西来重写历史,以删除不属于库的部分。我不是这方面的专家,但我能够进行实验,并发现类似的工作:

    git filter-branch --tag-name-filter cat --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch N O P Q R S T U V W X Y Z' HEAD
    
    注意:如果执行连续命令,则可能需要删除筛选器分支所做的备份

    git update-ref -d refs/original/refs/heads/temp-br
    
  • 最后,只需为库创建一个新的回购协议,并将剩下的所有内容都拉进来:

    cd <new-lib-repo>
    git init
    git pull <original-repo> temp-br
    
    cd
    初始化
    吉特拉温度
    

  • 当您在一个目录src中同时拥有子目录和文件时,您希望将其拆分为一个单独的存储库,该存储库随后将成为一个子模块,但答案并不多。假设您希望将dir2和file2移动到新的repo srcpublic,然后在原始repo中

    git mv src/file2 src/dir2;git子树拆分-P dir2-b branch_dir2

    在新回购协议中, 子树pull/dir2分支_dir2; git mv目录2/文件2/

    新回购协议: srcpublic-file2,dir2

    原始回购协议: src-file1,file2, dir1,dir2


    当有几十个文件夹和文件时,将命令放在一个脚本中是很有帮助的。

    这里有一个基于
    git子树的shell脚本
    ,它比基于
    git filter branch--tree filter
    的解决方案要快得多;它的副作用是生成多个额外的
    git mv
    ,并将
    git merge
    提交添加到最终的
    HEAD
    。如果您觉得这些额外的空提交没有问题,可以尝试:

    ids=0
    lists=(\
        "a/b" \
        "c/d/e" \
    )
    # subtree each path
    for dir in ${lists[@]}
    do
        echo git subtree split -P $dir -b split_dir_$ids
        git subtree split -P $dir -b split_dir_$ids
        ((ids++))
    done
    
    # restore folder structure
    for (( idx=0; idx < ${#lists[@]}; idx++ ))
    do
        git checkout split_dir_$idx
        dir=${lists[$idx]}
        mkdir -p $dir
        dirPrefix=${$dir%%/*}
        find . -maxdepth 1 ! -name $dirPrefix -and ! -name '\.*' \
            -exec git mv {} $dir \;
    done
    
    # merge
    git checkout split_dir_0
    for (( idx=1; idx < ${#lists[@]}; idx++ ))
    do
        git merge -q split_dir_$idx
    done
    
    git push -u `target remote` `target branch`
    
    ids=0
    列表=(\
    “a/b”\
    “c/d/e”\
    )
    #子树每条路径
    对于${lists[@]}中的目录
    做
    echo git子树拆分-P$dir-b拆分\u dir\u$id
    git子树拆分-P$dir-b拆分\u dir\uid
    ((ids++)
    完成
    #还原文件夹结构
    对于((idx=0;idx<${列表[@]};idx++)
    做
    git签出拆分目录$idx
    dir=${lists[$idx]}
    mkdir-p$dir
    dirPrefix=${$dir%%/*}
    找到-最大深度1-名称$dirPrefix-和-名称'\.''\
    -exec git mv{}$dir\;
    完成
    #合并
    git签出拆分目录0
    对于((idx=1;idx<${列表[@]};idx++)
    做
    git merge-q split_dir_uu$idx
    完成
    git push-u`target remote``目标分支`
    
    使用
    git子树添加
    你看,我认为你可以对两个以上的目录使用这种技术,甚至对多个回购协议,也就是

    cd/repos/big repo
    #将A..M分支分开
    对于{A..M}中的N;做
    git子树拆分--前缀=lib/$N--分支=split-$N
    完成
    #创建新回购协议
    mkdir/repos/am repo
    cd/回购/am回购
    初始化
    #提交某物或git子树添加将抱怨并失败
    触摸。忽略;吉特加。;git提交-m“开始历史修订”
    #拆分为A..M分支
    对于{A..M}中的N;做
    git子树添加--prefix=lib/$N../big repo split-$N
    完成
    
    此答案是否与所问问题相关?他想用git子树将多个子目录拆分成一个单独的repo…@enrol76我想是的。筛选器分支将删除新repo中不需要的目录。执行筛选器分支时,它会尝试备份新分支中的目录,因为该命令具有破坏性。如果您再次运行该命令,以分步筛选出其他内容,它将再次尝试备份,并且由于已经有备份,它会抱怨。如果您知道要保留原始分支需要注意什么,您可以忽略预防措施,update ref将删除备份分支。我遇到了同样的愿望,因为我的子目录A、B、C都是相互关联的,我想将它们从子目录D、E中分离出来,F.可能必须使用过滤分支这是否回答了您的问题?这不像是将一个到M作为一个单独的存储库进行拆分。如果提交同时涉及a和M,那么提交将在spl中重复