Git 存储
简介
Git 提供了
stash
存储的功能,即当你在工作到一半突然需要切换到另一个分支上,但又不想提交时,可将当前做出的修改通过
git stash
命令存储起来,之后再从其中重新读取之前的状态。
注意事项
若修改的文件没有执行
git add
即未被跟踪,则该文件不会被
git stash
存储,会提示
No local changes to save
。
git stash
git stash
Saved working directory and index state WIP on master: 4fae394 a
作用:将未完成的修改保存到一个栈上,在任何时候都可以重新应用这些改动。
git stash
其实会帮你做一次提交,只不过不被
git log
记录。
git stash list
$ git stash list
stash@{0}: WIP on master: 4fae394 a
作用:查看当前 Git 存储的栈空间。
git stash apply
$ git stash apply stash@{0}
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: b
作用:重新应用某个分支的修改状态。
git stash pop
$git stash pop [stash@{0}]
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: b
Dropped stash@{1}(748234869014c1bbbea8abcc1c781abfbace25ee)
作用:应用栈上存储的
stash@{0}
改动,并移除它。
git stash drop
$ git stash drop stash@{0}
Dropped stash@{0}(e1aaddefd1f1c2500822a1a8753f3e53445585ff)
作用:移除 Git 栈上存储的
stash@{0}
的改动。
Git 后悔药
Git 后悔药是指在 Git 工作系统中的任意位置的修改都可以进行撤回或回滚操作。
首先来看三大分区的流程图:
可以看出,Git 能够实现回滚操作的位置主要是三大分区:
工作目录
、
暂存区
、
本地版本库
。
注意:**一切撤销回滚的操作都是基于文件被 Git 系统跟踪监听的状态,即执行了
git add
命令**。否则会提示:
error: pathspec ‘init.txt’ did not match any file(s) known to git 【没有匹配到任何已知的 git 文件】
工作目录 checkout
针对工作目录的修改撤销,Git 主要提供了以下两种方式:
checkout – [file]
注:这是 Git 的早期命令,在Git @2.26.0 之后便不推荐这么做。后期推荐使用
restore
命令。
语法:
[file]
:撤销单个文件的修改.
:撤销所有文件的修改
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)# 使用"git restore …"丢弃工作目录中的更改
modified: init.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout -- init.txt
$ git status
On branch master
nothing to commit, working tree clean
作用:撤销针对当前工作目录的上一次更改。
原理:
checkout
切换分支会重新覆盖工作目录。
restore [file]
语法:
[file]
:撤销单个文件的修改.
:撤销所有文件的修改
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)# 使用"git restore …"丢弃工作目录中的更改
modified: init.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git restore init.txt
$ git status
On branch master
nothing to commit, working tree clean
作用:撤销针对当前工作目录的上一次更改。
暂存区 add
Git 提供了几种方式来将文件**从
已跟踪
状态回滚到
未跟踪
状态**:
已跟踪:
reset [file]
早期不推荐指令
git reset a.txt/.
作用:将文件撤回到
未跟踪
状态
reset HEAD [file]
早期不推荐指令
git reset HEAD a.txt/.
作用:**重置
HEAD
指向的同时将文件撤回到
未跟踪
状态**。
restore --staged [file]
推荐指令
git restore --staged a.txt/.
作用:**将文件撤回到
未跟踪
状态**。
未跟踪状态:
rm -r --cached
$gitrm -r --cached [. || fileName]
作用:删除暂存区文件。
$ git ls-files -s
100644 d905d9da82c97264ab6f4920e20242e088850ce9 0 a,nd$ git rm -r --cached .
rm ‘a,nd’
本地库 commit
**本地库的回滚操作对应的是
commit
提交的撤销操作**。
commit
提交的撤回系列操作主要有以下场景:
修改已提交的备注信息
–amend
当你修改了某些文件并提交之后发现
commit message
提交的备注信息写错了,那么可以通过
--amend
参数来修改:
$ git commit -m "init commit"
$ gitadd.
$ git commit --amend
注意:**
--amend
参数只针对上一次提交的备注信息更改,不包含对 commit 提交对象本身的撤回**。
--amend
指令会进入
vim
文本编辑器页面来支持你修改上一次
commit
提交的任何表面信息。
注:
--amend
指令会帮你重新提交一次,相当于有两次提交,只不过最后一次会覆盖上一次的提交。
删除上次提交
reset 三部曲
reset
指令主要用于撤销、删除等重置操作。
注意:删除上次提交后本地和远程仓库的数据都将被删除,故在删除上次提交时,记得备份数据!
语法:
$git reset [--soft | --mixed | --hard | --merge | --keep ][-q][ HEAD || commit hash]
作用:**实现对
工作目录
、
暂存区
、
commit
一系列流程的撤销操作。**
说明:
- HEAD:将 HEAD 指针往前顺移。 -
HEAD
:删除当前最新的提交-HEAD^ / HEAD~
:删除上一次提交-HEAD^^ / HEAD~2
:删除上上次提交- … <commit hash>
: 直接跳到某次提交。
reset 与 checkout 的区别
一个 Git 系统的指引流程主要有三部分参与:**
HEAD 分支指向
、
Index 暂存区
、
Working Directory 工作目录
**。
reset 与 checkout 的区别就在于:
- reset 会移动 HEAD 分支的指向,而 checkout 只会移动 HEAD 自身来指向另一个分支。
如图:
git reset
命令提供了 3 个参数来针对
HEAD 分支指向
、
Index 暂存区
、
Working Directory 工作目录
三部分的撤销操作:
–soft
git reset --soft [HEAD^ |<commit hash>]
作用:撤销 commit 提交,不撤销 git add,不删除工作空间改动代码。
本地仓库、暂存区、工作区都不改变。
–mixed
默认参数:
git reset --mixed HEAD^
和
git reset HEAD^
效果是一样的。
git reset --mixed [HEAD^ |<commit hash>]
作用:撤销 commit 提交,撤销 git add ,不删除工作空间改动代码。
修改暂存区的内容 >> 工作区、本地仓库不变。
–hard <慎用>
git reset --hard [HEAD^ |<commit hash>]
作用:撤销 commit 提交,撤销 git add 状态,删除工作空间改动代码。
修改暂存区、工作区的内容,本地仓库不变。
注意:完成这个操作后,就完全恢复到了上一次的commit状态。这个操作相当于是完全重置,会删除很多文件,慎用!
revert HEAD
git revert HEAD <[commit Hash]|''>
作用:**放弃指定
commit hash
提交的修改,但是会生成一次新的提交,需要填写新的注释,以前的
git los
历史记录都在。**
''
:不给commit hash
则指向最近一次的提交commit hash
:指定某次提交,并以此为基础重新生成一次提交。
reset 和 revert 的区别
- reset:将 HEAD 指针指向到指定提交,
git log
历史记录中不会出现放弃的提交记录。 - revert:放弃指定
commit hash
提交的修改,但是会生成一次新的提交,需要填写新的注释,以前的git los
历史记录都在。
checkout
不带路径
- git checkout [branch]
运行 git checkout [branch] 与运行 git reset --hard [branch] 非常相似,它会更新三者使其看起来像 [branch]
。
不过有两点重要的区别:
1、首先不同于 reset --hard 指令,checkout 对工作目录是安全的,它会通过检查来确保不会将已更改的文件弄丢。而 reset --hard 则会不做检查就全面地替换所有东西。
2、其次是如何更新 HEAD。
reset 会移动 HEAD 分支的指向【commit 提交】,而 checkout 只会移动 HEAD 自身来指向另一个分支。
例如,假设我们有 master 和 develop 分支,它们分别指向不同的提交;我们现在在 develop 上。 如果我们运行 git reset master,那么 develop 自身现在会和 master 指向同一个提交。而如果我们运行 gitcheckout master 的话,develop 不会移动,HEAD 自身会移动。 现在HEAD 将会指向 master。所以,虽然在这两种情况下我们都移动 HEAD 使其指向了提交 A,但做法_是非常不同的。 reset 会移动 HEAD 分支的指向,而 checkout 则移动 HEAD 自身。
带路径
- **git checkout commithash **
运行 checkout 的另一种方式就是指定一个文件路径,这会像 reset 一样不会移动 HEAD。 它就像是 git reset --hard [branch] file。 这样对工作目录并不安全,它也不会移动 HEAD 将会跳过第 1 步 更新暂存区 和 工作目录
- **git checkout – **
区别:相比于git reset – hard commitHash跟文件名的形式第一 第二步都没做。
Git 恢复
当在使用 Git 工作出现意外丢失了一次提交时,可以通过以下方式来恢复:
场景:假设已经提交了 5 次,需要跳转到
v3
版本的提交。
原理:**
reset --hard
重置到指定提交,后建立
branch
新分支来指向越过的分支,从而让其恢复工作**。
过程
1、
git log
查看要跳转的提交:
$git log --oneline
1d80c97 (HEAD -> master) v5
646f08d v4
5ad5c4f v3
c23755e v2
ac163ce v1
$git reset --hard 5ad5c4f
硬重置到
v3
提交,提示
HEAD is now at 5ad5c4f v3
代表已经 HEAD 指向已经变更。
现在顶部的两个提交已经丢失了 - 没有分支指向这些提交。 你需要找出最后一次提交的 SHA-1 然后增加一个指向它的分支。
2、
git reflog
查看要恢复的分支:
$git reflog
1d80c97 (HEAD -> master) HEAD@{0}: reset: moving to 1d80c97
5ad5c4f HEAD@{1}: reset: moving to 5ad5c4f9866a673305719c6c6a7c896688ba30d1
1d80c97 (HEAD -> master) HEAD@{2}: commit: v5
646f08d HEAD@{3}: commit: v4
5ad5c4f HEAD@{4}: commit (amend): v3
75f473e HEAD@{5}: commit: v2
c23755e HEAD@{6}: commit: v2
ac163ce HEAD@{7}: commit (initial): v1
- 可以选择硬重置回去,也可以选择新建分支来指向顶部的两个提交。
但是硬重置还是在当前分支操作,所以推荐新建分支。
方式
reset --hard 恢复
后悔药
git reset --hard 1d80c97 # 在当前分支重置回 v5 提交,但 v3 提交不保证。
branch [name] [hash] 新建分支恢复
版本穿梭(时光机)
git branch recover-branch 1d80c97 # 新建一个分支指向 v5 提交,让其恢复。
版权归原作者 小白菜duang 所有, 如有侵权,请联系我们删除。