压缩提交:如何像专业人士一样维护 Git 提交历史
压缩提交:如何像专业人士一样维护 Git 提交历史
人们不会告诉你的行业惯例
Photo by 潘卡伊·帕特尔
嘿朋友们,
所以在我的页面上,我一直赞同你应该不断提交更改的想法。您永远不知道您的网站或应用程序何时会因代码更改而中断,因此您希望不断保存代码的工作版本。如果您的应用程序确实中断并且您确实无法确定问题点,您将始终拥有备份选项以恢复到以前的工作版本。没有伤害,没有犯规。如果你经常提交,恢复你的代码不应该是一个重大的倒退。如果这是一个重大的飞跃,你应该考虑更频繁地提交。
所以提交是惊人的!这有点类似于写一篇 20 页的文章并在你取得进展时不断地点击保存按钮。上帝禁止发生任何事情,你会失去你的工作。但显然 混帐
比这更强大。它实际上节省了 所有工作版本 你承诺。您可以时间旅行到您保存的任何版本。如果现在还不清楚为什么这很有用,我保证随着您编写代码和创建项目,它会变得更加明显。
无论如何,如果你尽可能频繁地提交——你完全应该这样做——你最终会得到一个冗长的提交历史。
例如:这是我的快照 提交历史 对于我制作的天气应用程序。
Weather App Commit History
您可以看到我何时将城市名称、天气信息、日期信息和欢迎消息添加到用户界面。您实际上可以阅读我在 git 提交历史中取得的进展。这就是 git commit 历史的全部内容。它应该是可读的,您应该了解进度的流程,并且每次提交都应该专注于一件事!
但问题是:当你在开发一个实际的专业产品时,官方提交历史中的每个提交都应该代表一个正在实现的功能。
例如,这是我为我创建的游戏的设置菜单 高级项目 .这很简单。用户可以提高/降低 Sound FX 和/或背景音乐的音量。如果用户将其中一个选项静音,则用于提高或降低音量的单选按钮会消失。
所以对于这个功能,我做了一些事情。首先,我必须实际渲染游戏中的图形。我必须收集用户输入并以某种方式保存数据。我必须确保其他游戏场景可以访问这些数据。我必须确保 UI 反映了数据。我必须对某些点击事件进行 UI 更改。我还研究了其他一些小细节。所以总的来说, 实施设置菜单是一项功能 .但正如您所看到的,此功能伴随着许多其他工作部分的实现。
在我们的官方 git 提交历史中,我们应该只看到一个完整功能的条目。提交消息应该类似于“实施设置菜单”。我不应该看到包含十几个项目的提交历史记录,例如:
- 渲染设置图形
- 渲染复选框和单选按钮
- 创建 onClick 事件处理程序
- 将数据保存在数据库或本地存储中
… 等等。
我们不应该看到实现该功能所需的所有微小细节。 我们不应该看到实现该功能所需的所有提交 .同样,我们应该只看到一个提交说我们实现了该功能。
为什么?好吧,当您在开发实际的专业产品时,您将与其他工程师一起工作。其他工程师同时在同一个存储库上工作以实现其他功能。想象一下每个工程师,包括你自己,都刚刚添加了他们所有的提交。您的 git 提交历史将不再可读。 git commit 历史会在特性之间来回跳转,你不会知道每个 commit 做了什么。它完全违背了拥有 git 提交历史的目的。
例如,这里是 git 提交历史 为游戏。
这个提交历史是一团糟。没有结构。我正在从键盘事件跳到游戏玩法,再到“游戏结束”屏幕再到错误修复。一团糟。如果其他工程师推挤在我的提交之间的不相关的提交,这种混乱将会变得更糟。
同样,为了保持它的整洁和可读性,我们应该只为整个功能添加一个提交。我们不应该添加实现该功能所需的所有提交。
这对你意味着什么?
对于初学者来说,这并不意味着你不应该尽可能频繁地提交。在开发功能时,尽可能多地提交。保留更多版本只会对您有所帮助。
当您完成该功能的实现时,对话才真正开始。此时,该功能仅存在于您的计算机上。更改和提交历史仅存在于您的计算机上。因此,在这一点上,我们将接受您的所有提交并将它们合并为一个。在我们将提交合并为一个之后,我们就可以 git 拉
和 git 推送
到远程存储库——也就是 GitHub、GitLab 或您的团队使用的任何托管服务。然后,正如我们一直在谈论的那样,官方提交历史只会显示整个功能的一次提交。
咚咚咚,搞定!
那么我们如何真正将所有提交合并为一个呢?
我们可以采取一些方法。
git rebase
git rebase -i HEAD~n
它在说什么?这就是说,从头开始(也就是最后一次提交),采取 n 最近的提交并将它们压缩为一个。
例子: git rebase -i HEAD~10
在此示例中,我们将最后 10 个提交压缩为一个。如果你想要最后 3 次提交,那就是 头~3
.希望你明白这一点。
运行此命令时,将打开一个交互式菜单。
Stack Overflow: 我如何将最后的 N 次提交压缩在一起?
交互式菜单看起来像这样。它将列出所有将被合并的提交。所以在上面的例子中,它将结合三个提交。
对于这个解释, 我们正在查看前三行 .上面,你看到命令 挑选
.后 挑选
,您会看到提交 ID 和提交消息。
要合并多个提交,您必须进行一些编辑。现在,它看起来像这样:
选择 ceb9dd6 保存更改
选择 6bcfc34 保存更改
选择 80853d8 保存更改
为了结合,我们必须将所有提交压缩到第一个提交中。因此,如果您有 10、20、30 或任何数量的提交,您将始终将它们压缩到第一个提交中。必须这样做。您可以尝试其他方式,但错误消息会告诉您同样的事情。
要执行壁球,我们只需将其重写为:
选择 ceb9dd6 保存更改
squash 6bcfc34 保存更改
壁球 80853d8 保存更改
同样,我们将提交压缩到第一个。或者,您还可以执行以下操作:
p ceb9dd6 保存更改
s 6bcfc34 保存更改
s 80853d8 保存更改
如果它不允许你在交互式菜单中写任何东西,只需点击 一世
插入。
如果你意识到你错过了一个提交(也许你的意思是合并 4 个提交而不是 3 个),你可以通过删除所有列出的提交来中止变基,使其为空白。
如果你已经完成并且你准备好变基了,点击键盘上的escape,然后 :wq
+ ENTER 保存您的更改。之后,您的提交将被压缩为一个。
如果您想重写提交消息以进行变基或任何一般提交,只需运行 git commit --amend
并替换提交消息。同样,如果它不允许您输入,请点击 一世
插入。保存,点击ESCAPE,输入 :wq
,然后按 Enter。
如果我的解释不充分,请查看 开发室 .我从这个资源中学到了,我一直向我的同行推荐这个资源。
git 重置
git reset --soft HEAD~n
这是您以前在我的页面上看到的命令。我将其作为撤消提交更改的命令呈现。这个命令基本上会撤消最近的 n 提交。
例子: git reset --soft HEAD~5
例如,在这里,它将获取 5 个最近的提交并将它们从提交历史记录中删除。您对这些提交所做的更改仍将被保留。它们只是准备提交的暂存文件。
执行重置后,您可以在一次提交下提交所有这些更改。
git 合并
还有 git 合并——壁球
.我个人从未使用过它。我之前谈到的前两种方法非常简单明了,所以我通常只使用这两种方法。如果您想了解有关使用压缩提交的更多信息 git 合并——壁球
, 我会推荐 你知道如何使用 Git Merge — Squash 吗? 经过 维克拉姆·古普塔
谁知道?也许它对你来说更直观。自己试试吧。
git commit - 修改
最后,我有一个最后的建议。这不是最好的解决方案。如果您还是 git 新手,它可能会使开发变得比实际需要的更加困难。但我一直在使用这个超过 git rebase
和 git 重置
.也许随着我的任务变得越来越复杂,这将不像现在这样可靠。谁知道?
我通常不会有这么多提交然后将它们压缩在一起,而是在整个过程中通常只有一个提交。当我进行更改时,我会经常提交我的代码的工作版本。但是,我不会进行全新的提交,而是“更新”我已经拥有的提交。
这是使用 git commit --amend
.
我认为最大的问题是还原您的代码。如果您仍处于该开发过程中并且实施尚未完成,那么恢复您的代码可能会更加困难。当您的代码的旧版本保留在他们自己的提交中时,您会收到突出显示您所在位置的提交消息。如果您需要恢复到特定版本,则更容易知道您应该恢复到哪个提交。
但如果你只是这样做 git commit --amend
?如果您不断更新相同的提交,您甚至可以恢复到以前的修改吗?是的。你完全可以。代替 混帐日志
, 你可以做 git reflog
每次修改提交时查看。唯一的问题是您不会知道每个修正案的作用。
这对我来说是个大问题吗?一点也不。我的代码更改保留在 CR(也称为代码审查)中,并且我只修改我的代码的工作版本。如果我的代码中断,恢复到我之前的提交通常没问题。也许在未来,随着我的任务变得越来越复杂,这将不是一种可行的方法。但就目前而言,它有效。
感谢您与我一起阅读和学习:)
当我还是一名没有经验的大学四年级时,我开始写这个博客。当时我什至不知道 Javascript 或许多这些 git 命令。现在我在硅谷的一家 FAANG 公司工作。这个博客一直在为这种转变而存在。坚持和我一起学习。我分享了很多关于我在此过程中学到的东西,这样你就可以从中学习并变得比我更好。
祝贺你。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明