前言
我们不说那些 git push, git merge, git reset 等等,这些基操,这里主要讲一下 git rebase, git cherry-pick, git reflog, git stash 四个可能会用到的操作。
git rebase
两个作用
作用一:合并多次提交记录
一个小功能更改,提交 几十次 ,项目充满了无用的 commit 纪录。
简介
简要概括为:可以对某一段线性提交历史进行编辑、删除、复制、粘贴;因此,合理使用rebase命令可以使我们的提交历史干净、简洁!
基本用法
这里介绍合并提交:

-
命令
git rebase -i [startpoint] [endpoint] 复制代码-i的意思是--interactive,即弹出交互式的界面让用户编辑完成合并操作。[startpoint] [endpoint]则指定了一个编辑区间。(一个前开后闭的区间)
或者
git rebase -i HEAD~3 复制代码-
最新的三个
commit
-
然后进入
vi编辑模式
上面的是本次
rebase操作包含的所有提交,下面注释的是git命令说明。pick:保留该commit(缩写:p)
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
exec:执行shell命令(缩写:x)
drop:我要丢弃该commit(缩写:d)
-
修改2、3的第一个单词为s,输入:
wqorx保存退出。
-
有冲突解决冲突。没有则会出现一个
commit message编辑页面。
修改
commit message,然后 输入:wqorx保存退出。
-
查看结果
git log 复制代码 -
异常退出vi窗口,想回去:
git rebase --edit-todo 复制代码 -
放弃此次压缩:
git rebase --abort 复制代码
当然,你可以使用其他命令比如:d(删除),修改这几次的提交。
作用二:分支合并(变基)
从 master 分支切出一个 dev 分支,进行开发,你的同事在master上完成一次提交,这时两个分支情况:

我们想要同步 master 分支的改动,首先想到了 merge,还有一个命令就是rebase,那这两个的区别是什么呢?
merge 和 rebase 的区别
两张图就可以看出:
merge:

- 新增一个新的
merge commit,然后将两个分支的历史联系在一起。 - 使用
merge是很好的方式,因为它是一种非破坏性的操作,对现有分支不会以任何方式被更改。
rebase:

-
rebase会将整个dev分支移动到master分支的顶端,从而有效地整合了所有master分支上的提交。 -
rebase通过为原始分支中的每个提交创建全新的commits来重写项目历史记录,特点是仍然会在dev分支上形成线性提交。
Git rebase并不会删除老的提交,也就是说你在对某个分支执行了rebase操作之后,老的提交仍然会存放在.git文件夹的objects目录下。
git rebase 做了什么
-
git会把dev分支里面的每个commit取消掉; -
把上面的操作临时保存成
patch文件,存在.git/rebase目录下; -
把
dev分支更新到最新的master分支; -
把上面保存的
patch文件应用到dev分支上。
基本用法
-
命令:
git rebase master #将master最新的commit作为基 复制代码 -
解决冲突:
rebase和merge的另一个区别是rebase的冲突是一个一个解决,如果有十个冲突,先解决第一个,然后用命令:# 解决冲突 git add xxx git rebase --continue 复制代码继续后才会出现第二个冲突。
-
在任何时候,我们都可以用
--abort参数来终止rebase的行动,并且分支会回到rebase开始前的状态。git rebase —abort 复制代码
总结
-
融合代码到公共分支的时使用
git merge,而不用git rebase -
融合代码到个人分支的时候使用
git rebase,可以不污染分支的提交记录,形成简洁的线性提交历史记录。
作用三:将某一段commit粘贴到另一个分支上
这个建议使用git cherry-pick,我也没实践过。
git cherry-pick
作用:挑选指定 commit 来合并。
将某个分支的部分提交(某几个提交)转移到另一个分支,原先分支提交不变。
好处
举个栗子:
在 dev 上改了提交1个更改,然后这个更改也想用到 master 分支上面。但又不需要全部提交。
基本用法
转移一个提交
-
命令:
git cherry-pick <commitHash> 复制代码在
master分支执行,指定dev分支的一个提交的commitHash,就可以将这个提交应用到master分支,产生一个新的提交,两个的哈希值不一样,相当于在两个分支上做一样的修改,然后分别提交。 -
看图秒懂:

在
master分支上git cherry-pick Y,然后master上会有一个Y' -
参数不一定是哈希值,也可以是分支名:
git cherry-pick dev 复制代码表示将
dev分支的最近一次提交,转移到当前分支。
转移多个提交
-
多个不连续的
git cherry-pick <A> <B> 复制代码转移
A和B两个提交。 -
多个连续的(不包含
A)git cherry-pick <A>..<B> 复制代码转移从
A到B的所有提交。 -
多个连续的(包含
A)git cherry-pick <A>^..<B> 复制代码
转移到另一个代码库
cherry-pick 的奥义就是,只要是在一个 .git 仓库管理下的本地代码,任何提交都可以被应用到任何可访问的本地分支,哪怕是跨代码库。
常用配置项
-
n, –no-commit
只更新工作区和暂存区。不产生新的提交
-
-x
在提交信息末尾追加一行(cherry picked from commit…)方便以后查到这个提交是如何产生的。
-
m parent-number, –mainline parent-number
-
如果原始分支是一个合并节点,那么
cherry-pick默认会失败,因为不知道应该采用哪个分支的代码变动。 -
-m 配置项告诉 git 应该采用哪个分支分变动,parent-number 代表原始提交的父分支编号。
git cherry-pick -m 1 <A> 复制代码一般1号父分支是接受变动分支,2号父分支是作为变动来源的分支。
-
git reflog
作用
-
git reflog可以查看所有分支的 所有操作记录 (包括(包括checkout和reset的操作),包括已经被删除的commit记录。 -
用来恢复本地错误操作。
基本用法
-
git reflog显示所有操作。
回退到某一步:
git reset --hard HEAD@{1}或者用前面的id -
git reflog 分支名显示某个分支的引用日志
与 git log 的区别
-
git log命令可以显示所有提交过的版本信息。git reflog查看所有分支的 所有操作记录 。 -
git log不能察看已经删除了的commit记录。
git stash
作用
保存当前的工作进度至栈中。会分别对暂存区和工作区的状态进行保存(未提交前)
场景:
-
在一个分支开发,有一个紧急的bug,不想提交现在的更改,
stash存起来,改完bug后又切回该分支,从栈中取出来继续开发。 -
本来应该在
feat分支上开发,但是却在dev分支上开发了,可以暂存起来,切到想要开发的分支,然后取出来。
注意
没有在git 版本控制中的文件,是不能被git stash 存起来的
基本用法
-
git stash保存当前的工作空间。但是提交信息是上次commit的信息。 -
git stash save "save message"保存;添加备注。 -
git stash list显示保存进度的列表。也就意味着,git stash命令可以多次执行。 -
git stash pop恢复最新保存的工作进度。-
默认会把工作区和暂存区的改动都恢复到工作区。
-
恢复进度后,会删除栈中的当前进度。
-
-
git stash pop --index恢复最新的进度到工作区和暂存区。(尝试将原来暂存区的改动还恢复到暂存区)。 -
git stash pop stash@{1}恢复指定的进度到工作区。 -
git stash show stash@{1}显示具体某一个做了哪些改动。直接show显示全部。 -
git stash apply除了不删除恢复的进度之外,其余和git stash pop命令一样。 -
git stash drop stash@{1}删除一个存储的进度。如果不指定id,则默认删除最新的存储进度。 -
git stash clear删除所有存储的进度。





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)