此处主要来自[Learn Git Branching],以及个人的一点点理解,当做记录使用
Git 基础篇(Git 主要命令)
1. Git Commit
Git 仓库中的提交记录保存的是你的目录下所有文件的快照,就像是把整个目录复制,然后再粘贴一样,但比复制粘贴优雅许多!
Git 希望提交记录尽可能地轻量,因此在你每次进行提交时,它并不会盲目地复制整个目录。条件允许的情况下,它会将当前版本与仓库中的上一个版本进行对比,并把所有的差异打包到一起作为一个提交记录。
Git 还保存了提交的历史记录。这也是为什么大多数提交记录的上面都有父节点的原因 —— 我们会在图示中用箭头来表示这种关系。对于项目组的成员来说,维护提交历史对大家都有好处。
git commit
2. Git Branch
Git 的分支也非常轻量。它们只是简单地指向某个提交纪录 —— 仅此而已。所以许多 Git 爱好者传颂:
早建分支!多用分支!
这是因为即使创建再多的分支也不会造成储存或内存上的开销,并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了。
- 创建一个到名为 newImage 的分支。
git branch bugFix
- 切换到改分支,如果该分支存在的话
git checkout bugFix
- 创建一个新的分支,同时切换到新创建的分支(如果该分支已存在,报错)
git checkout -b bugFix
- 如果 abc 分支存在,强制移动到 c1 提交点,如果不存在,创建一个 abc 分支,并强制移动到 c1 提交
git checkout -f abc c1
3. 分支与合并(git merge)
我们新建一个分支,在其上开发某个新功能,开发完成后再合并回主线。
第一种方法 —— git merge。在 Git 中合并两个分支时会产生一个特殊的提交记录,它有两个父节点。翻译成自然语言相当于:“我要把这两个父节点本身及它们所有的祖先都包含进来。”
- 把 bugFix 分支合并到现有的分支上
git merge bugFix
4. Git Rebase
第二种合并分支的方法是 git rebase。Rebase 实际上就是取出一系列的提交记录,“复制” 它们,然后在另外一个地方逐个的放下去。
Rebase 的优势就是可以创造更线性的提交历史,这听上去有些难以理解。如果只允许使用 Rebase 的话,代码库的提交历史将会变得异常清晰。
-
首先移动到 bugFix 分支上,然后把 bugFix 分支里的工作直接移到 main 分支上。
-
现在我们切换到了 main 上。把它 rebase 到 bugFix 分支上……
-
由于 bugFix 继承自 main,所以 Git 只是简单的把 main 分支的引用向前移动了一下而已
git checkout bugFix
git rebase main
git checkout main
git rebase bugFix
- 把 side 分支中不一致的提交按照顺序, 添加到 main 分支中
git rebase main side
Git 高级篇
1. 在提交树上移动 HEAD(分离 HEAD)
HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。
HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。
HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见。
如果想看 HEAD 指向,可以通过 cat .git/HEAD 查看, 如果 HEAD 指向的是一个引用,还可以用 git symbolic-ref HEAD 查看它的指向。
- 是 HEAD 指向 c4 提交点
git checkout c4
2. 相对引用(^ 和 ~)
使用相对引用的话,你就可以从一个易于记忆的地方(比如 bugFix 分支或 HEAD)开始计算。
相对引用非常给力,这里我介绍两个简单的用法:
使用 ^ 向上移动 1 个提交记录
使用 ~<num> 向上移动多个提交记录,如 ~3
- 以 bugFix 分支为基准,向上移动上一个提交点
git checkout bugFix^
- 以 bugFix 分支为基准,向上移动上3个提交点
git checkout bugFix~3
-
强制修改分支位置:我使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交。
-
把 main 分支(如不存在,创建该分支)以 HEAD 为基准,强制向上移动 3 个位置
git branch -f main HEAD~3
3.撤销变更(Git Reset 和 Git Revert)
Git Reset
git reset 通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成 “改写历史”。git reset 向上移动分支,原来指向的提交记录就跟从来没有提交过一样。
- Git 把 main 分支移回到 C1;现在我们的本地代码库根本就不知道有 C2 这个提交了。
git reset C2~1 //(或者 C2^ C2~2,必须添加)
(注:在 reset 后, C2 所做的变更还在,但是处于未加入暂存区状态。)
Git Revert
虽然在你的本地分支中使用 git reset 很方便,但是这种 “改写历史” 的方法对大家一起使用的远程分支是无效的哦!
为了撤销更改并分享给别人,我们需要使用 git revert。
git revert C2 //(不添加任何后缀,撤销一级, 或者 C2^撤销一级 C2~2,撤销 n 级)
奇怪!在我们要撤销的提交记录后面居然多了一个新提交!这是因为新提交记录 C2' 引入了更改 —— 这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2' 的状态与 C1 是相同的。
revert 之后就可以把你的更改推送到远程仓库与别人分享啦。
Git 移动提交记录(自由修改提交树)
1. 整理提交记录 (Git Cherry-pick)
git cherry-pick <提交号>...
如果你想将一些提交复制到当前所在的位置(HEAD)下面的话, Cherry-pick 是最直接的方式了。我个人非常喜欢 cherry-pick,因为它特别简单。
把 c2 c4 按照输入顺序添加到当前分支上(不能添加当前分支上的提交)
git cherry-pick c2 c4
2. 交互式的 rebase
当你知道你所需要的提交记录(并且还知道这些提交记录的哈希值)时,用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。
但是如果你不清楚你想要的提交记录的哈希值呢?幸好 Git 帮你想到了这一点,我们可以利用交互式的 rebase —— 如果你想从一系列的提交记录中找到想要的记录,这就是最好的方法了
交互式 rebase 指的是使用带参数 --interactive 的 rebase 命令,简写为 -i
如果你在命令后增加了这个选项,Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。
在实际使用时,所谓的 UI 窗口一般会在文本编辑器 —— 如 Vim —— 中打开一个文件。
当 rebase UI 界面打开时,你能做 3 件事:
调整提交记录的顺序(通过鼠标拖放来完成)
删除你不想要的提交(通过切换 pick 的状态来完成,关闭就意味着你不想要这个提交记录)
合并提交。 遗憾的是由于某种逻辑的原因,我们的课程不支持此功能,因此我不会详细介绍这个操作。简而言之,它允许你把多个提交记录合并成一个。
- 在 main 分支上重置上面上次的提交
git rebase -i main~4
3. Git Tags
指向某个提交记录的标识
- 在 c2 提交点设置 v1 的标签
git tag v1 c2
4.多个父节点直接的切换^2
- 切换到另外一个父节点,如果只有一个父节点则报错
git checkout main^2
网友评论