zoukankan      html  css  js  c++  java
  • 【git | 11】git reset

    git的基本提交流程

    Git的基本流程,有三步,如图所示:

    • Working Tree:本地的工作区域
    • Index/Stage 暂存区域,和git stash命令暂存的地方不一样,使用git add xx,就可以将xx添加近Stage里面。
    • Repository 提交的历史,即使用git commit提交后的结果。

    简单叙述流程:

    1. 刚开始 working tree 、 index 与 repository(HEAD)里面的內容都是一致的。

    2.当git管理的文件夹里面的内容出现改变后,此時 working tree 的內容就会跟 index 及 repository(HEAD)的不一致,而Git知道是哪些文件(Tracked File)被改动过,直接将文件状态设置为 modified (Unstaged files)。

     3.当执行 git add 后,会将这些改变的文件內容加入 index 中 (Staged files),所以此时working tree跟index的內容是一致的,但他们与repository(HEAD)內容不一致。

    4.执行 git commit 后,將Git索引中所有改变的文件內容提交至 Repository 中,建立出新的 commit 节点(HEAD)后, working tree 、 index 與与repository(HEAD)区域的内容 又会保持一致。

    版本回退git reset

     现在我需要版本回退,想把当前的版本回退到上一个版本,可以使用如下两种命令:

    ①  git reset --hard HEAD^ 回到上一个版本, git reset --hard HEAD^^ 回退到上上一个版本,以此类推;

    ② 如果回退到前50个版本的话,使用方法①就显得不太明智了,我们可以使用简便命令操作: git reset --hard HEAD~50 就可以了。

    HEAD 说明:

    • HEAD 表示当前版本

    • HEAD^ 上一个版本

    • HEAD^^ 上上一个版本

    • HEAD^^^ 上上上一个版本

    • 以此类推...

    可以使用 ~数字表示

    • HEAD~0 表示当前版本

    • HEAD~1 上一个版本

    • HEAD^2 上上一个版本

    • HEAD^3 上上上一个版本

    • 以此类推...

     实践操作

    git reset --hard

    reset --hard 会在重置 HEADbranch的同时,重置stage区和工作目录里的内容。当你在 reset 后面加了 --hard 参数时,你的stage区和工作目录里的内容会被完全重置为和HEAD的新位置相同的内容。换句话说,就是你的没有commit的修改会被全部擦掉。

    例如:你在上次 commit 之后又对文件做了一些改动:对test01.txt进行修改,执行了git add命令, 对test02.txt只进行修改,没做其他操作。执行命令 git reset --hard HEAD^ ,结果工作区、暂存区、版本仓库和上一次commit提交之后的状态完全一致。

     
    实践操作

     2. 修改test01.txt、test02.txt,对test01.txt执行命令 git add.txt。如图所示:

     

     执行命令:

    git reset --hard HEAD^

     如图所示:

    reset --soft:保留工作目录,并把重置 HEAD 所带来的新的差异放进暂存区

    reset --soft 会在重置 HEADbranch 时,保留工作目录和暂存区中的内容,并把重置 HEAD 所带来的新的差异放进暂存区。

    什么是「重置 HEAD 所带来的新的差异」?就是这里:

    由于 HEAD 从 4 移动到了 3,而且在 reset 的过程中工作目录和暂存区的内容没有被清理掉,所以 4 中的改动在 reset 后就也成了工作目录新增的「工作目录和 HEAD 的差异」。这就是上面一段中所说的「重置 HEAD 所带来的差异」。

    此模式下会保留 working tree工作目录的內容,不会改变到目前所有的git管理的文件夹的內容;也会
    保留 index暂存区的內容,让 index 暂存区working tree 工作目录的內容是一致的。就只有 repository 中的內容的更变需要与 reset 目标节点一致,因此原始节点与reset节点之间的差异变更集合会存在与index暂存区中(Staged files),所以我们可以直接执行 git commitindex暂存区中的內容提交至 repository 中。当我们想合并「当前节点」与「reset目标节点」之间不具太大意义的 commit 记录(可能是阶段性地频繁提交)時,可以考虑使用 Soft Reset 来让 commit 演进线图较为清晰点。

    所以在同样的情况下,还是老样子:把修改后的ganmes.txt文件addstage区,修改后的shopping list.txt保留在工作目录

     注意:--hard 会清空工作目录和暂存区的改动; --soft则会保留工作目录的内容,并把因为保留工作目录内容所带来的新的文件差异放进暂存区

    reset 不加参数(mixed):保留工作目录,并清空暂存区

    reset 如果不加参数,那么默认使用 --mixed 参数。它的行为是:保留工作目录,并且清空暂存区。也就是说,工作目录的修改、暂存区的内容以及由 reset 所导致的新的文件差异,都会被放进工作目录。简而言之,就是「把所有差异都混合(mixed)放在工作目录中」。

    还以同样的情况为例:

    总结

    区别:

    • --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 commitIndex暂存区 中的內容提交至Repository中,这样一样可以达到合并commit节点的效果(与上面--soft合并commit节点差不多,只是多了git add添加到暂存区的操作);(2)移除所有Index暂存区中准备要提交的文件(Staged files),我们可以执行 git reset HEADUnstage 所有已列入 Index暂存区 的待提交的文件。(有时候发现add错文件到暂存区,就可以使用命令)。(3)commit提交某些错误代码,或者没有必要的文件也被commit上去,不想再修改错误再commit(因为会留下一个错误commit点),可以回退到正确的commit点上,然后所有原节点和reset节点之间差异会返回工作目录,假如有个没必要的文件的话就可以直接删除了,再commit上去就OK了。

    参考资料

    ·1. Git Reset 三种模式

  • 相关阅读:
    Java 泛型 泛型的约束与局限性
    Java 泛型 泛型方法
    Java 泛型 泛型数组
    Java 泛型 协变性、逆变性
    Java 泛型 协变式覆盖和泛型重载
    Java 泛型 泛型代码和虚拟机
    Insertion Sort List
    Remove Duplicates from Sorted List II
    String to Integer (atoi)
    SpringMvc源码入门
  • 原文地址:https://www.cnblogs.com/sunbines/p/14920495.html
Copyright © 2011-2022 走看看