背景 我们的项目一般都是由文件和文件夹组成,在git中文件夹称为tree(其中顶层文件称为top-level tree),文件称为blob
一、git工作区域
1.工作区:IDE中看到的项目代码
2.暂存区:git add 进入暂存区
3.本地仓库/资源库:要想进入仓库都必须有一个版本号,所以进入仓库之前必须通过git commit
4.远程仓库
其中工作区市最不稳定的,通过add到暂存区的相对稳定一点,commit是保存到本地仓库
二、git reset 回退的三种模式
git reset --soft(温柔模式)
仅仅重置HEAD和branch,但是会保留工作目录和暂存区的内容
git reset --mixed(中等模式):对暂存区
git reset --hard(强硬模式):将暂存区、工作区所有内容丢弃
| 指令 | 作用&范围 |
|---|---|
| --soft | 只会退HEAD |
| --mixed | 回退HEAD、index,但是工作区不会退 |
| --hard | HEAD、index、working-tree都会回退 |
git reset/revert/rebase 三种撤销操作的区别 这三种操作都是可以修改git提交历史的 假设我们有四次修改文件的记录
# 新建 git 环境
mkdir demo; cd demo ; git init
# 新建 reset 分支
git checkout -b dev
echo AAAAA > reset.txt
git add reset.txt
git commit -m "AAAAA"
echo BBBBB >> reset.txt
git add reset.txt
git commit -m "BBBBB"
echo CCCCC >> reset.txt
git add reset.txt
git commit -m "CCCCC"
echo DDDDD >> reset.txt
git add reset.txt
git commit -m "DDDDD"
# 此时的 git log 如下
$ git log --pretty=format:"%h %s" --graph
* d6212d8 DDDDD
* e807553 CCCCC
* 3609018 BBBBB
* a9fb808 AAAAA
# 此时的文件如下
$ cat reset.txt
AAAAA
BBBBB
CCCCC
DDDDD
git reset是用来会退到指定版本的,git reset后面的第一个参数是对于版本的选择,这里的版本是指commit提交之后才会生成的版本,对于版本之后的暂存区和工作区而言,没有commit则不存在版本号。
比如说,你现在新拉一个分支,这个时候你commit一次,那么本地仓库就会生成一个版本commit-1,这个时候当前的版本就是指向这个commit-1。这个时候假如我们修改了工作区,或者修改之后执行了add(commit没有执行),此时我们执行git reset HEAD^ --hard,这里HEAD^会退到上一版本的意思,就是指commit-1之前的版本。也就是你执行commit-1之前的初始版本。
所以,git reset回退的版本是指commit指针指向的版本,回退上一个版本是相对于当前版本的上一个,当前版本就是你最后一次提交到本地仓库的那个版本,所以上一个就是最后一次提交到本地仓库对应版本的上一个commit版本。
至于是否覆盖工作区或者暂存区,需要看后面的reset参数 --hard/--soft/--mix
注意:
HEAD是当前版本(也就是最后一次提交的commit版本,即commit-1)
HEAD^是当前版本的前一个版本也就是最后一次提交的commit版本之前版本,即commit-0初始版本)
git revert
git revert commitId 表示重新提交某一次commit
和reset的区别就在于对版本库历史是否修改,reset是对版本历史的删除,而revert是通过重新提交版本库,增加了一个版本ID。revert 会生成一个新的提交记录,而reset是直接删除指定的提交
假如git commit链是: A -> B -> C -> D
commit链就变为了: A -> B -> C -> D->'revert D'
git rebase和git merge的区别在于是否重写了commit的提交历史。 rebase 的主要好处是可以获得更清晰的项目历史,merge的提交历史如果很多的话,可读性就比较差