merge操作
git checkout -b bugFix
git commit //在bugFix branch上操作,并且commit
git checkout main
git commit //在main上操作,并且commit
git merge bugFix //此时on main branch,如果在bugFix branch执行merge bugFix,会提示分支已经是最新当然也可以在别的分支上merge别的分支
//git checkout -b new_branch
//git merge bugFix //需要指出要merge哪一个分支,最终merge结果在当前分支
通过前面的main branch上执行git merge bugFix。将bugFix分支上的改动合并,从而得到新的main branch。此时c4的父类是c2和c3。这时,bugFix还没有之前main的更新,可以通过如下代码更新
git checkout bugFix
git merge //因为此时main的继承自bugFix,所以只是简单地把 bugFix 移动到 main 所指向的那个提交记录。
rebase操作
Rebase 实际上就是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。
Rebase 的优势就是可以创造更线性的提交历史
把 bugFix 分支里的工作直接移到 main 分支上。移动以后会使得两个分支的功能看起来像是按顺序开发,但实际上它们是并行开发的。提交记录 C3 依然存在(树上那个半透明的节点),而 C3' 是我们 Rebase 到 main 分支上的 C3 的副本。
git rebase main //on branch bugFix
切换到了 main
上。把它 rebase 到 bugFix
分支。由于 bugFix
继承自 main
,所以 Git 只是简单的把 main
分支的引用向前移动了一下而已。
git checkout main
git rebase
分离Head
HEAD 是一个对当前所在分支的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。
HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。
HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见。
git checkout c1 //通过hash指向,也可以通过branch名指向
git checkout main
git commit
git checkout c2
分离的 HEAD 就是让其指向了某个具体的提交记录而不是分支名
HEAD -> main -> C1
HEAD 指向 main, main 指向 C1。
通过哈希值指定提交记录。每个提交记录的哈希值显示在代表提交记录的圆圈中。
相对引用
git log
来查查看提交记录的哈希值
Git 对哈希的处理很智能。你只需要提供能够唯一标识提交记录的前几个字符即可。
通过哈希值指定提交记录很不方便,所以 Git 引入了相对引用
相对引用非常给力,这里我介绍两个简单的用法:
- 使用
^
向上移动 1 个提交记录 - 使用
~<num>
向上移动多个提交记录,如~3
把这个符号加在引用名称的后面,表示让 Git 寻找指定提交记录的 parent 提交。
所以 main^
相当于“main
的 parent 节点”。
main^^
是 main
的第二个 parent 节点。
git checkout main^
你也可以将 HEAD
作为相对引用的参照。下面咱们就用 HEAD
在提交树中向上移动几次。
git checkout c3
git checkout HEAD^
git checkout HEAD^
git checkout HEAD^
“~”操作符
该操作符后面可以跟一个数字(可选,不跟数字时与 ^
相同,向上移动一次),指定向上移动多少次。
git checkout HEAD~4 //一次后退四步
强制修改分支位置
使用相对引用最多的就是移动分支。可以直接使用 -f
选项让分支指向另一个提交。例如:
git branch -f main HEAD~3
上面的命令会将 main 分支强制指向 HEAD 的第 3 级 parent 提交。
\
撤销分支
和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。我们这个应用主要关注的是后者。
主要有两种方法用来撤销变更 —— 一是 git reset
,还有就是 git revert
。
git reset
通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset
向上移动分支,原来指向的提交记录就跟从来没有提交过一样。
git reset HEAD~1
虽然在你的本地分支中使用 git reset
很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的哦!
为了撤销更改并分享给别人,我们需要使用 git revert
。
git revert HEAD
在我们要撤销的提交记录后面居然多了一个新提交!这是因为新提交记录 C2'
引入了更改 —— 这些更改刚好是用来撤销 C2
这个提交的。也就是说 C2'
的状态与 C1
是相同的。
revert 之后就可以把你的更改推送到远程仓库与别人分享啦。
git cherry-pick
git cherry-pick <提交号>...
如果你想将一些提交复制到当前所在的位置(HEAD
)下面的话, Cherry-pick 是最直接的方式了。
git cherry-pick c2 c4
出现冲突怎么办???
交互式rebase
当你知道你所需要的提交记录(并且还知道这些提交记录的哈希值)时, 用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。
但是如果你不清楚你想要的提交记录的哈希值呢? 幸好 Git 帮你想到了这一点, 我们可以利用交互式的 rebase —— 如果你想从一系列的提交记录中找到想要的记录, 这就是最好的方法了
交互式 rebase 指的是使用带参数 --interactive
的 rebase 命令, 简写为 -i
如果你在命令后增加了这个选项, Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。
当 rebase UI界面打开时, 你能做3件事:
- 调整提交记录的顺序(通过鼠标拖放来完成)
- 删除你不想要的提交(通过切换
pick
的状态来完成,关闭就意味着你不想要这个提交记录) - 合并提交。
git rebase -i HEAD~4
下面c2和c3位置变化,是因为在交互界面进行了编辑交换顺序