get commit
在当前分支创建一个提交记录
分支
创建新分支
git branch <branch-name>
创建分支后直接使用
git commit
并不会在新分支产生提交记录, 这是因为没有切换到新分支.
git 工具会使用*
来提示你目前所在的分支.
git checkout <branch-name>
切换到名为 branch-name
的分支, 这个时候提交就可以在该分支下产生新提交记录了.
把这两个功能整合起来的命令:
git checkout -b <branch-name>
合并
对于同一父节点有着不同的分支, 这两个分支表示各有一个独立提交.
把branch-name
合并到 main
里:
git merge <branch-name>
这会产生一个新节点 C4
, 其父节点为 main
和 branch-name
的最新提交记录所表示的结点(C2
和C3
).
在此基础上再将 main
合并到 branch-name
, 因为此时 main
继承自 branch-name
, 所以只会把 branch-name
代表的指针移动到最后产生的结点(C4
)
Rebase
这是另一种合并分支的方法, 就是去除一系列的提交记录, 将其在另一个地方逐一执行. 这可以让代码库的提交历史变得更清晰.
假设 main
和 bugFix
的分支自结点C1
, 各自的最新提交记录结点为 C2
和 C3
, 目前所在分支是 bugFix
.
C2
和 C3
的工作可以是并行的.
现在使用 rebase
命令实现合并, 这会使得两个分支的功能像是顺序实现的.
git rebase main
这会产生一个新结点C3'
, 其父节点为 C2
, main
停留在 C2
, bugFix
停留在 C3'
, 目前所在分支仍然为 bugFix
.
现在我们需要使 main
得到更新:
git checkout main;git merge bugFix;
因为 bugFix
继承自 main
, 所以git 要做到以上指令, 只需要将 main
指针移动到 C3'
即可.
目前所在分支为 main
.
分离
如何在提交树上移动?
Head 是一个对当前分支的符号引用, 它用来指代当前分支的最新提交记录. 这也意味着 Head 会随着你的提交而更新.
现在我们要让 HEAD 指向 具体的提交记录而并非分支名.
假设这样一个状态:main*指针指向最新提交记录C1, HEAD 指向 main.
即
HEAD -> main -> C1
我们执行命令:
git checkout C1
这样就变成了
HEAD -> C1
当然在具体的操作实践中, 结点的记录不会像 C1
这样简单, 而是一个更复杂的哈希值(可以长达40位!).
相对引用
Git 对于哈希值的处理有一定的智能, 它允许你可以只使用哈希值的前几个字符来指代对应的提交记录, 而无需将哈希值完整写出.
你可以通过
git log
来查看提交记录的哈希值.
如果是通过相对引用, 就可以不用使用哈希值.
两种常见的移动方法:
-
使用
^
向上移动一个提交记录具体用法是将^加在引用名称的后面, 比如
git checkout main^
将
HEAD
切换到main
的父节点.HEAD
本身也可以作为引用名称的对象. -
使用
~<num>
向上移动num
个提交记录git checkout HEAD~4
这将使得
HEAD
指针移到HEAD
的第四个父节点.
使用 -f 来让分支指向另一个提交.(-f 代表强制)
git branch -f main HEAD~3
这会将 main
分支强制指向 HEAD
的第3级父提交.
撤销变更
有两种实现方法:
-
git reset
这会使得提交记录回溯, 原来指向的提交记录会被代码库忽略.
但是原提交记录所作出变更还在, 只是没有加入暂存区.
这个只适用于本地代码库, 对于远程分支是无效的.
-
git revert C2
为了将撤销更改分享给别人, 需要用到这个指令.
这会产生一个新的提交记录结点C2’, 这个更改是用来撤销C2的. 即 C2’ 状态也就是 C1.
注意辨别两个指令在使用的时候所使用的坐标是谁.
整理提交记录
现在我们需要处理更复杂的工作流了.
git cherry-pick <commit>
假设 C2
和 C5
分支自共有父节点 C1
, 而C2
后的提交记录分别是C3
, C4
.
现在main
指针指向 C5
, side
指针指向 C4
. 且当前所在分支为main
.(git 工具会提示你main*
)
我们执行
git cherry-pick C2 C4
这会使得 C5
后依次出现新提交记录 C2'
和 C4'
, 并且 main*
指向C4'
.
交互式 rebase
在我们并不清楚提交记录的哈希值的时候, git 提供了一个方法.
--interactive
或者 -i
, 这会使 Git 打开一个 UI 界面并列出提交记录的哈希值和提交说明.
在实际操作中, 这个 UI 窗口可能仅仅只是一个文本编辑器中的界面. VS Code 中的代码管理会比这个更人性化一些.
具体来说里面有若干个提交记录, 通过鼠标点击拖动来调整或者忽略这些结点顺序.
只取一个提交记录
为了调试而在代码中添加了一些调试命令, 这部分代码在正式的 使用中显然是不会用到的.
实际上我们只需要’刚好能解决问题并且没有任何调试代码’的那一个提交记录就可以了.
我们可以借助之前所学的命令来达成这一目的.
-
git rebase -i
-
git cherry-pick
git checkout main;
git cherry-pick bugFix;
或者
git rebase -i main bugFix;
git branch -f main HEAD
提交的技巧
假设在 newImage
分支进行了一次提交, 又在这个提交基础上创建了 caption 分支, 然后又在 caption 分支上进行了一次提交.
现在如果要对 newImage
中的提交进行修改, 就需要进行一些修改和排序.