Git pull.rebase这是一个可能很危险的操作

erk*_*fel 14 git git-pull git-rebase

git-config文档中有关pull.rebase的信息:

pull.rebase

如果为true,则rebase在获取的分支顶部分支,而不是在运行"git pull"时合并默认远程的默认分支.请参阅"branch..rebase"以在每个分支的基础上进行设置.

注意:这是一个可能危险的操作; 除非您了解其含义,否则不要使用它(有关详细信息,请参阅git-rebase(1)).

谁能详细描述一下"NOTE: this is a possibly dangerous operation; do not use it unless you understand the implications (see git-rebase(1) for details)"是什么意思?

Pik*_*ass 17

假设你有这些Git存储库:

  • 你的私人仓库,坐在你的工作电脑上;
  • 你的公共回购you,托管在某个地方;
  • 一个主要的回购,origin这是主要的开发树.

你正在做一些事情,做了两个提交A和B.你把它们发布到你的公共仓库.在同一时间,origin有另一个提交Z.

     /-A-B master, you/master
o-o-o
     \-Z origin/master
Run Code Online (Sandbox Code Playgroud)

现在让我们假设一位同事需要你的两个提交来开始一个新功能.他从你的公共回购中抽出你的分支并做出一些提交.

          /-C-D-E colleague/master
     /-A-B master, you/master
o-o-o
     \-Z origin/master
Run Code Online (Sandbox Code Playgroud)

您现在想要添加两个经过完全测试的提交origin/master.您从中获取origin并生成一个rebase(与pull.rebase选项集等效git pull --rebase或相同git pull).这会创建两个提交.你把它们推送到你的公共回购和origin.为了进一步复杂化,我们假设origin在此之后推送新的提交F.

     /-A-B-C-D-E colleague/master
o-o-o
     \-Z-A'-B'-F master, you/master, origin/master
Run Code Online (Sandbox Code Playgroud)

现在的问题是,你的同事有一些基于两个"弃用"提交的工作,并且为了避免进一步的复杂化(合并时的冲突,弄乱历史),他必须在B'之上重新分支他的分支(让我们说他不想要F).你需要告诉他这个,否则也许他不会注意到你做了什么.

            /-C-D-E colleague/master
o-o-o-Z-A'-B'-F master, you/master, origin/master
Run Code Online (Sandbox Code Playgroud)

如果你没有告诉他,之后他会将他的分支合并回原点,历史将如下所示:

     /-A-B-C-D-E
o-o-o           \
     \-Z-A'-B'-F-M colleague/master, origin/master
Run Code Online (Sandbox Code Playgroud)

你有两次A和B提交,但名称不同.历史变得更难阅读,你遇到可怕的合并冲突.请记住这个例子非常简单.如果有数十人参与该项目,并且origin正在快速行动,那么历史将很快变得一团糟.

如果只有一位同事,那可能就好了.但如果你不知道究竟是谁从你那里撤了过来,你就无法知道你有谁在警告.在开源开发中尤其如此.

主要规则是:不要重新设置已经发布的提交.如果A和B只在您的私人仓库中,那么退货很好并且可能是最好的事情,因为它使历史变得更加简单和有意义.分支历史只有在分支有充分理由存在时才有意义(例如特征分支).

  • 如果您只与一个远程存储库交互:是的,恕我直言,这可能是最佳实践。如果您有多个遥控器,那么不行,您必须小心哪些提交已经推送到某处,并且可能会被“pull --rebase”重新设置基础。 (2认同)
  • @jrahhali 取决于你所说的“推到原点”的意思。您是否将它们放在远程服务器上的特定分支中?你想在 master 之上重新调整它们吗?那么不,这并不危险。在这种情况下,变基基本上是复制粘贴(并解决冲突)。但是,如果您要推送到提交所在的同一分支(例如,因为您使用“git rebase -i”编辑了它们),则必须强制推送,这很容易出现竞争条件。当然,如果您知道没有人在您的提交之上工作,那也不是问题。 (2认同)

小智 10

Rebase是一个用于重写提交历史记录的命令,重写提交会导致其SHA ID发生变化.重新定位你自己的私人提交,没有其他人基于他们自己的工作(即作出提交)很好.

但是,在重新分配共享公共历史记录时会遇到麻烦,因为具有旧历史记录的其他人在新历史记录之上被强制同步或重做其提交(这可能是一个困难的过程),或者尝试用新的历史解决旧的历史,这肯定会产生冲突.从官方Linux Kernel Git文档中rebase:

重新定位(或任何其他形式的重写)其他人基于其工作的分支是一个坏主意:它下游的任何人都被迫手动修复其历史记录.

因此,您不应该重新提交提交,除非您确定没有其他人共享您正在进行重新设置的提交.

也就是说,你应该学会以交互方式和非交互方式学习,因为它是Git武器库中最强大和最有效的工具,如果你不知道如何使用它,那么你就不会有效地使用Git .

您可以从免费在线Pro Git书重写历史部分了解更多关于变基的知识,当然还有正式的Linux Kernel Git文档.rebase