何时需要使用git-rebase?

17
每次我阅读git-rebase文档时都会感到困惑。对我来说,它感觉像一种低级操作(也就是说:黑魔法)。
引用文档:
假设存在以下历史记录,并且当前分支为“topic”:
       A---B---C topic
      /
 D---E---F---G master 

从这个点开始,以下任一命令的结果:

git rebase master 
git rebase master topic 

将会是:

               A'--B'--C' 分支
              /
 D---E---F---G 主分支

问题是:为什么有人想这样做?

首先,它似乎"重新编写"历史,就好像分支在不同的点开始一样;本质上,提交记录将会是"一堆谎言"。

另一方面,它不太可靠。我试过一次,在合并时出现了很多冲突,所有的东西都乱套了。我不太记得当时是怎么解决这个问题的,但如果我没记错的话,那是在一个临时测试分支上进行的。

另一个问题是:我如果不知道如何使用git-rebase,是否会错过一些真正酷炫/省时的功能?

编辑:

相关问题:撤销 git rebase 的操作

4个回答

8
您需要使用它,例如当您想提交补丁代码给已修改的代码时。例如,如果您从软件的修订版1.56分支,并在此期间维护者移动到修订版1.57,则他/她可能只接受在修订版1.57上的补丁。
您将重置您的分支到修订版1.57,纠正所有冲突,验证并重新提交补丁。

我没有使用git来提交补丁,但是通过获取、合并,然后与“远程”分支进行差异比较有什么问题吗? - hasen
没有特别的要求。首先需要这个的原因是Git(不像Mercurial)不记录给定修订版本所在的分支。在Git中,一些团队更喜欢拥有开发/主分支的干净历史记录;因此,他们会将源分支变基(并可能将其压缩为目标分支上的单个修订版本)。在Mercurial中,如果您想要一个干净的分支历史记录,您只需过滤到该分支;分支名称是修订版本的组成部分。(副作用是在Mercurial中,分支是永久的,不能被重命名一旦发布。) - Mike Rosoft

8
首先,git中没有不安全的操作。rebase有一个中止操作,并且所有操作都会在reflog中进行记录,因此您可以撤消任何操作。事实上,情况恰恰相反。
它使您随时可以提交内容,而无需在构建“好”的版本之前等待。您发布的修订版可以通过将沿途采取的所有步骤压缩为单个提交来变得更加干净。
我经常使用rebase(通常通过pull进行配置,以在获取阶段后进行rebase)。不要认为这是重写历史--请将其视为提供一种工具,让您在发布之前清理草稿。
从现在起一年后,您的项目中是否重要知道您真正从修订版E开始实现该功能,而不是修订版G?
不必要的递归合并会掩盖历史中更重要的部分。

你能详细说明一下“撤销”这个东西吗?例如,如何撤销一个变基操作? - hasen
抱歉,我觉得我的一些评论被吃掉了。几乎每个改变存储库的操作都是通过添加新内容并指向它来完成的。Reflog会显示您以前的所有HEAD状态。您始终可以“reset --hard”到一个分支或者回溯。除非您尝试删除,否则这些信息不会在90天内丢失。 - Dustin
8
“git 中没有不安全的操作”这种说法是不正确的。尽管“git rebase”不会丢失任何信息,“git gc”(默认情况下,git会定期调用它)却会删除部分信息。即使在“git gc”不可逆地销毁信息之前,“git rebase”也会将信息埋藏在 reflog 中,需要一些挖掘才能找回。Rebase 是一个非常有用的工具,但不要误解:它是一种锋利的工具。 - mhagger
@mhagger:你能解释一下为什么git-gc会丢弃信息吗?我以为它只会删除不再被引用的东西? - sleske
1
@sleske "git rebase" 创建新的提交并将分支指向这些提交,不再指向旧的提交。因此,旧的提交可能会被垃圾回收(除非有另一个引用指向它们)。 - mhagger

5

一旦你把“topic”合并回“master”,你将不可避免地遇到这些冲突。因此,最好定期将“topic”变基到“master”上(如果你采取小步骤,比一次性采取大步骤更容易 - 至少我是这么认为的)。如果在合并之前进行变基,所有“有风险”的操作都发生在分支中,合并后很容易。


4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接