目录
Git Reset
归属系列:
Git Reset
是git中最常用的命令,但也是最危险,最容易被误用的命令。
git reset [<mode>] [<commit ID>], it means that
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit ID>
This form “git reset” resets the current branch head to <commit>
and possibly updates the index (resetting it to the tree of <commit>
) and the working tree depending on <mode>
. If <mode>
is omitted, defaults to --mixed
. The <mode>
must be one of the following:
该格式的“git reset”重置当前的head到commit,可能更新索引(重置到commit树),工作树(工作目录)取决于模式mode。如果模式省去,则默认为mixed模式。模式必须是以下几种。
关于上图的名词解释:Working Copy 当前工作(树)目录下的文件,一般而言:有修改,既没有git add,也没有git commit的文件
- Index: staging area(暂存区)文件, 即git add 添加后的文件, 但没有git commit。文件commit之后,它就是当前HEAD的父节点。
- HEAD: 指向当前branch最新的commit,即该分支最近一次commit后的节点
- 当你首次checkout一个新的分支,HEAD默认指向该分支上最近一次commit。它的index和working copy是一样的(未曾有文件被改动)。
- 当你修改了一个文件,git会标记改动的文件,working copy不再和index和HEAD相同。
- 当你执行git add命令,会将上面修改的文件缓存在index中,此时working copy和index相同,而他们和HEAD不同。
- 当你执行git commit后,Git创建了一个新的commit,HEAD这时指向这个新的commit,此时,HEAD & index & working copy相同。
Git reset主要的参数有soft、 mixed、hard, 它们告诉Git,当执行reset时,要对index和working copy做什么。
- --soft
不改变index和工作树的内容,只将HEAD重置到commit(就像所有模式都做的一样)。这使得你所有变更的文件变成“有改变需要被提交”。
For example, git reset --soft [commit ID] 回退到某个版本,只回退了commit的信息。如果还要提交,直接commit即可
- --mixed(default)
If -N
is specified, removed paths are marked as intent-to-add (see git-add [1]).
重置Head和index,但不影响工作树(当前工作目录下改动的文件被保留,但不会被标记用来commit),并且报告哪些没有被更新。这是默认行为。
指向那个你要reset到的commit上。而working copy文件不被改变。当然会显示工作目录下有修改,但没有缓存到index中。
Note: 用于重置暂存区的文件与某次历史提交(commit)保持一致,工作区文件内容保持不变。
- --hard
重置HEAD & index & working copy(同时改变到你要reset到的那个commit上)。Commit之后任何改变的文件都会被丢弃。这个参数很危险,你的本地修改可能都会丢失。
- --merge
Resets the index and updates the files in the working tree that are different between <commit>
and HEAD
, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added). If a file that is different between <commit>
and the index has unstaged changes, reset is aborted.
In other words, --merge
does something like a git read-tree -u -m <commit>
, but carries forward unmerged index entries.
- --keep
Resets index entries and updates files in the working tree that are different between <commit>
and HEAD
. If a file that is different between <commit>
and HEAD
has local changes, reset is aborted.
- --[no-]recurse-submodules
When the working tree is updated, using --recurse-submodules will also recursively reset the working tree of all active submodules according to the commit recorded in the superproject, also setting the submodules' HEAD to be detached at that commit
注意:
如果通过 git reset --hard将版本回退到之前的commit。可以先通过 git reflog命令,找到要退回的commit Id,然后通过命令git reset —hard commit Id来恢复。
- git revert 和 git reset的区别
- git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
- 就回滚这一操作上,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit “中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
- git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
- 将本地某个分支强制更新到远程分支最新的commit
归属系列:
LINK:<li><a href="文章链接">文章标题</a></li>