工作目录、暂存区、版本库
-
工作区:就是你在电脑里能看到的目录,又称工作目录。你修改的文件并且没有
git add
的文件也算属于工作区。 -
暂存区:英文叫
stage
或index
。一般存放在 .git 目录下的index
文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。使用git add
可以将文件添加到暂存区。 -
版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支
master
,以及指向master
的一个指针叫HEAD
。使用git commit
可以将文件添加到我们的版本库里。
git reset
将当前 HEAD
重置为指定状态
git reset --soft【保留工作区,保留暂存区、修改版本库】
将 HEAD
引用指向给定提交。索引(暂存区)和工作目录的内容是不变的,在三个命令中对现有版本库状态改动最小。
git reset --mixed【保留工作区、修改暂存区、修改版本库】(git reset默认的模式)
HEAD
引用指向给定提交,并且索引(暂存区)内容也跟着改变,工作目录内容不变。这个命令会将索引(暂存区)变成你刚刚暂存该提交全部变化时的状态,会显示工作目录中有什么修改。
git reset --hard 【修改工作区、修改暂存区、修改版本库】
HEAD
引用指向给定提交,索引(暂存区)内容和工作目录内容都会变给定提交时的状态。也就是在给定提交后所修改的内容都会丢失(新文件会被删除,不在工作目录中的文件恢复,未清除回收站的前提)。
git revert
撤销提交的命令,git revert是创建一个commit来覆盖当前的commit,指针向后移动。
实战
了解完 git reset
和 revert
,下面我们来进行一个实战。
编写一个 hello.txt
文件,提交5次,每次提交内容分别是 111
、222
、 333
、 444
、 555
。
touch hello.txt echo '111' >> hello.txt git add . git commit -m '111' echo '222' >> hello.txt git add . git commit -m '222' echo '333' >> hello.txt git add . git commit -m '333' echo '444' >> hello.txt git add . git commit -m '444' echo '555' >> hello.txt git add . git commit -m '555'
效果如图所示:
当我们提交了 5 次 commit 时,出现了以下的情况:
-
情况一:我发现第三次提交的时候有 bug,但是我又想要第四次和第五次的提交。那么这个时候我们可以使用
git revert
,来覆盖掉第三次的提交。
# 使用 git log 查看 commitId $ git log
# 使用 git revert 撤回提交 git revert 6bde9ba2f72059bb2689071013b55ddbe40dc919
revert
后,由于之前的提交跟第三次提交有冲突,我们可以解决冲突然后提交。再用 git log
命令查看的时候,发现多了一个commit
没错,git revert
就是使用新的提交来覆盖旧的提交,实现 撤回 的功能
-
情况二:我们提交完 5次 commit之后,发现从第三次提交之后,我们的提交因为业务需求都需要去掉。也就是我们不需要第 3 次提交以及之后的commit。这个时候我们可以使用
git reset
,回退到第 2 次 提交的版本。
# 查看commitId git log
# 回退版本 git reset --hard 9a8d74cc2800e2cb5251cee0db9ca9c8f0412c56
# 查看一下提交日志 git log
发现已经删除第 3 次以及之后的提交了。
总结:
-
git revert
后会多出一条commit
,这里可进行撤回操作,新多出来的commit
正好抵消了旧的commit
提交的修改
-
git reset
直接把之前commit
删掉,非git reset --hard
的操作是不会删掉修改代码,如果远程已经有之前代码,需要强推git push -f