如何在git中维护线性历史记录

如何在git中维护线性历史记录,git,Git,出于不同的原因,我需要维护一个线性主分支。也就是说,该分支中的提交不能有多个父级 我们的团队中有很多人,我们希望建立feature分支来共同工作。通常,我们会在这个特性分支上重新设置自己的个人提交,然后在特性准备就绪时将其合并到我们的开发分支中。我们还依赖于一个foreign项目(该项目使用不同的分支,但我们在此假设它都在一个foreign分支中,该分支有自己的独立来源),我们定期合并到devel分支中 然而,所有这些工作最终都必须以线性形式转发给主分支。我们可以在master(使用git re

出于不同的原因,我需要维护一个线性
主分支。也就是说,该分支中的提交不能有多个父级

我们的团队中有很多人,我们希望建立
feature
分支来共同工作。通常,我们会在这个
特性
分支上重新设置自己的个人提交,然后在特性准备就绪时将其合并到我们的
开发
分支中。我们还依赖于一个
foreign
项目(该项目使用不同的分支,但我们在此假设它都在一个
foreign
分支中,该分支有自己的独立来源),我们定期合并到
devel
分支中

然而,所有这些工作最终都必须以线性形式转发给
分支。我们可以在
master
(使用
git reset--soft devel
)中将所有这些更改压缩成一个提交,然后将
master
合并回
devel
。然而,我们希望尽可能保留我们的承诺:

  • 应保留每个提交消息(包括合并消息)
  • 必须保留提交之间的拓扑顺序
  • 外部
    分支合并的提交必须压缩为单个“合并”提交(遗憾的是没有父信息)
  • 分支
    master
    devel
    feature
    foreign
    必须保持完全向前兼容(因为这是一个共享存储库)
我最初的想法是:

  • devel
  • 重新设置基础
    staging
    ontop of
    master
  • 将新的
    staging
    合并回
    devel
  • 但这不起作用,因为:

    • foreign
      分支是从其原始位置重新设置的,没有被压扁
    • 我不得不再次处理来自
      devel
      的所有冲突,而在
      devel
      本身的许多合并过程中,这些冲突已经得到了处理
    因此,我计划做以下工作:

    让我们调用
    div
    最新提交的
    devel
    不在
    master
    (最新分歧点)。如果
    master
    有未合并到
    devel
    中的新提交,则中止。也就是说,如果在
    div
    之后的
    master
    中有新的commit,则必须在此之前手动将它们合并到
    devel

    对于从
    div
    devel
    的每次提交(按拓扑顺序),执行
    git reset--soft
    ,并将更改提交到
    master
    (使用相同的提交消息)。这意味着:

    • 不在
      div
      之后,但在
      devel
      之前的提交将被压扁:这些提交要么是从
      foreign
      合并的(在这种情况下,我们很高兴),要么是从
      master
      合并的(在这种情况下,实际提交已经在master中)
    • 介于两者之间的提交会一个接一个地被正确地推送到
      master
      中,除了
      devel
      的并行分支之外,它每次看起来都像是提交撤消另一端(这很难看,但可能是不可避免的)
    最后,我将
    master
    合并回
    devel
    ,这个合并提交将成为下次的
    div

    由于我希望尽量减少“撤消”/“重做”的次数,我将对所选拓扑顺序添加以下限制:在
    devel
    中只有一个父级的提交将具有与
    master
    中的父级相同的提交

    总而言之,这似乎过于复杂。是否有一种内置方法可以使线性分支跟随非线性分支?否则,我的策略是否有效,或者我是否遗漏了真正重要的细节?

    如中所述,最好删除
    开发
    分支,将
    母版
    的功能分支拆分,并在合并到
    母版
    之前重新设置基础。完成要素分支后,可以执行以下操作:

    git rebase master myfeature
    git checkout master
    git merge --ff-only myfeature
    
    当您需要合并来自
    foreign
    分支的更改时,请执行以下操作:

    git merge --squash foreign
    git commit
    
    git merge
    的手册页:

    --squash

    生成工作树和索引状态,就像发生了真正的合并一样(合并信息除外),但实际上不进行提交,移动
    ,或记录
    $GIT\u DIR/merge\u头
    (以使下一个
    GIT commit
    命令创建合并提交)。这允许您在当前分支上创建一个提交,其效果与合并另一个分支相同(如果是八达通,则为多个分支)


    考虑到压缩提交和重定基址的风险性质,使用特性分支听起来并不是团队的解决方案。您可能希望直接提交给master(当然,没有功能分支那么理想,但是实现了您想要的线性历史,并且丢失提交的风险更小)。我认为您无法维护master和开发分支并实现此目标。您的最佳选择似乎是放弃开发,从主功能分支功能,然后在合并到主功能之前重新设置功能分支的基础。如果您想在合并到master之前“组装”功能分支,可以使用一次性集成分支,并尝试利用Reere避免在合并到master时必须重新进行合并冲突,那么
    外部
    分支呢?我无法重新设定它的基础(它不在我的控制之下)。