git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)

文件恢复

  • 工作区、暂缓区、版本(提交历史)
  • git rest三种模式
    • git rest --soft(提交历史(仓库))
    • git rest --mixed(暂存区,提交历史(仓库))
    • git rest --hard(工作区,暂存区,提交历史(仓库))
  • git checkout(工作区)
  • git restore(工作区,暂存区)
  • git revert
  • git stash
  • git amend
  • 参考链接

git一大堆后悔药,而且很有疗效

工作区、暂缓区、版本(提交历史)

理解关于文件恢复,需要理解Git的基本流程,所有的恢复的依据以及原理,都是根据这个三个概念而来的,所以这3个概念比较重要了,正如下图,Git会有三个区域:

Working Tree 当前的工作区域
Index/Stage 暂存区域,和git stash命令暂存的地方不一样。使用git add xx,就可以将xx添加近Stage里面
Repository 提交的历史,即使用git commit提交后的结果
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第1张图片
理解这3个概念,还可以参考文章,如下链接。
https://www.runoob.com/git/git-workspace-index-repo.html

git rest三种模式

假设版本库中存在test.txt文件,
第一次在这个文件中第一行写入“version 1”,然后提交一下。
第二次在这个文件中第一行写入“version 2”,然后提交一下。
第三次在这个文件中第一行写入“version 3”,然后提交一下。
第四次在这个文件中第一行写入“version 4”,然后提交一下。
如下图
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第2张图片
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第3张图片

git rest --soft(提交历史(仓库))

现在假如,我们现在想回退到第2个版本,我们使用git rest --soft HEAD^^命令,这个命令,只会更改提交历史的内容,不会更改工作区和暂存区的内容。
运行回退命令前
工作区(回退版本前)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第4张图片
暂存区(回退版本前)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第5张图片
提交历史(仓库)(回退版本前)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第6张图片
运行命令
git reset --soft HEAD^^,并且查看log
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第7张图片
我们再来看一下,工作区,暂存区,提交历史(仓库)的变化
工作区(回退版本后),我们发现工作区和之前比,没有变化
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第8张图片
暂存区(回退版本后),我们发现暂存区和之前比,没有变化
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第9张图片
提交历史(仓库)(回退版本后)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第10张图片
我们接着用git push -f命令,将更新提交到远程仓库
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第11张图片
远程仓库
再次总结一下,这个命令,只会更改提交历史的内容,不会更改工作区和暂存区的内容
为了方便后面的说明,我现在将其恢复到第4个版本的状态。
**第一步:**通过git reflog命令找到,找到第四个提交版本的提交历史
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第12张图片
**第二步:**通过第一步找到的提交历史,然后使用git reset +提交历史,将其恢复到第4个版本
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第13张图片

git rest --mixed(暂存区,提交历史(仓库))

现在假如,我们现在想回退到第2个版本,我们使用git rest --mixed HEAD^^(其实不加–mixed也可以,默认是–mixed)命令,这个命令,只会更改提交历史的内容和暂存区,不会更改工作区的内容。
运行回退命令前
工作区(回退版本前)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第14张图片
暂存区(回退版本前)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第15张图片
提交历史(仓库)(回退版本前)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第16张图片
运行命令
git reset --soft HEAD^^,并且查看log
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第17张图片
我们再来看一下,工作区,暂存区,提交历史(仓库)的变化
工作区(回退版本后),我们发现工作区和之前比,没有变化
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第18张图片
暂存区(回退版本后),我们发现暂存区和之前比,发生变化
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第19张图片
**提交历史(仓库)(回退版本后)**我们发现暂存区和之前比,*发生变化
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第20张图片
总结一下:我们使用git rest --mixed HEAD^^(其实不加–mixed也可以,默认是–mixed)命令,这个命令,只会更改提交历史的内容和暂存区,不会更改工作区的内容。接下来,我们再接着使用git push -f命令,可以将回退的版本推送到远程仓库中。

git rest --hard(工作区,暂存区,提交历史(仓库))

git rest --hard命令使用方法跟上面两个命令,差不多,就不再做运行命令前后的对比。这个命令会更改工作目录,暂存区,提交历史(仓库)中的所有文件。这个命令比较危险,如果,你在工作目录修改了文件,没有提交到暂存区中,那修改的这个文件,就会丢失。

git checkout(工作区)

第一,git checkout可以作为分支的相关用法,由于和本篇blog主题(文件恢复)不符合,就不说分支相关的用法,如果想了解,可以参考文档:
http://www.srcmini.com/15342.html#heading_0
第二,关于git checkout的用法,对于工作区误删文件,可以使用git checkout进行恢复。
比如我们误删工作区的文件test.txt,使用2种方法,恢复成不同的版本
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第21张图片

git restore(工作区,暂存区)

git restore常用的两个命令

第一种常用用法
git restore 直接跟文件,撤销对工作区文件的修改,已经修改的文件,恢复未修改的情况。git restore指令使得在工作空间但是不在暂存区的文件撤销更改(内容恢复到没修改之前的状态)
(1)先用cat和git status看一下状态
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第22张图片
(2)在test.txt中添加文件后,再查看状态
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第23张图片
(3)使用git restore test.txt文件将文件进行恢复
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第24张图片
第二种常用用法
git restore --staged的作用是将暂存区的文件从暂存区撤出,但不会更改文件文件的内容
(1)先用cat和git status看一下状态
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第25张图片
(2) 打开test.txt文件修改文件的内容,并且查看状态
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第26张图片
(4)git add a.c 将文件添加到暂存区
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第27张图片
(5)git restore --staged 的使用
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第28张图片
可以看到使用git restore --staged之后,文件的内容并没有改变。
当然git restore的用法还有很多,这两个命令是常见的用法,如下图,可以查看和研究一下其他的用法。git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第29张图片

