我希望有 Git Rebase 简介
我新工作中最重要(也是最令人困惑)的 git 功能之一就是 rebase。现在回想起来,最糟糕的是找不到一份清晰的新手指南。所以,对于过去的我,以及任何像过去的我一样的未来开发者来说,这篇介绍是为你准备的!
还有一点,给大学时的我:用 Jekyll 搭建你的个人网站。别把你微薄的大学学费浪费在搭建 WordPress 网站上面了……
无论如何,请尽情享受!本文假设您具备 Git 和版本控制的基础知识,并且喜欢纸杯蛋糕。您很快就会明白为什么。
首先,为什么我需要重新设置某些内容?
假设你是一家名为“丘比特杯蛋糕”(Cupid's Cupcakes)的纸杯蛋糕店的初级开发人员。这家店有很多线上销售,并且有很多经验丰富的开发人员不断改进。你被雇佣来主要负责前端工作。
你的第一个任务是更新一个卡片组件。当人们寻找纸杯蛋糕时,每个纸杯蛋糕都出现在一张卡片中。所以你去仓库,拉取主分支的最新版本,从该分支创建一个新分支,然后开始工作!
几次提交之后,一切就绪了。卡片看起来更美观了,所有测试都通过了,甚至还优化了移动端的布局。剩下的就是将你的 feature 分支合并回 master 分支,让它上线!
但是等一下!
毫不奇怪,当您制作此卡片组件时,其他人也在网站上工作。
- 一名开发人员改变了导航
- 调整数据库字段以删除不需要的信息
- 关于每个纸杯蛋糕的附加信息
- 其他人通过商店的银行记录秘密挪用资金
所有这些更改都让你担心。如果有人合并了影响或与你所做的更改重叠的更改怎么办?这可能会导致 cupcake 网站出现 bug!如果你查看所做的不同更改,就会发现其中一项确实存在 bug!(另一项更改应该报告给警方,但这实际上不那么重要)。有没有一种安全的方法可以合并你的更改,而不会产生任何冲突的风险,也不会错过其他所做的更改?
类似这样的情况就是您想要重新设定基准的典型例子。
Rebasing 的细节是什么?
假设你从 master 分支创建了一个分支,master 分支的提交号是 1。你分支中的每个提交都基于 1 号提交。当你准备合并分支时,你发现其他开发人员做了一些更改,而最近的提交是 5 号提交。
变基操作会将你分支上的所有提交添加到提交 #5 之上,而不是提交 #1 之上。如果你将提交 #1 视为分支的“基础”,那么你实际上是将基础更改为最新的提交 #5。这就是变基操作的由来!
好的,那么我该如何 Rebase 某些东西呢?
你已经为丘比特的纸杯蛋糕制作出了这个很棒的卡片组件。既然你已经了解了什么是rebase ,让我们更详细地看看如何使用它。
首先,确保你拥有要 rebase 的分支的最新版本。在本例中,我们假设它是 master 分支。运行git checkout master
checkout 命令,然后运行git pull
获取最新版本。然后再次 checkout 你的分支——它应该显示为git checkout updated-card
或类似内容。
简单的 rebase 命令结构非常简单:git rebase <branch>
.branch
是你要 rebase 的命令。所以在这里你只需要运行git rebase master
. ,假设没有冲突,rebase 就完成了!
从技术上讲,rebase 本身会删除旧的提交,并生成与其完全相同的新提交,从而重写仓库的提交历史记录。这意味着将 rebase 推送到远程仓库需要一些额外的资源。使用git push --force
可以很好地完成操作,但更安全的选择是git push --force-with-lease
。后者会提醒您任何您未注意到的上游更改,并阻止推送。这样可以避免覆盖其他人的工作,因此它是更安全的选择。
至此,你的 rebase 工作就完成了!不过,rebase 并不总是那么顺利……
如何处理 Rebase 冲突?
还记得我们多么担心新卡片会与别人的更改冲突吗?结果,确实有!一位开发人员在新的纸杯蛋糕卡片上添加了额外的信息,例如卡路里计数或晚上制作纸杯蛋糕需要多少个精灵。两组更改的更新标记都在同一行 - 这意味着 rebase 无法自动进行。Git 不知道更改的哪些部分应该保留,哪些部分应该删除。这个问题必须解决!
幸好,git 让这一切变得非常简单。在 rebase 过程中,git 会将每个提交逐一添加到新的基上。如果遇到有冲突的提交,它会暂停 rebase,并在冲突修复后恢复。
如果您之前处理过合并冲突,那么变基冲突的处理方式基本相同。运行命令git status
会告诉您冲突的位置,并且两个冲突的代码段会并排显示,以便您决定如何修复它们。
一旦所有问题都修复完毕,add
并且commit
修改操作与普通合并冲突类似,那么运行git rebase --continue
git 就可以对剩余的提交进行变基。它会暂停以检查是否有其他冲突,一旦设置完成,你只需要push --force-with-lease
.
还有两个不太常用的选项你也可以使用。一个是git rebase --abort
,它会把你带回到开始 rebase 之前的状态。这对于你无法仓促做出决定的意外冲突非常有用。另一个是git rebase --skip
,它会完全跳过导致冲突的提交。除非是不必要的提交,而且你很懒,否则你可能不会经常使用它。
我可以对 Rebase 过程进行额外的控制吗?
可见,Git Rebasing 功能强大。正如某些知名英雄所言,能力越大,责任越大。值得庆幸的是,Rebasing 可以让你更好地掌控整个过程。
为此,只需在命令中包含--interactive
, 或, 标志即可!对于我们的纸杯蛋糕 rebase 来说,它将是。-i
git rebase -i master
这会显示所有即将 rebase 的提交列表。您可以选择停止并编辑哪些提交,跳过哪些提交,甚至可以合并一些提交!这里我不会讲得太详细,但这篇文章是阅读更多内容的一个很好的起点。
另请注意:所有这些都是通过 VIM 界面完成的,它非常实用,但学习起来却更加困难。要按原样运行 rebase,请按esc + : + w + q + enter
。我会把解释其含义以及 VIM 其余功能的教程留给其他人。
最后,一个有用的变基技巧:自动压缩!
在交互式 rebase 中,我想分享一个实用技巧,那就是自动压缩提交。也就是将两个提交合并在一起,并重命名新的提交。如果你有很多类似的小提交可以合并,或者需要修改旧提交,那么这个技巧就非常有用。Rebase 的“自动压缩”功能让这一切变得轻而易举。
假设我们的分支中已经有五次关于丘比特纸杯蛋糕新卡片的提交。然后我们意识到在第二次提交中漏掉了一个小细节!为了保持提交历史记录的整洁,我们需要将这个更改合并到第二次提交中。
我们使用fixup
提交来做到这一点,其操作如下:
- 进行并准备您的更改。
- 获取您想要添加的提交的 ID。例如,假设它是 123456ABCD。您可以通过运行 找到它
git log
。 - 修复提交的公式是
git commit --fixup <commitID>
。在本例中,我们将使用git commit --fixup 123456ABCD
。这将正常提交更改,但名称将与我们的第二个提交相同,并在前面加上“fixup!”。 - 接下来我们运行 rebase,但务必包含正确的参数!我们运行
git rebase -i --autosquash master
。 - 我们将看到交互式 rebase 的正常页面,其中所有提交都列在 VIM 界面中。但是我们的修复提交将位于第二个提交的正下方,并设置为自动合并到第二个提交中!
- 运行 rebase 后,你的提交将自动合并!如果发生冲突,它会像平常一样要求你解决,然后 rebase 将继续进行。
这对于更新提交非常有用,避免了大量“小修复”修改污染历史记录,避免繁琐和混乱。最好的提交历史记录应该讲述一个易于理解的故事。自动压缩功能可以避免被令人讨厌的脚注淹没。所以,好好利用它吧!
享受你的纸杯蛋糕吧!
希望这篇文章能帮助大家理解 git rebase 的基础知识、它的作用以及如何开始使用它。最终,我自己理解了 rebase,这使其成为我工作中常用且必不可少的工具。我希望其他初级开发人员也能做到这一点,避免像我一样在过程中遇到一些挫败感/推送后的恐慌。
毕竟,我们都想帮助更多人买到并享用纸杯蛋糕,不是吗?当然!Git Rebasing 就像所有美好的事物一样,让我们更接近这个目标。
文章来源:https://dev.to/maxwell_dev/the-git-rebase-introduction-i-wish-id-had