-
B站视频地址: https://www.bilibili.com/video/BV1KX4y1a7N9
-
Git学习文档:https://d9bp4nr5ye.feishu.cn/wiki/PeDPw3mm3iFA36k9td9cVeignsZ
在很长一段时间里,我对Git的操作只限于:提交代码,拉取代码,合并代码。
虽然上面这些操作在日常工作中也足够了,但不会点高级知识不利于装X,今天我们来学习几个高级点的操作。
一、前提
在正式操作之前,我们先来共知几个命令和概念。
SHA标识
每一次提交Git都会生成一个唯一SHA标识(简单来说就是为这次提交生成一个唯一字符串),代码合并、回滚、检出都和这个标识相关。
注:SHA标识是指Git中的SHA-1哈希标识符,它是一个40个字符的字符串,用于唯一标识Git中的每个提交、对象和分支。SHA-1是一个加密哈希函数,它接受输入(例如文件内容或提交信息)并生成一个唯一的40字符长的哈希值。
git log
Git 的每次提交都会携带很多信息,提交者、提交时间、唯一SHA标识等,想要查看这些信息,可以使用 git log
命令。
git log
完整的查看 log信息,展示效果如下:
git log --oneline
精简提交信息,以一行的方式展示
git log --graph --oneline
以时间线的方式查看精简的日志信息
二、回滚代码
代码回滚,提交了错误的代码、代码错合并到非目标分支
- commit 回滚
- merge 回滚
回滚
使用 git log --graph --oneline
查看日志线,并找到我们要撤回提交的hash
1、找到我们要回滚commit的 hash
git log --graph --oneline
2、执行回滚命令 回滚之后可能是有冲突的,是需要手动解决冲突
git revert 1b17801
git push
3、回滚 mergn
git revert f259bf5
git push
冲突
如果回滚的时候有冲突,会这样提示
方式一
可以选择放弃这次的回滚 git revert --abort
方式二
-- 1、手动解决冲突
-- 2、提交修改
git add .
-- 3、继续revert, 会弹出一个文件,可以修改commit的描述,也可以直接关闭
git revert --continue
-- 4、push代码
git push
三、合并代码
合并代码就是把branchA的代码移植到branchB,有两个命令可以来完成此操作:merge、rebase。
假如branchA是我们的开发分支,branchB是正式分支,在branchA上面我们提交了三次。现在我们来看看使用 merge 和 rebase 合并会有什么不同。
Merge
merge会把branchA所有的提交打包成一个最终状态,去和branchB的最终状态来一次合并。如果有冲突,我们只需要解决一次冲突就好了。
# branchA 当前log
A---B---C (branchA)
# branchB 当前log
D---E---F---G (branchB)
# 在branchB 上执行 git merge branchA
A---B---C (branchA)
/ \
D---E---F---G---H (branchB, merge commit)
其实就是把 branchA 当前的状态当作一次提交合并到branchB上去,所以会形成一次新的提交 H。对branchA没什么改变,对branchB 多了一次提交。(Merge remote-tracking branch ‘origin/branchA’ into branchB)
Rebase
rebase 会把branchA 上的每一次提交,都依次合并到 branchB 上去。 如果在branchA上的三次提交都和branchB有冲突,那你就要解决三次冲突。(因为它是依次提交的)
# branchA 当前log
A---B---C (branchA)
# branchB 当前log
D---E---F---G (branchB)
# 在branchB 上执行 git rebase branchA
A--B--C (branchA, rebased)
/
D---E---F---G (branchB)
从结果来看相对于 merge, rebase有两个特殊点(代码没有冲突的情况下)
- 它不会生成新的 SHA标识。
- 目标分支成了一条直线,且更长了。(具体看branchA提交的次数)
结论
合并代码的时候使用 merge,可以更好的看到提交的变更,并保留每个分支的独立性和历史记录,只需要解决一次冲突,所以在正常情况下,更推荐使用 merge 来合并代码。
当然如果你是把别的分支 rebase到自己的分支,那没什么关系,最起码不会影响到别人。
Rebase 合并 commit
rebase 除了上面的合并代码,它还有一个很大的用处就是合并commit,开发的过程中我们可能提交了很多乱七八糟的commit,但是为了更美观,我们可以把多个commit合并成一个新的commit。
合并commit有两个方式
- 以头为标准,往下合并N个commit
git rebase -i HEAD~N
- 以某个节点向上做commit合并
git rebase xxx
xxx 就是commit的hash值
假设我们有三次提交,现在我们要把 two 和 three 合并成一个新的提交 two and three
git rebase -i 49412a4
执行命令后,会弹出一个文本窗口,让我们来确定要对这次rebase的操作,可以对每个commit进行很多。
把 pick 687575f three commit
改为 squash 687575f three commit
然后保存退出。
保存后,又会弹出一个窗口,告知我们修改 commit的提交信息
修改前
# This is a combination of 2 commits.
# This is the 1st commit message:
two commit
# This is the commit message #2:
three commit
修改后
# This is a combination of 2 commits.
# This is the 1st commit message:
two three commit
# This is the commit message #2:
three commit
保存后就成功
再次查看日志
rebase修改commit的操作有很多,上面我们用了一个squash
,下面是全部的命令,可以根据需要选择
命令 | 解释 | 简写 |
---|---|---|
pick | 使用提交,即应用该提交的更改。 | p |
reword | 使用提交,但可以编辑提交消息。 | r |
edit | 使用提交,但停下来以进行修改。 e | |
squash | 使用提交,将其融入到前一个提交中。 | s |
exec | 使用shell运行命令(行中的其余部分)。 | x |
break | 在此处停止(稍后使用 git rebase --continue 继续进行rebase)。 b | |
drop | 删除提交。 | d |
label | 为当前HEAD标记一个名称。 | l |
reset | 将HEAD重置为一个标签。 | t |
merge | 将标签合并到HEAD上,并且可以选择编辑合并提交的消息。 | m |
fixup | 类似于"squash",但仅保留前一个提交的日志消息,除非使用了-C ,这种情况下仅保留当前提交的消息;-c 与 -C 相同,但会打开编辑器。 | f |
四、从A分支选择N次提交,合并到B分支
如标题所示,目的是从A分支拣取某几次提交到B分支,可使用命令 git cherry-pick
假设在A分支上提交了三次,三次的hash分别是 A1、A2、A3, 现在我们要把 A2、A3 提交合并到B分支上,需要执行的命令如下:
-- 1、切换到B分支
git checkout B
-- 2、把A2、A3 提交合并过来
git cherry-pick A2 A3
-- 3、提交代码
git push
正常流程就是上面这样,但合并代码总面临着冲突,如果冲突了就会显示下面的异常
冲突了的解决办法有两个
方式一
取消这次的操作 git cherry-pick --abort
方式二
解决冲突
-- 1、先手动解决冲突
-- 2、添加修改
git add .
-- 3、在解决冲突后继续执行git cherry-pick命令 、 会弹出一个文件,可以修改commit的描述,也可以直接关闭
git cherry-pick --continue
-- 4、push代码
git push