🌳🚀 CS 可视化:有用的 Git 命令
虽然 Git 是一个非常强大的工具,但我想大多数人都会同意,它也可能……是一场彻头彻尾的噩梦😐 我一直觉得,在脑海中想象使用 Git 时发生的事情非常有用:当我执行某个命令时,各个分支是如何交互的?它会如何影响历史记录?为什么当我硬重置 git master
,force push
回到 origin 并rimraf
删除.git
文件夹时,我的同事会哭?
我认为这将是创建一些最常见和最实用的命令的可视化示例的完美用例!🥳 我介绍的许多命令都包含可选参数,您可以使用这些参数来更改它们的行为。在我的示例中,我将介绍命令的默认行为,而无需添加(太多)配置选项!😄
合并
拥有多个分支非常方便,可以区分不同的变更,并确保不会意外将未经批准或损坏的变更推送到生产环境。一旦变更获得批准,我们希望将这些变更推送到生产分支!
将更改从一个分支转移到另一个分支的一种方法是执行git merge
!Git 可以执行两种类型的合并:快进或非快进🐢
现在这可能没有多大意义,所以让我们看看其中的区别!
快进 (--ff
)
当当前分支与我们要合并的分支相比没有多余的提交时,可以进行快进合并。Git 很懒,会首先尝试执行最简单的选项:快进!这种合并不会创建新的提交,而是将我们要合并的分支上的提交直接合并到当前分支中🥳
完美!现在,我们在分支上所做的所有更改都已dev
保存到master
分支中。那么,为什么没有快进呢?
不快进 ( --no-ff
)
如果你的当前分支与要合并的分支相比没有任何额外的提交,那就太好了,但不幸的是,这种情况很少见!如果我们在当前分支上提交了想要合并的分支所没有的更改,git 将执行非快进合并。
使用非快进合并时,Git 会在活动分支上创建一个新的合并提交。该提交的父提交同时指向活动分支和我们要合并的分支!
没什么大不了的,完美合并!🎉 该master
分支现在包含了我们在分支上所做的所有更改dev
。
合并冲突
尽管 Git 擅长决定如何合并分支和向文件添加更改,但它并不总是能独自做出这个决定 🙂 当我们尝试合并的两个分支在同一个文件的同一行上有更改时,或者一个分支删除了另一个分支修改的文件时,就会发生这种情况,等等。
在这种情况下,Git 会要求你帮忙决定要保留这两个选项中的哪一个!假设在两个分支上,我们都编辑了README.md
.
如果我们想合并dev
到master
,这会导致合并冲突:您希望标题是Hello!
还是Hey!
?
尝试合并分支时,Git 会显示冲突发生的位置。我们可以手动移除不想保留的更改,保存更改,再次添加更改的文件,然后提交更改🥳
太棒了!虽然合并冲突通常很烦人,但这完全说得通:Git 不应该仅仅假设我们想要保留哪些更改。
变基
我们刚刚了解了如何通过执行 将更改从一个分支应用到另一个分支git merge
。将更改从一个分支添加到另一个分支的另一种方法是执行git rebase
。
A从当前分支git rebase
复制提交,并将这些复制的提交放在指定分支的顶部。
太棒了,现在我们在分支上所做的所有更改都已master
保存到分支上了dev
!🎊
与合并相比,一个很大的区别是,Git 不会尝试找出哪些文件应该保留,哪些不该保留。我们正在 rebase 的分支始终包含我们想要保留的最新更改!这样,您就不会遇到任何合并冲突,并且还能保持良好的线性 Git 历史记录。
此示例展示了如何在master
分支上进行 rebase。然而,在大型项目中,通常不需要这样做。由于会为复制的提交创建新的哈希值,因此git rebase
会更改项目的历史记录!
当你在功能分支上工作,并且 master 分支已经更新时,rebasing 就非常有用了。你可以获取分支上的所有更新,从而避免将来发生合并冲突!😄
交互式变基
在 rebase 提交之前,我们可以修改它们!😃 我们可以使用交互式 rebase来实现。交互式 rebase 在你当前正在处理的分支上也很有用,并且可以帮助你修改一些提交。
我们可以对正在重新定基的提交执行 6 个操作:
reword
:更改提交消息edit
:修改此提交squash
:将提交合并到上一个提交中fixup
:将提交合并到前一个提交中,但不保留提交的日志消息exec
:在我们要重新基准的每次提交上运行命令drop
:删除提交
太棒了!这样,我们就可以完全控制我们的提交了。如果想删除某个提交,直接删除即可drop
。
或者如果我们想将多个提交压缩在一起以获得更清晰的历史记录,没问题!
交互式变基使您可以对尝试变基的提交进行大量控制,即使在当前活动分支上也是如此!
重置
我们可能会提交一些之后不想要的更改。这可能是一个WIP
提交,也可能是一个引入了 bug 的提交!🐛 在这种情况下,我们可以执行git reset
.
Agit reset
摆脱了所有当前暂存的文件并让我们控制HEAD
应该指向的位置。
软复位
软重置移动到HEAD
指定的提交(或与 相比的提交的索引HEAD
),而不会摆脱之后提交中引入的更改!
假设我们不想保留9e78i
添加style.css
文件的提交,也不想保留035cc
添加index.js
文件的提交。但是,我们想保留新添加的style.css
文件index.js
!这非常适合软重置。
输入 后git status
,你会看到我们仍然可以访问之前提交的所有更改。这很棒,因为这意味着我们可以修复这些文件的内容,并在稍后再次提交它们!
硬重置
有时,我们不想保留某些提交引入的更改。与软重置不同,我们不应该再访问这些更改。Git 应该简单地将其状态重置回指定提交时的状态:这甚至包括工作目录和暂存文件中的更改!💣
9e78i
Git 已丢弃在和上引入的更改035cc
,并将其状态重置为提交时的状态ec5be
。
恢复
撤消更改的另一种方法是执行git revert
。通过还原某个提交,我们会创建一个包含已还原更改的新提交!
假设我们ec5be
添加了一个index.js
文件。后来,我们意识到我们不再需要这个提交带来的更改了!那就撤销这个ec5be
提交吧。
完美!提交9e78i
撤销了提交引入的更改ec5be
。执行此操作git revert
非常有用,可以撤消某个提交,而无需修改分支的历史记录。
挑选
当某个分支包含一个提交,该提交引入了我们在活动分支上所需的更改时,我们就可以执行cherry-pick
该命令!通过cherry-pick
ing 提交,我们在活动分支上创建一个新的提交,其中包含由 ed 提交引入的更改cherry-pick
。
76d12
假设分支上的提交对我们想要添加dev
到分支中的文件进行了更改。我们不需要全部,我们只关心这一个提交!index.js
master
太棒了,主分支现在包含引入的更改76d12
!
获取
如果我们有一个远程 Git 分支,例如 Github 上的一个分支,那么远程分支可能会有当前分支没有的提交!也许另一个分支合并了,或者你的同事推送了一个快速修复,等等。
我们可以在远程分支上执行 ,将这些更改本地化到本地git fetch
!它不会以任何方式影响您的本地分支:fetch
只是下载新数据。
现在,我们可以看到自上次推送以来所做的所有更改!既然新数据已经存储在本地,我们就可以决定如何处理它们了。
拉动
虽然 agit fetch
在获取远程分支信息方面非常有用,但我们也可以执行 a git pull
。 Agit pull
实际上是两个命令合二为一: agit fetch
和 a git merge
。当我们从源站拉取更改时,我们首先像使用 a 一样获取所有数据git fetch
,然后将最新的更改自动合并到本地分支中。
太棒了,我们现在与远程分支完美同步,并拥有所有最新的更改!🤩
引用日志
每个人都会犯错,这完全没问题!有时候,你可能会觉得自己把你的 git 仓库搞砸了,甚至想把它彻底删掉。
git reflog
是一个非常有用的命令,可以显示所有已执行操作的日志!这包括合并、重置、还原:基本上是任何对分支的修改。
如果您犯了错误,您可以HEAD
根据我们提供的信息轻松地重新进行操作reflog
!
假设我们实际上并不想合并 origin 分支。执行git reflog
命令时,我们会看到合并前仓库的状态是HEAD@{1}
。让我们执行 ,git reset
将 HEAD 指向原来的HEAD@{1}
!
我们可以看到最新的动作已经被推送到了reflog
!
Git 有太多实用的“瓷器”和“管道”命令了,真希望我能把它们都讲一遍!😄 我知道还有很多其他命令或修改,我现在没时间讲解——告诉我你最喜欢/最有用的命令是什么,我可能会在另一篇文章里讲解!
和往常一样,欢迎随时联系我!😊
文章来源:https://dev.to/lydiahallie/cs-visualized-useful-git-commands-37p1