git revert

应用场景:
在 Git 开发中通常会控制主干分支的质量,但有时还是会把错误的代码合入到远程主干。 虽然可以直接回滚远程分支, 但有时新的代码也已经合入,直接回滚后最近的提交都要重新操作。 那么有没有只移除某些 Commit 的方式呢?可以一次 revert操作来完成。
这种情况在团队协作的开发中会很常见:可能是流程或认为原因不小心合入了错误的代码, 也可能是合入一段时间后才发现存在问题。 总之已经存在后续提交,使得直接回滚不太现实。
原理: git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的。比如,我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。如下图所示:
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第30张图片
举例说明:
Step1:假设添加3个文件1.txt,2.txt,3.txt文件,分别对应三次提交历史,我们准备反做2.txt
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第31张图片
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第32张图片
Step2:使用“git revert -n 版本号”反做,并使用“git commit -m 版本名”提交:
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第33张图片
这个仅仅是最简单最常用的用法,仅仅是抛砖引玉
参考文章:
https://blog.csdn.net/yxlshk/article/details/79944535
https://www.jianshu.com/p/5e7ee87241e4

git stash

应用场景:
1 当正在dev分支上开发某个项目,这时项目中出现一个bug,需要紧急修复,但是正在开发的内容只是完成一半,还不想提交,这时可以用git stash命令将修改的内容保存至堆栈区,然后顺利切换到hotfix分支进行bug修复,修复完成后,再次切回到dev分支,从堆栈中恢复刚刚保存的内容。
2 由于疏忽,本应该在dev分支开发的内容,却在master上进行了开发,需要重新切回到dev分支上进行开发,可以用git stash将内容保存至堆栈中,切回到dev分支后,再次恢复内容即可。
总的来说,git stash命令的作用就是将目前还不想提交的但是已经修改的内容进行保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容。这也就是说,stash中的内容不仅仅可以恢复到原先开发的分支,也可以恢复到其他任意指定的分支上。git stash作用的范围包括工作区和暂存区中的内容,也就是说没有提交的内容都会保存至堆栈中。
1 git stash
能够将所有未提交的修改(工作区和暂存区)保存至堆栈中,用于后续恢复当前工作目录。
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第34张图片
2 git stash pop
将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。
注:该命令将堆栈中最近保存的内容删除(栈是先进后出)
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第35张图片
3. git stash save
作用等同于git stash,区别是可以加一些注释,
git stash save “test1”
4 git stash list
查看当前stash中的内容
5 git stash apply
将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除,也就说该命令能够将堆栈的内容多次应用到工作目录中,适应于多个分支的情况。堆栈中的内容并没有删除。
可以使用git stash apply + stash名字(如stash@{1})指定恢复哪个stash到当前的工作目录。
6 git stash drop + 名称
从堆栈中移除某个指定的stash
7 git stash clear
清除堆栈中的所有 内容
8 git stash show
查看堆栈中最新保存的stash和当前目录的差异。
9 git stash branch
从最新的stash创建分支。
应用场景:当储藏了部分工作,暂时不去理会,继续在当前分支进行开发,后续想将stash中的内容恢复到当前工作目录时,如果是针对同一个文件的修改(即便不是同行数据),那么可能会发生冲突,恢复失败,这里通过创建新的分支来解决。可以用于解决stash中的内容和当前目录的内容发生冲突的情景。
发生冲突时,需手动解决冲突。

git amend

适用场景:
比方说,你的代码已经提交到git库,leader审核的时候发现有个Java文件代码有点问题,于是让你修改,通常有2种方法:
方法1:leader 将你提交的所有代码 abandon掉,然后你回去 通过git reset …将代码回退到你代码提交之前的版本,然后你修改出问题的Java文件,然后 git add xx.java xxx.java -s -m “Porject : 1.修改bug…”
最后通过 git push origin HEAD:refs/for/branches
方法2:
leader不abandon代码,你回去之后,修改出问题的Java文件,修改好之后,git add 该出问题.java
然后 git commit –amend –no-edit,
最后 git push origin HEAD:refs/for/branches。

Step1:我们先在工作区中创建两个文件1.txt和2.txt。并且add到暂存区git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第36张图片
Step2;执行提交操作,并查看相关日志
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第37张图片
Step3:此时我们发觉我们忘了创建文件3.txt,而我们认为3.txt应该和1.txt,2.txt一同提交,而且1.txt文件中应该有内容‘3333333’。于是我们在工作区中创建3.txt,并add到暂存区。并且修改1.txt(故意写错语法且没有将1.txt的修改add到暂存区):
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第38张图片
Step4:运行命令git commit –amend –no-edit:
git核心功能文件恢复(git reset/git checkout/git restore/git revert/git stash/git commit --amend)_第39张图片
git commit --amend 相当于上次提交错误的信息被覆盖了,gitk图形化界面上看不到上次提交的信息,git log上也看不到之前的信息,而add 后再commit 相当于重新加了一个信息。相当于打了个补丁?
git commit --amend的用法很多,目前就距了比较常用的列子

关于gitt amend的用法说明,参考文档:https://www.jianshu.com/p/a8a2ac58f37d

参考链接

https://www.jianshu.com/p/c2ec5f06cf1a
https://bingohuang.gitbooks.io/progit2/content/07-git-tools/sections/rewriting-history.html
https://mp.weixin.qq.com/s/hYjGyIdLK3UCEVF0lRYRCg
https://blog.csdn.net/asoar/article/details/84111841
https://www.cnblogs.com/kidsitcn/p/4513297.html

你可能感兴趣的:(Git,git)