升级你的 Git 游戏并清理你的历史记录
这篇文章针对的是那些想要学习如何使用 rebase 等命令并学习一些技巧以获得更好的 Git 体验的人。
好吧,让我们先来看一下我在 Github 上最早的一些项目的 Git 历史记录:
哦不
哦不不不不不
哦天啊我做了什么
现在我已经嘲笑了自己,让我们看看我的大部分项目现在是什么样子的😄
噢,好多了
如果您不知道这一切意味着什么,让我简单解释一下:
这是您在 Github 上的 Git 历史记录的表示,即您在一段时间内对项目分支所做的提交。
您可以通过导航到您的某个项目的“Insights”选项卡,然后转到左侧的“Network”选项卡来查看您自己的项目。
黑色条代表我的master
分支,交替出现的蓝绿条代表不同的分支。
正如你在最近更新、更清晰的历史记录中看到的那样,它们交替地合并到主分支中,从而形成了编写代码并合并的良好流程(我们始终建议这样做,而不是堆积拉取请求)。
那么,如何才能拥有更清晰的历史记录呢?让我们来看看实际用例。
以下是我们今天要讲的内容(请确保按顺序完成每个部分):
魔力git rebase
Git rebase 可以让你根据自己的意愿重塑提交历史记录。你可以将其视为一种操作特定分支上提交列表的方法。
例如,你可以彻底删除提交(基本上就是在 git 的深渊中与它们告别)、重命名提交(重写提交信息)、将它们压缩到其他提交中(这对于隐藏那些执行诸如添加分号之类的小操作的提交很有用,因为你并不想在历史记录中看到它们)等等。
通过实践学习
转到我为此场合创建的以下项目,将其分叉然后让我们开始吧。
Fork 基本上就是为你自己创建一个我的项目的副本,你可以毫无问题地使用它!点击右上角的 fork 按钮即可:
然后,克隆您分叉的存储库。
示例 1:使用 rebase 修复提交
场景:您提交了一些不值得提交的内容,或者您想在发出拉取请求之前将分支上的提交次数减少为一次。
-
从该
master
分支创建一个新分支。 -
创建一个新文件,其内容并不重要。
-
将新文件提交到您的分支。
git add index.js
git commit -m "add index.js"
-
更新该文件中的某些内容
-
再次提交,并添加“更新 index.js”等消息
-
运行
git log
,如你所见,我们现在有 2 个提交
我们现在想要将fixup
提交update
纳入add
提交,因为这个小变化不值得单独提交。
为此,我们将使用 的交互模式git rebase
,该模式让我们能够通过良好的界面应用变基。
- 像这样运行 rebase 命令:
git rebase -i HEAD~2
HEAD~2
表示从分支(头部)的最后一次提交开始,回溯 2 次提交。如果我们想操作更多提交,可以更改最右边的值。
现在你应该看到一个类似这样的界面:
别担心,这只会在顶部显示您正在修改的两个提交,并在其下方显示可用的命令。
默认情况下,rebase 界面使用 Vim,要在其中写入,只需按i键即可。您现在处于“插入”模式。由于我们想在第一个提交中修复第二个提交,所以我们只需在第二个提交前面写入fixup
或f
而不是即可。我们的提交现在将被压缩到 中,但只有的消息会被保留。pick
update index.js
add index.js
add index.js
- 像这样更新第二行:
pick c0091ec add index.js
f a19336e update index.js
现在,我们要应用变基,按 Esc键退出INSERT模式,按:(冒号)并输入wq(分别表示“写入”和“退出”),然后按ENTER 键应用这些更改。冒号的作用是让你编写 Vim 需要执行的命令。
您的控制台中现在应该会出现以下消息:
已成功重新定位并更新 refs/heads/{YOUR BRANCH NAME}。
检查一下git log
,你现在有一个漂亮而干净的提交!
- 最后,强制推送到该分支以将 rebase 应用于远程服务器
git push origin {BRANCH-NAME} -f
这-f
很重要,因为 rebase 会修改你的 git 历史记录,并且需要强制执行。
示例 2:删除提交
接下来的两个步骤与第一步非常相似,因为你现在有了进行任何类型的 rebasing 的工具🎉
场景:您想要完全删除提交
我们将放弃add FILENAME
之前做出的提交:
- 运行 rebase 命令
git rebase -i HEAD~1
- 在您想要删除的提交前面添加
d
或。drop
-
在 Vim 编辑器中运行
:wq
(并检查git log
提交是否被删除) -
不要忘记将其强制推送到远程服务器😀
示例 3:重新表述提交
非常相似,但有一处变化。
场景:您想要修复拼写错误或重写提交的标题或描述
- 创建随机提交
- 运行 rebase 命令
git rebase -i HEAD~1
-
在您想要改写的提交前面添加
r
或reword
(现在无需编辑标题)。 -
在 Vim 编辑器中运行
:wq
。这将打开一个类似的编辑器,其中包含你想要修改的提交。
- 根据您的意愿更新提交的标题和描述,运行
:wq
即可!检查git log
是否已应用改写
- 不要忘记将其强制推送到远程服务器😀
示例 4:rebasemaster
此示例未在 Github 项目中重现,但请随意测试。
场景:您同时打开多个 PR(拉取请求)
您合并了一个 PR,现在,您的第二个 PR 不是最新的master
,哦不!
这种非常常见的情况会让我们重新设定我们的第二个 PR,master
以便它能够从第一个 PR 合并新的代码。
- 从您想要重新设置基准的分支(在我们的例子中是第二个 PR 的分支)运行以下命令:
git fetch
这将下载我们的分支应用变基所需的所有引用。
- 然后,像这样执行 rebase:
git rebase origin/master
- 最后,运行
git push origin {MY-BRANCH} -f
以将 rebase 应用到我们的远程服务器
好哇!
奖金:更好的git log
您是否git log
难以处理太多事情?
您是否想要一个git log
直截了当且看起来更美观的东西?
别再犹豫了!具体操作如下:在控制台中粘贴以下内容:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
现在,您已经为git log
called创建了一个别名git lg
,它将显示之前更漂亮的输出。您可以尝试输入以下命令git lg
(或git lg -p
查看更改的行)。
感谢Coderwall提供的奖励 ✨
强制推搡的危险及其他注意事项
正如 Nick Huanca 提到的,在团队合作中,强制推行可能会很危险:
因此,另一种选择可能是--force-with-lease
“允许强制推送,而不会无意中覆盖他人的工作。只有当远程引用的值与我们本地的远程跟踪分支的值相同时,它才会更新远程引用。”参考。感谢 Nick 提供的提示!😄
你可能已经注意到,他还提到了git rebase --abort
,这样一来,万一出现问题,我们可以中途停止 rebase。所以,如果你因为某种原因搞砸了 rebase,可以稍微 git 一下--abort
,然后重新开始。
总结
学习如何使用 Git 可能是我们作为开发人员所能掌握的最重要的技能之一。我希望你们中的一些人不会像rebase
我之前那样感到害怕。
如果这篇文章对您有帮助,请随时给它一个❤️🦄🔖并在 Twitter 上关注我@christo_kade!
文章来源:https://dev.to/christopherkade/up-your-git-game-and-clean-up-your-history-4j3j
谢谢你的文章!这是一篇很好的读物/复习文章。由于读者是想要提升 Git 水平的人,我建议添加一些关于“强制推送”危险的信息,并且谨慎引用强制推送,
--force-with-lease
这样可以避免人们意外覆盖团队推送的内容。:)另一件值得注意的事情是,
git rebase --abort
如果在 rebase 过程中出现意外情况(冲突或其他奇怪/意外的行为),应该如何处理。了解如何安全地退出命令总是有用的,尤其是在刚开始的时候。再次感谢!