ToB企服应用市场:ToB评测及商务社交产业平台
标题:
Git -- reset 详解
[打印本页]
作者:
北冰洋以北
时间:
2024-7-30 17:24
标题:
Git -- reset 详解
弁言
当我们在项目中有多个人协同开辟时候,不免会出现一些错误的提交大概删除了一些重要文件。我们需要回滚到指定的某一个节点。那些七零八落的各种提交都要清撤消。
这时候,我们的指令就要用到了。reset
正文
git reset
。它的一句话概括
git-reset - Reset current HEAD to the specified state
复制代码
意思就是可以让HEAD这个指针指向其他的地方。例如我们有一次commit不是不是很满意,需要回到上一次的Commit里面。那么这个时候就需要通过reset,把HEAD指针指向上一次的commit的点。
它有三种模式,soft,mixed,hard,具体的使用方法下面这张图,展示的很全面。
别的git reset --hard HEAD^
等价于git reset --hard xxx(xxx为commit id)
git各个区域和下令关系
这三个模式理解了,对于使用这个下令很有帮助。在理解这三个模式之前,需要略微知道一点Git的根本流程。正如上图,Git会有三个区域:
Working Tree
当前的工作区域
Index/Stage
暂存区域,和git stash下令暂存的地方不一样。使用git add xx,就可以将xx添加近Stage里面
Repository
提交的历史,即使用git commit提交后的结果
文件存入Repository流程
以下简单敘述一下把文件存入Repository流程:
刚开始 working tree 、 index 与 repository(HEAD)里面的內容都是一致的
阶段1
当git管理的文件夹里面的内容出现改变后,此時 working tree 的內容就会跟 index 及 repository(HEAD)的不一致,而Git知道是哪些文件(Tracked File)被改动过,直接将文件状态设置为 modified (Unstaged files)。
阶段2
当我們实行 git add 后,会将这些改变的文件內容加入 index 中 (Staged files),所以此时working tree跟index的內容是一致的,但他们与repository(HEAD)內容不一致。
阶段3
接着实行 git commit 后,将Git索引中所有改变的文件內容提交至 Repository 中,创建出新的 commit 节点(HEAD)后, working tree 、 index 與与repository(HEAD)区域的内容 又会保持一致。
阶段4
实战演示
reset --hard:重置stage区和工作目录:
reset --hard
会在重置
HEAD
和
branch
的同时,重置stage区和工作目录里的内容。当你在
reset
后面加了
--hard
参数时,你的stage区和工作目录里的内容会被完全重置为和
HEAD
的新位置雷同的内容。换句话说,就是你的没有
commit
的修改会被全部擦掉。
例如你在上次
commit
之后又对文件做了一些改动:把修改后的
ganmes.txt
文件
add
到
stage区
,修改后的
shopping list.txt
保留在
工作目录
git status
复制代码
最初状态
然后,你实行了
reset
并附上了
--hard
参数:
git reset --hard HEAD^
复制代码
你的
HEAD
和当前
branch
切到上一条
commit
的同时,你工作目录里的新改动和已经add到stage区的新改动也一起全都消失了:
git status
复制代码
reset --hard head^之后
可以看到,在
reset --hard
后,所有的改动都被擦掉了。
reset --soft:保留工作目录,并把重置 HEAD 所带来的新的差异放进暂存区
reset --soft
会在重置
HEAD
和
branch
时,保留工作目录和暂存区中的内容,并把重置
HEAD
所带来的新的差异放进暂存区。
什么是「重置
HEAD
所带来的新的差异」?就是这里:
由于
HEAD
从 4 移动到了 3,而且在 reset 的过程中工作目录和暂存区的内容没有被清理掉,所以 4 中的改动在
reset
后就也成了工作目录新增的「工作目录和
HEAD
的差异」。这就是上面一段中所说的「重置
HEAD
所带来的差异」。
此模式下会保留
working tree工作目录
的內容,不会改变到现在所有的git管理的文件夹的內容;也会
保留
index暂存区
的內容,让
index 暂存区
与
working tree
工作目录的內容是一致的。就只有
repository
中的內容的更变需要与
reset
目标节点一致,因此原始节点与
reset
节点之间的差异变更聚集会存在与index暂存区中(
Staged files
),所以我们可以直接实行
git commit
將
index暂存区
中的內容提交至
repository
中。当我们想合并「当前节点」与「reset目标节点」之间不具太大意义的
commit
记录(可能是阶段性地频繁提交)時,可以考虑使用
Soft Reset
来让
commit
演进线图较为清晰点。
所以在同样的情况下,还是老样子:把修改后的
ganmes.txt
文件
add
到
stage区
,修改后的
shopping list.txt
保留在
工作目录
git status
复制代码
最初状态
假设此时当前
commit
的改动内容是新增了
laughters.txt
文件:
git show --stat
复制代码
git show --stat
如果这时你实行:
git reset --soft HEAD^
复制代码
那么除了
HEAD
和它所指向的
branch1
被移动到
HEAD^
之外,原先
HEAD
处
commit
的改动(也就是谁人
laughters.txt
文件)也会被放进暂存区:
git status
复制代码
使用git reset --soft HEAD^
后
这就是
--soft
和
--hard
的区别:
--hard
会清空工作目录和暂存区的改动,*而
--soft则会保留工作目录的内容,并把由于保留工作目录内容所带来的新的文件差异放进暂存区
。
reset 不加参数(mixed):保留工作目录,并清空暂存区
reset
如果不加参数,那么默认使用
--mixed
参数。它的举动是:保留工作目录,并且清空暂存区。也就是说,工作目录的修改、暂存区的内容以及由
reset
所导致的新的文件差异,都会被放进工作目录。简而言之,就是「把所有差异都混淆(mixed)放在工作目录中」。
还以同样的情况为例:
git status
复制代码
最初状态
修改了 的games.txt 和 shopping list.txt,并把 games.txt 放进了暂存区。
git show --stat
复制代码
git show --stat
最新的 commit 中新增了 laughters.txt 文件。
这时如果你实行
无参数
的
reset
大概带
--mixed
参数:
[/code] [list=1]
[*] git reset HEAD^
[*] git reset --mixed HEAD^
[/list] 工作目录的内容和 [b]--soft[/b] 一样会被保留,但和 [b]--soft[/b] 的区别在于,它会把暂存区清空,并把原节点和[b]reset[/b]节点的差异的文件放在工作目录,总而言之就是,工作目录的修改、暂存区的内容以及由 [b]reset[/b] 所导致的新的文件差异,都会被放进工作目录
[code]git status
复制代码
git reset HEAD^之后
总结
reset 的本质:移动 HEAD 以及它所指向的 branch
实质上,
reset
这个指令虽然可以用来撤销
commit
,但它的实质举动并不是撤销,而是移动
HEAD
,并且「捎带」上
HEAD
所指向的
branch
(如果有的话)。也就是说,
reset
这个指令的举动其实和它的字面意思 "
reset
"(重置)十分相符:它是用来重置
HEAD
以及它所指向的
branch
的位置的。
而
reset --hard HEAD^
之所以起到了撤销
commit
的结果,是由于它把
HEAD
和它所指向的 branch 一起移动到了当前
commit
的父
commit
上,从而起到了「撤销」的结果:
git reset
Git 的历史只能往回看,不能向未来看,所以把
HEAD
和
branch
往回移动,就能起到撤回
commit
的结果。
所以同理,
reset --hard
不仅可以撤销提交,还可以用来把
HEAD
和
branch
移动到其他的任何地方。
git reset --hard branch2
复制代码
git reset --hard branch2
reset三种模式区别和使用场景
区别:
--hard
:重置位置的同时,直接将
working Tree工作目录
、
index 暂存区
及
repository
都重置成目标
Reset
节点的內容,所以结果看起来等同于清空暂存区和工作区。
--soft
:重置位置的同时,保留
working Tree工作目录
和
index暂存区
的内容,只让
repository
中的内容和
reset
目标节点保持一致,因此原节点和
reset
节点之间的【差异变更集】会放入
index暂存区
中(
Staged files
)。所以结果看起来就是工作目录的内容不变,暂存区原有的内容也不变,只是原节点和
Reset
节点之间的所有差异都会放到暂存区中。
--mixed(默认)
:重置位置的同时,只保留
Working Tree工作目录
的內容,但会将
Index暂存区
和
Repository
中的內容更改和reset目标节点一致,因此原节点和
Reset
节点之间的【差异变更集】会放入
Working Tree工作目录
中。所以结果看起来就是原节点和
Reset
节点之间的所有差异都会放到工作目录中。
使用场景:
--hard
:(1)
要放弃现在本地的所有改变時
,即去掉所有add到暂存区的文件和工作区的文件,可以实行
git reset -hard HEAD
来逼迫规复git管理的文件夹的內容及状态;(2)
真的想扬弃目标节点后的所有commit
(可能以为目标节点到原节点之间的commit提交都是错了,之前所有的commit有题目)。
--soft
:原节点和
reset
节点之间的【差异变更集】会放入
index暂存区
中(
Staged files
),所以假如我们之前工作目录没有改过任何文件,也没add到暂存区,那么使用
reset --soft
后,我们可以直接实行
git commit
將 index暂存区中的內容提交至
repository
中。为什么要这样呢?这样做的使用场景是:假如我们想合并「当前节点」与「
reset
目标节点」之间不具太大意义的
commit
记录(可能是阶段性地频繁提交,就是开辟一个功能的时候,改大概增长一个文件的时候就
commit
,这样做导致一个完整的功能可能会好多个
commit
点,这时假如你需要把这些
commit
整合成一个
commit
的时候)時,可以考虑使用
reset --soft
来让
commit
演进线图较为清晰。总而言之,
可以使用--soft合并commit节点
。
--mixed(默认)
:(1)使用完
reset --mixed
后,我們可以直接实行
git add
将這些改变果的文件內容加入
index 暂存区
中,再实行
git commit
将
Index暂存区
中的內容提交至
Repository
中,这样一样可以到达合并
commit
节点的结果(与上面--soft合并commit节点差不多,只是多了git add添加到暂存区的操作);(2)移除所有Index暂存区中预备要提交的文件(Staged files),我们可以实行
git reset HEAD
来
Unstage
所有已列入
Index暂存区
的待提交的文件。(偶然候发现add错文件到暂存区,就可以使用下令)。(3)
commit
提交某些错误代码,大概没有须要的文件也被
commit
上去,不想再修改错误再
commit
(由于会留下一个错误
commit
点),可以回退到准确的
commit
点上,然后所有原节点和
reset
节点之间差异会返回工作目录,假如有个没须要的文件的话就可以直接删除了,再
commit
上去就OK了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4