譯注:為了避免丟失本地的修改以及original HEAD,建議在進行reset操作之前,在本地創建一個新的branch,在新的branch上面進行reset,以保證master分支永遠處於original HEAD
以下為轉發的正文
The reset command. Confusing. Misunderstood. Misused. But it doesn’t need to be that way! It’s really not too confusing once you figure out what’s going on.
Definitions
首先,讓我們來解釋幾個定義.
First, let’s define a few terms.
HEAD(頭)
指向當前branch最頂端的一個commit,該分支上一次commit后的節點
This is an alias for the tip of the current branch, which is the most recent commit you have made to that branch.
Index(索引)
The index, 也可以被認為是staging area(暫存區), 是一堆將在下一次commit中提交的文件,提交之后它就是 HEAD的父節點. (譯注:git add添加的文件)
The index, also known as the staging area, is the set of files that will become the next commit. It is also the commit that will become HEAD’s parent.
Working Copy(工作副本)
當前工作目錄下的文件,(譯注:一般指,有修改,沒有git add,沒有git commit的文件)
This is the term for the current set of files you’re working on in your file system.
Flow(流程如下)
當你第一次checkout一個新的分支,HEAD指向該分支上最近一次commit。它和index和working copy是一樣一樣的。
When you first checkout a branch, HEAD points to the most recent commit in the branch. The files in the HEAD (they aren’t technically files, they’re blobs but for the purposes of this discussion we can think of them as straight files) match that of the files in the index, and the files checked out in your working copy match HEAD and the index as well. All 3 are in an equal state, and Git is happy.
當你修改了一個文件,Git注意到了會說“哦,有些東西被改了”,你的working copy不再和index和HEAD相同了,所以當文件有改動,它會標記這些文件。
When you perform a modification to a file, Git notices and says “oh, hey, something has changed. Your working copy no longer matches the index and HEAD.” So it marks the file as changed.
然后,你執行git add命令,這條命令會將上面修改的文件緩存在index中,Git又說了“哦,你的working copy和index相同了,而他們倆和HEAD不同了”。
Then, when you do a git add
, it stages the file in the index, and Git says “oh, okay, now your working copy and index match, but those are both different than HEAD.”
當你執行git commit,Git創建了一個新的commit,HEAD這時指向這個新的commit,此時,HEAD & index & working copy又相同了,Git又開心了一次。
When you then perform a git commit
, Git creates a new commit that HEAD now points to and the status of the index and working copy match it so Git’s happy once more.
Reset
If you just look at the reset command by itself, all it does is reset HEAD (the tip of the current branch) to another commit. For instance, say we have a branch (the name doesn’t matter, so let’s call this one “super-duper-feature”) and it looks like so:
If we perform:
> git reset HEAD
… nothing happens. This is because we tell git to reset this branch to HEAD, which is where it already is. But if we do:
> git reset HEAD~1
(HEAD~1 is shorthand case for “the commit right before HEAD”, or put differently “HEAD’s parent”) our branch now looks like so:
If we start at the latest commit again and do:
> git reset HEAD~2
our branch would look like so:
Again, all it does on a basic level is move HEAD to another commit.
Parameters
reset命令本身很簡單,但是它的參數讓人迷惑,主要的參數有soft
, hard
and mixed,它們告訴Git,當執行reset時,要對index和working copy做什么。
So the reset command itself is pretty simple, but it’s the parameters that cause confusion. The main parameters are soft
, hard
and mixed
. These tell Git what to do with your index and working copy when performing the reset.
Soft
The --soft
參數只告訴Git將其他的commit重置到HEAD,就僅此而已。index和working copy中的文件都不改變。
parameter tells Git to reset HEAD to another commit, but that’s it. If you specify --soft
Git will stop there and nothing else will change. What this means is that the index and working copy don’t get touched, so all of the files that changed between the original HEAD and the commit you reset to appear to be staged.
Mixed (default)
The --mixed
改變HEAD和index,指向那個你要reset到的commit上。而working copy文件不被改變。當然會顯示工作目錄下有修改,但沒有緩存到index中。
parameter (which is the default if you don’t specify anything) will reset HEAD to another commit, and will reset the index to match it, but will stop there. The working copy will not be touched. So, all of the changes between the original HEAD and the commit you reset to are still in the working copy and appear as modified, but not staged.
Hard
The --hard
HEAD & index & working copy同時改變到你要reset到的那個commit上。這個參數很危險,執行了它,你的本地修改可能就丟失了。
parameter will blow out everything – it resets HEAD back to another commit, resets the index to match it, and resets the working copy to match it as well. This is the more dangerous of the commands and is where you can cause damage. Data might get lost here*!
轉自:http://davidzych.com/2014/05/24/difference-between-git-reset-soft-mixed-and-hard