Git &引用;“反向重基”;或;重新定位到这一点上;吉特

Git &引用;“反向重基”;或;重新定位到这一点上;吉特,git,Git,目前,我最常用的工作流之一是: git checkout branch git rebase master git checkout master git reset --hard branch 换句话说,我想在这个分支上重新设置分支的基址,并将其设置为新的基址。有内置的吗?或者你必须开始制作别名之类的东西吗?我不知道你为什么要运行这些命令。让我们看看这些命令的作用。假设你有一个分支 A - B - C [master] \ D - E [branch] git签出分

目前,我最常用的工作流之一是:

git checkout branch
git rebase master
git checkout master
git reset --hard branch

换句话说,我想在这个分支上重新设置分支的基址,并将其设置为新的基址。有内置的吗?或者你必须开始制作别名之类的东西吗?

我不知道你为什么要运行这些命令。让我们看看这些命令的作用。假设你有一个分支

A - B - C [master]
     \
      D - E [branch]
  • git签出分支
  • git重基主控器
好的,这是使用rebase用master更新分支的正常方法

  • git签出主机
  • git重置--硬分支
最后,分支“合并”到主分支中。这是处理合并的一种方法。我想你这样做是为了你有一个很好的线性历史

通过将
git reset--hard branch
替换为
git merge branch
,您可以更安全地执行此操作。这是更安全的,因为如果master是分支的直接祖先,那么master将快速前进到分支,并且您将具有相同的效果

但如果主人不是分支的直系祖先呢
git合并分支
将合并,并且您仍然有一个合理的历史记录。但如果您运行了
git reset--hard branch
,那么master将被丢弃。例如,假设由于某种原因,您忘记了git-rebase-master,或者它失败了,或者您在它之后运行了另一个命令,导致了这种情况

A - B - C [master]
     \
      D - E [branch]
git reset——硬分支将悄悄地抛出master。这个错误很难发现

A - B
     \
      D - E [branch] [master]
然而,
git merge master
将执行合并,master仍然有意义

A - B - C - F[master]
     \     /
      D - E [branch]

但我得到了一个丑陋的合并提交和一个更丑陋的历史

并非所有合并提交都是丑陋的。丑陋的是“更新”提交,它们只是内务管理。这就是你在git checkout branch中避免的;git rebase主机
。但是,当最终合并一个功能分支时,您希望合并提交保留一个分支存在的事实、它的用途以及其中的提交内容。该上下文对于理解代码非常重要

我建议您改为:

  • git签出分支
  • git重基主控器
  • 测试分支是否工作
  • git签出主机
  • git合并--无ff分支
按正常方式更新分支,结果与以前一样

A - B - C
         \
          D1 - E1 [branch] [master]
但后来情况就不同了。第一个变化,以及为什么不应该自动化整个过程,是在将分支合并到主分支之前验证分支是否工作。这样可以避免破坏主界面。在重新基址之后,分支将与合并到主节点中的分支完全相同,所以测试分支还将验证合并的主节点

第二个更改是使用
gitmerge--no ff
强制合并,即使不需要合并。结果就是这样

A - B - C ------- F [master]
         \       /
          D1 - E1 [branch]
这更好,因为它都提供了一个线性历史记录(即,
git log
将提交显示为F、E1、D1、C、B、a),并且它保留了D1和E1作为一个分支一起完成的情况。这是未来人们试图理解你的代码的重要背景。分支中的提交通常非常小,如果在分支的上下文中理解它们,则更有意义

A - B - C [master]
     \
      D - E [branch]
当您对下一个分支执行此操作时,仍然会得到一个良好的线性历史记录。结果是一系列没有交叉的近特征气泡

A - B - C ------- F ------- I [master]
         \       / \       /
          D1 - E1   G1 - H1 [branch2]
最后,merge-commit提供了一个提供更多分支上下文的地方。您可以描述分支的目的,也可以简单地在问题跟踪器中创建指向问题的链接


未来的代码考古学家将为此感谢您。

为了澄清,您希望将分支A重新设置到主节点上,然后将主节点重置为分支A的等效节点?首先,请在文本中解释您希望执行的操作,而不是使用git命令。你写的是“沿着……的路线”,那么,是沿着……的路线(因此不完全像那样)还是完全像那样?@TheGeorgeous确切地说,你为什么要运行这些命令?此工作流用于什么?这是合并已完成分支的方式吗?不,如果您刚刚重新设置分支的基础,则不会得到合并提交。合并将快速前进。我知道如何进行
--no ff
合并,并且在适当的时候使用它。但绝大多数时候,我只是在做一些小的承诺。如果我要对所有这些文件进行合并提交,我需要一个4k屏幕来显示
gitk
——这就是问题所在。@JV同样,这种技术会导致线性历史。因为在合并之前,每个分支都首先重设为主分支的基础,所以这些分支不会重叠。这使gitk可以将master和所有合并的分支显示为两列,一列显示master,一列显示分支。每个分支都会产生一个小凸起。举个例子,看看我知道。这不是问题所在。问题是,这个工作流与我问题中的代码片段相同,
reset--hard
替换为
merge--no ff
——引用问题的相关部分:“是否有一个内置的,或者你必须开始制作别名和其他东西?”@JV是的,你必须开始制作别名和其他东西。我没有为此烦恼,因为工作流是基于一个不正确的假设,即不能同时拥有合并和整洁的历史记录。而且,正如我在回答中所说的,您不希望自动执行此操作,因为这将导致将未经测试的代码放入master。
A - B - C ------- F ------- I [master]
         \       / \       /
          D1 - E1   G1 - H1 [branch2]