深入理解Git - 一切皆commit (2)

可以使用 git show 命令查看一个提交的详细信息,
因为 commitId/HEAD/branch/tag/origin-branch 这些都是指向一个提交,所以 show 命令后面写任意一个都可以。
另外,还可以使用其他参数控制显示内容,这里不展开。

git show commitId/HEAD/branch/tag/origin-branch --format=short 3 一切皆 commit :动词部分 3.1 cherry-pick

cherry-pick 比较好理解,就是将一个指定提交的修改摘取过来,举例:

深入理解Git - 一切皆commit

如图,6 提交是增加一个有用的 helper 类(间接说明,一个 commit 最好功能独立),但你不想将整个分支合并过来,就可以使用 cherry-pick 命令。使用任何一个指向 6 提交的引用都可以。
需要说明的是,cherry-pick 过来的提交,只是内容与之前的提交一样,他们是两个不同的提交。

案例

做了两个提交的修改,然后删掉分支了,过会发现刚才两个提交有价值,怎么找回来?

Step1 使用 git reflog 查看之前的提交历史,找到需要找回的提交ID。

深入理解Git - 一切皆commit

Step2 使用 cherry-pick 命令将需要的提交摘取出来即可。

如何丢失的提交比较多,除了可以批量 cherry-pick 之外,根据实际情况,可以直接在那些提交的最新提交上,新建一个分支,那些提交在此之前的所有提交,都在新的分支上了。

新建分支(03620f1 指提交号/commit id):

git branch newbranch 03620f1 git checkout -b newbranch 03620f1 3.2 rebase

如果用一句话理解 rebase 的话,就是:rebase = 一连串自动的 cherry-pick 。

关于 rebase ,需要回答三个问题:

为什么推荐使用 rebase 而不是 merge?

为什么听说过使用 rebase 会被打?

使用 rebase 有什么问题(什么情况不用 rebase )?

rebase 究竟是什么意思?

深入理解Git - 一切皆commit

如上图,假设 dev 上的提交是 1-2-3-4-5,f/table 分支上的提交是 1-2-3-6-7。现在我们需要合并 dev,通常,会使用 (@f/table)git merge dev 的方式合并。这里,我们使用 rebase 来合并 dev 。

首先,rebase 会找到 dev 和 f/table 共同的父提交,即 3 提交。然后以 dev 最新的提交为基础,把 f/table 分支上新的提交(这里就是 6 和 7),逐个 cherry-pick 过来。形成新的 f/table 分支。

注意,整个过程中,对 dev 分支不会有任何影响,因为你是在 f/table 上进行的操作。所有,rebase 的中文翻译,变基,就可以理解为:变基:用 cherry-pick 的方式,给 f/table 上的新提交,换一个基,将基从之前的 3 换到了 dev 所指的提交 5 上。

问题1 为什么推荐使用 rebase 而不是 merge?

深入理解Git - 一切皆commit

当使用 merge 时,提交历史如右侧所示,使用 rebase 的提交历史如下侧所示。
提交历史更清晰,当分支非常多时,回溯提交与查找问题更容易。

问题2 为什么听说过使用 rebase 会被打

使用 rebase 会修改提交历史,上面的例子中,6和7提交将不在 f/table 分支上存在,取而代之的是8和9分支,在协作分支上,如果6和7已经存在于远端仓库(即别人可能已经基于此有了新的修改),再将6和7移除,将带来诸多冲突与合并的麻烦。(这是,你 push 时,也需要强推,在协作分支上强推,是很危险的行为。)
所以:rebase只对本地未推送的commit上或自己的分支上进行。

深入理解Git - 一切皆commit

问题3 使用 rebase 有什么问题(什么情况不用 rebase )

使用 rebase 的收益:更简洁清晰易回溯的提交历史。

使用 rebase 的代价:逐个 cherry-pick ,如果有冲突,需要逐个解冲突,使合并变复杂。

以合并 dev 分支为例,当工作分支已经做了大量修改(有很多提交,预期有许多冲突),或者之前 merge 过 dev。则建议使用 merge 的方式合并 dev。

rebase 小结:
rebase : 一连串的 cherry-pick。(移花接木)

3.3 reset

reset,重置,将当前分支的状态(这里指工作区,暂存区,代码仓库)重置到指定的状态。reset 的语法如下图,第一个参数是重置方式,后面是一个指向提交的引用(可以是提交ID,分支,tag,HEAD~1等等)。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppxfz.html