GIT reset命令,似乎让人很迷惑,以至于误解,误用。但是事实上不应该如此难以理解,只要你理解到这个命令究竟在干什么。
首先我们来看几个术语
- HEAD
这是当前分支版本顶端的别名,也就是在当前分支你最近的一个提交
- Index
index也被称为staging area,是指一整套即将被下一个提交的文件集合。他也是将成为HEAD的父亲的那个commit
- Working Copy
working copy代表你正在工作的那个文件集
- Flow
当你第一次checkout一个分支,HEAD就指向当前分支的最近一个commit。在HEAD中的文件集(实际上他们从技术上不是文件,他们是blobs(一团),但是为了讨论的方便我们就简化认为他们就是一些文件)和在index中的文件集是相同的,在working copy的文件集和HEAD,INDEX中的文件集是完全相同的。所有三者(HEAD,INDEX(STAGING),WORKING COPY)都是相同的状态,GIT很happy。
当你对一个文件执行一次修改,Git感知到了这个修改,并且说:“嘿,文件已经变更了!你的working copy不再和index,head相同!”,随后GIT标记这个文件是修改过的。
然后,当你执行一个git add,它就stages the file in the index,并且GIT说:“嘿,OK,现在你的working copy和index区是相同的,但是他们和HEAD区是不同的!”
当你执行一个git commit,GIT就创建一个新的commit,随后HEAD就指向这个新的commit,而index,working copy的状态和HEAD就又完全匹配相同了,GIT又一次HAPPY了。
下面这一段是另外一个牛人的解释:
总的来说,git reset命令是用来将当前branch重置到另外一个commit的,而这个动作可能会将index以及work tree同样影响。比如如果你的master branch(当前checked out)是下面这个样子:
- A - B - C (HEAD, master)
HEAD和master branch tip是在一起的,而你希望将master指向到B,而不是C,那么你执行
git reset B以便移动master branch到B那个commit:
- A - B (HEAD, master) # - C is still here, but there's no branch pointing to it anymore
注意:git reset和checkout是不一样的。如果你运行git checkout B,那么你讲得到:
- A - B (HEAD) - C (master)
这时HEAD和master branch就不在一个点上了,你进入detached HEAD STATE. HEAD,work tree,index都指向了B,但是master branch却依然指向C。如果在这个点上,你执行一个新的commit D,那么你讲得到下面(当然这可能并不是你想要的,你可能想要的是创一个branch做bug fix):
- A - B - C (master)
\
D (HEAD)
记住git reset不会产生commits,它仅仅更新一个branch(branch本身就是一个指向一个commit的指针)指向另外一个commit(Head和branch Tip同时移动保持一致).其他的仅剩对于index和work tree(working directory)有什么影响。git checkout xxxCommit则只影响HEAD,如果xxxCommit和一个branch tip是一致的话,则HEAD和branch相匹配,如果xxxCommit并不和任何branch tip相一致,则git进入detached HEAD 状态
- Reset
如果你仔细研究reset命令本身就知道,它本身做的事情就是重置HEAD(当前分支的版本顶端)到另外一个commit。假设我们有一个分支(名称本身无所谓,所以我们就简单称为"super-duper-feature”分支吧),图形化表示如下:
如果我们执行:
git reset HEAD
任何事情都不会发生,这是因为我们告诉GIT重置这个分支到HEAD,而这个正是它现在所在的位置。
git reset HEAD~
当我们再执行上面的命令时(HEAD~1是“the commit right before HEAD”的别名,或者说:put differently "HEAD's parent"),我们的分支将会如下所示
如果我们执行git reset HEAD~2,则意味着将HEAD从顶端的commit往下移动两个更早的commit。
- Parameters
- soft
--soft参数告诉Git重置HEAD到另外一个commit,但也到此为止。如果你指定--soft参数,Git将停止在那里而什么也不会根本变化。这意味着index,working copy都不会做任何变化,所有的在original HEAD和你重置到的那个commit之间的所有变更集都放在stage(index)区域中。
2.hard
--hard参数将会blow out everything.它将重置HEAD返回到另外一个commit(取决于~12的参数),重置index以便反映HEAD的变化,并且重置working copy也使得其完全匹配起来。这是一个比较危险的动作,具有破坏性,数据因此可能会丢失!如果真是发生了数据丢失又希望找回来,那么只有使用:git reflog命令了。makes everything match the commit you have reset to.你的所有本地修改将丢失。如果我们希望彻底丢掉本地修改但是又不希望更改branch所指向的commit,则执行git reset --hard = git reset --hard HEAD. i.e. don't change the branch but get rid of all local changes.另外一个场景是简单地移动branch从一个到另一个commit而保持index/work区域同步。这将确实令你丢失你的工作,因为它将修改你的work tree!
3.mixed(default)
--mixed是reset的默认参数,也就是当你不指定任何参数时的参数。它将重置HEAD到另外一个commit,并且重置index以便和HEAD相匹配,但是也到此为止。working copy不会被更改。所有该branch上从original HEAD(commit)到你重置到的那个commit之间的所有变更将作为local modifications保存在working area中,(被标示为local modification or untracked via git status),但是并未staged的状态,你可以重新检视然后再做修改和commit
git reset soft,hard,mixed之区别深解的更多相关文章
-
git reset --soft --hard 区别
[转]git reset 之 soft mixed hard选项的区别 (2014-09-09 16:54:06) 转载▼ 标签: git 分类: Linux 译注:为了避免丢失本地的修改以及orig ...
-
撤销git reset soft head操作
一不小心在eclipse的git库中执行了Reset Soft(HEAD ONLY)操作,不料界面中竟然没有找到撤销方法(于是心中五味俱全,经过一番折腾,无果还是回归Git本身),最终通过命令行,很快 ...
-
git --mixed --soft --hard之间的区别
git reset --mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和add信息git reset --soft:回退到某个 ...
-
Whats the difference between git reset --mixed, --soft, and --hard?
https://*.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-ha ...
-
git reset、git checkout和git revert的区别
这三个git命令都是用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于commit层面,还可以作用于file层面Reset在commit层面,reset通过移除当前分支的一些节点来实现版本回滚; ...
-
git reset与git revert的区别
http://alpha-blog.wanglianghome.org/2010/07/30/git-partial-rollback/ reset(版本撤回) 格式 git reset [-q] [ ...
-
git reset revert区别
git revert HEAD~1 撤销倒数第二次提交,并将这次操作作为一个新提交添加到log里,之前的提交历史不变,是撤销某次提交 git reset,直接回退到指定版本 git reset --s ...
-
git reset 与 git revert的区别?
一,git reset的功能: 该命令修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本, 说明: 修改后,push到远程仓库时需要使用"git push -f"提 ...
-
git revert和git reset的区别
git revert 是撤销某次操作,此次操作之前的commit都会被保留 git reset 是撤销某次提交,但是此次之后的修改都会被退回到暂存区 具体一个例子,假设有三个commit, git s ...
随机推荐
-
QT征程之初识qt
下载 https://www.qt.io/cn/download-open-source/ 下载QT离线安装包 Qt 5.5.1 for Linux 32-bit (546 MB) (info ...
-
ORACLE存储过程创建失败,如何查看其原因
工作中用SQL Server比较多,Oracle可以说是小白,最近想用存储过程来完成单据复制的功能,结果遇到各种问题,其实都是非常简单的问题,但是对我来说还是花了很多时间来解决,浪费这些时间非常不值得 ...
-
【leetcode❤python】198. House Robber
class Solution(object): def rob(self, nums): """ :type nums: List[in ...
-
java单元测试(使用junit)
JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),供Java开发人员编写单元测试之用. 1.概述 Ju ...
-
编译安装lnmp
http://wenku.baidu.com/view/ec45d5dd28ea81c758f578cc.html
-
poj 2049 Let it Bead(polya模板)
Description Cannery Row percent of the target audience insists that the bracelets be unique. (Just ...
-
纯win32实现PNG图片透明窗体
#include <windows.h> #include <gdiplus.h> /* GDI+ startup token */ ULONG_PTR gdiplusSta ...
-
Learning Cocos2d-x for WP8(6)——场景切换和场景过渡效果
原文:Learning Cocos2d-x for WP8(6)--场景切换和场景过渡效果 C#(wp7)兄弟篇 Learning Cocos2d-x for XNA(6)——场景切换和场景过渡效果 ...
-
一个基于Asp.net MVC的博客类网站开源了!
背景说明: 大学时毕业设计作品,一直闲置在硬盘了,倒想着不如开源出来,也许会对一些人有帮助呢,而且个人觉得这个网站做得还是不错了,毕竟是花了不少心思,希望对你有所帮助. github地址:https: ...
-
剑指offer(36)两个链表中的第一个公共节点
题目描述 输入两个链表,找出它们的第一个公共结点. 题目分析 我发现关于链表的题都涉及双指针,大家做的时候记得用双指针. 题目理解了就很好做了,比较简单,先在长的链表上跑,知道长的和短的一样长,再一起 ...