关于 git 中 rebase,revert,rest 三者的区别。

今天刚有一轮电话面试问到了 rebase 和 rest 的的区别。以及刚好我其实对 branch 的操作其实不是很熟悉。查找了一些资料之后大概明白了一些,顺便记下来。

首先 git 的版本记录方式并不是记录全部源代码,而是记录修改操作。

比如(提交A:删除了第一行的123)

依次而来构成了一个修改链,比如 A B C D ,最新的修改为 D ,有一个指针叫做 HEAD,意思是最后输出的文件结果就计算到这里。

比如一般默认 HEAD 是最后一次提交,即为 D,那最后仓库的文件就是 A B C D 四次修改的最后结果。

而 reset 的意思是,告诉 git,将 HEAD 指向从最后一位移走,比如移到 C,那么最后的文件就是 A B C 三次修改的结果,修改 D 虽然依旧还在 git 仓库内,但是实际上没有发挥用途。如果以后想恢复,可以通过记录 D 的 commit id 的方法恢复。

而 reset 有个参数,这个参数又关系到另外一个东西。

在 git 中,文件分为三步三个地方保存

1. 工作区,即文件系统。也就是每次 ctrl s 之后就算是保存到工作区。

2. 暂存区,每次执行 git add 或者 git delete 这种命令的时候,会把工作区已经保存的内容保存到暂存区。

3. 仓库,每次执行 git commit 的时候,会把暂存区的东西保存到仓库,同时创建一个 commit,记录当前修改并且自动把 HEAD 移动到最新的 commit。

reset 带的参数中,

soft 表示只把 HEAD 移动一下,这样后面做任何操作都以 HEAD 为基础修改,但是暂存区和工作区都不管

mixed 表示除了上述修改,还把暂存区也还原成当时的样子。

hard 则表示,除了上述两项修改,还把工作区也还原成当时的样子。

而 git rebase 则是与分支合并有关,在我的理解中,这个命令不该与 reset 进行区分,而应该与 merge 进行区分。

简单点说,merge 是将两个分支合并,而 rebase 是将两个分支变成一个分支。

打个简单的比方。 一共有三个修改,A,B1 和 B2,其中 B1 和 B2 是两个分支上的修改。

如果使用 merge,git会认为这两个分支进行了一次合并。

而如果使用rebase,git会把 B2 的修改复制一份挪到 B1 后面。(不知道会不会有冲突,等我有时间试一试,具体内容后续补充)则不视为一次合并。

而 git revert 则是一次撤销操作,继续上面的例子, A B C D 四个修改内容,如果想要撤销 B,则提交一个反向操作。例如B是 添加第一行abc,那么提交一个 删除第一行 abc 的操作

A B C D E(-B)