使用git子树合并,同时也合并所有合并子树的所有分支

使用git子树合并,同时也合并所有合并子树的所有分支,git,merge,redmine,subtree,Git,Merge,Redmine,Subtree,我想使用一个流行的、开放源码的问题跟踪器(Redmine),它提供git集成。不幸的是,跟踪器中的每个项目只能与一个git回购关联。在跟踪器中创建多个项目不是我的理想设置 考虑到这一点,我尝试使用git子树合并(解释和)。我创建了一个“伞式”回购协议,它与我正在处理的众多其他回购协议合并在一起 不幸的是,给出的示例只拉入每个子树的主分支。由于我在每个子树的多个分支中进行了开发,所以我需要学习如何让伞式回购反映每个子树的每个分支 这可能吗 额外积分:如果两个子树每个都有一个同名分支会怎样?对于我们

我想使用一个流行的、开放源码的问题跟踪器(Redmine),它提供git集成。不幸的是,跟踪器中的每个项目只能与一个git回购关联。在跟踪器中创建多个项目不是我的理想设置

考虑到这一点,我尝试使用git子树合并(解释和)。我创建了一个“伞式”回购协议,它与我正在处理的众多其他回购协议合并在一起

不幸的是,给出的示例只拉入每个子树的主分支。由于我在每个子树的多个分支中进行了开发,所以我需要学习如何让伞式回购反映每个子树的每个分支

这可能吗


额外积分:如果两个子树每个都有一个同名分支会怎样?

对于我们这些不熟悉Redmine的人,请扩展您的描述,包括以下问题的答案:追踪器需要什么样的存储库访问权限?它是否需要作出自己的承诺?或者,它是否只需要某些类型的读取访问(可能是为了验证提交哈希和扫描提交日志中的关键字)

如果您的跟踪器只需要读取访问权限,则可能根本不需要任何子树合并。在一个存储库中有多个初始提交(允许多个独立的历史记录)是完全可以接受的。Git项目本身为一些“额外的”(man、html、todo)执行此操作,这些“额外的”(man、html、todo)与没有(提交)历史记录,但与源代码的主要分支集(maint、master、next、pu)一起发布。出于您的目的,为每个子存储库设置一个远程存储库并将它们的分支提示提取到聚合存储库中就足够了。也许自动的“远程跟踪分支”就足够了,或者也许您需要采取额外的步骤来基于远程跟踪分支创建(和更新)本地分支

在源存储库中的分支不相关或仅半相关的一般情况下,您描述的子树合并方案可能没有意义。但是,如果所有源存储库共享一组分支,其中每个分支都有一个在所有存储库中都相同的给定目的,那么您可能会有意义地将它们合并到一种超级存储库中

但有趣的问题不是“如果两个存储库有同名的分支怎么办?”,而是“如何处理存储库在共享的“全局”集中缺少分支的情况?”

如果所有子存储库都有相同的分支集,那么只需像使用master一样执行操作,但每个分支只执行一次。当存储库中缺少特定分支时,就会出现问题。你可以代替它的主人,但这可能并不总是正确的答案。这取决于您首先将存储库聚合在一起的原因,以及您希望在超级存储库中该分支的子树中“看到”什么

如果子存储库不是紧密相关的,那么我真的怀疑这种子树方法的合理性。对于不相关的存储库,这种方法感觉像是“违背常规”。这可能仍然是可能的,但我怀疑是否有任何工具可以帮助你,你将需要花一些时间来计划解决这些棘手的问题

如果您最终坚持使用子树合并,您可以查看第三方命令。它可能有助于保持您的无数存储库同步


正在收集分支,但不合并 如果Redmine指定了
--mirror
克隆,这意味着它需要本地分支,并且可能无法直接读取“远程跟踪分支”,因此您可能需要创建和更新一些本地分支

从“远程跟踪分支”更新的本地分支
  • 初始设置

    mkdir $COLLECTION_REPO && cd $COLLECTION_REPO &&
    git init
    git remote add alpha <url/path-to-alpha-repo>
    git remote add bravo <url/path-to-bravo-repo>
    git remote add charlie <url/path-to-charlie-repo>
    for r in $(git remote); do
        git config --add remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.heads.tags.;s.remotes.tags/all.')"
        git config remote.$r.tagopt --no-tags
    done
    
    mkdir $COLLECTION_REPO && cd $COLLECTION_REPO &&
    git init
    git remote add alpha <url/path-to-alpha-repo>
    git remote add bravo <url/path-to-bravo-repo>
    git remote add charlie <url/path-to-charlie-repo>
    for r in $(git remote); do
        git config remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.remotes.heads/all.')"
        git config --add remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.heads.tags.g')"
        git config remote.$r.tagopt --no-tags
    done
    
直接接收获取的分支提示的本地分支
  • 初始设置

    mkdir $COLLECTION_REPO && cd $COLLECTION_REPO &&
    git init
    git remote add alpha <url/path-to-alpha-repo>
    git remote add bravo <url/path-to-bravo-repo>
    git remote add charlie <url/path-to-charlie-repo>
    for r in $(git remote); do
        git config --add remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.heads.tags.;s.remotes.tags/all.')"
        git config remote.$r.tagopt --no-tags
    done
    
    mkdir $COLLECTION_REPO && cd $COLLECTION_REPO &&
    git init
    git remote add alpha <url/path-to-alpha-repo>
    git remote add bravo <url/path-to-bravo-repo>
    git remote add charlie <url/path-to-charlie-repo>
    for r in $(git remote); do
        git config remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.remotes.heads/all.')"
        git config --add remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.heads.tags.g')"
        git config remote.$r.tagopt --no-tags
    done
    
这两种方法最终都会在
refs/heads/all/
下收集分支,但第一种方法在
refs/remotes//
下也有一组重复的ref。第一种方法使用普通的fetch REFSEC,并使用
git分支
将“远程跟踪分支”(
refs/remotes/…
)复制到普通的本地分支(
refs/heads/all/…
)。第二种方法使用自定义refspec将获取的ref直接存储到目标ref层次结构中

由于更新是盲目地获取到这个组合存储库中的,所以任何人都不应该尝试直接使用它:不直接在其分支上进行提交,也不从外部进行推送。如果有人在本地进行提交或推到其中一个分支上,那么在下一次更新完成时,这些提交将被删除

如果Redmine可以处理裸存储库,我建议使用一个。使用
git init--bare
和以.git结尾的回购名称。另外,
git config core.logAllRefUpdates true
可能是一个好主意(因为在裸存储库中默认为false)

除了名称空间中的
all/
前缀之外,此方法与完整的
--mirror
克隆之间的另一个区别是,不会收集
refs/heads
refs/tags
之外的refs。大多数其他公共引用被认为是存储库的“本地”(这就是为什么它们不被普通克隆复制的原因)。其他一些引用是“远程跟踪分支”(
refs/remotes
),一些“对分”记录保存(
refs/bisect
),
git过滤器分支
“原始”引用备份(
refs/original
),等等。也许这些东西对Redmine来说都不重要。如果是,它们也可以包含在其他参照规范中

创建额外的初始提交 安排具有新初始提交的分支