发现一篇非常好的通过图示的方式介绍 Git 常用命令的工作原理。
object 类型
Git object 类型
- blob 类型:存储文件内容,不包括文件名等其他信息
- tree 类型:当前目录结构打了一个快照
- commit 类型:存储一个提交的信息,包括对应目录结构的快照 tree 的哈希值、上一个提交的哈希值、提交的作者、提交时间和提交信息
- tag 类型:在添加含附注的 tag 时会新建
merge
git merge 的两种合并策略
- fast-forward:默认策略,发生在当前分支对比将合并分支没有额外的 commit 时,不会创建新的 commit
- no-fast-forward:发生在当前分支有额外的 commit 时,创建一个新的 commit,commit 的父 commits 指向当前分支和合并分支
rebase
git rebase
- 复制当前分支的 commit,并将这些复制的 commit 放在指定分支的顶部,没有创建新的 commit,保持一个线性的提交历史,这就是为什么 git rebase 提交历史会很清爽
- 不同于 merge 的是,变基的分支总是有最新的改动,因此你不会陷入合并冲突,同时保持线性的提交历史
- 需要注意的是,rebase 会为复制的 commit 创建新的 hash commit id,这会改变项目的 commit 历史。变基当你工作在特性分支时十分好用,当 master 分支更新时,你可以得到所有的更新,这将避免将来的合并冲突,因此一般我们把别的分支合并到 master 时用 merge,而把 master 合并到别的分支时会用到 rebase
Interactive Rebase
Interactive Rebase - 交互式变基
- reword 修改提交信息
- edit 修改提交
- squash 将提交合并到前一个提交中
- fixup 将当前提交合并到之前的提交中,不保留提交日志信息
- exec 在每一个需要变基的提交上执行一条命令
- drop 删除提交
reset
git reset
- soft:撤销 commit,相关更改内容放在暂存区,可继续提交
- hard:撤销 commit,清空工作区和暂存区
- mixed:默认值,撤销 commit 和 stage,相关更改内容均放工作区中。
misc
其他小内容
- git revert 用于还原某次提交的修改,会创建一个包含已还原更改的新提交记录
- git cherry-pick 用于从其他分支挑选特定的 commit 到当前分支
- git checkout - 身兼多职
- 常规用法:用于操作分支
- 恢复文件到之前的某个状态,需要使用
--
参数,用于回到最近一次git commit
或git add
时的状态
- HEAD ~ vs ^
- ^ 找父 commit,^^ 表示父亲的父亲。在 merge 的情况下,你会有多个父提交,比如 git merge br1 br2 br3,注意这里的顺序很重要,此时你会有三个父提交,依次是 br1、b2、br3 分支上最新的 commit。当一个提交有多个父提交时,可以在后面跟上一个数字,表示第几个父提交,^ 相当于 ^1
- ~n 相当于连续的 n 个 ^
pull-request strategy
gitlab 等平台常用策略
- squash commit
- merge commit
- rebase then fast-forward
- rebase then create merge commit