# Git command之回退篇
`欲練回退 必先了解:HEAD、index、WorkingCopy`

> HEAD: 對(duì)應(yīng)local repository,指當(dāng)前所在的分支版本頂端的別名,也就是最新的一次commit. git commit 之后與HEAD一致
>
> index: 對(duì)應(yīng)staging area,指git add 之后放入該區(qū)域
>
> WorkingCopy: 對(duì)應(yīng)working directory,指當(dāng)前文件包括修改等操作所在區(qū)域,沒(méi)有 git add 和 git commit 操作
## git reset HEAD --file (單個(gè)文件)
### 可與git checkout --file配合
> 1. git reset HEAD --file:回退暫存區(qū)里的某個(gè)文件,還原為HEAD commit里該文件的狀態(tài),撤銷從上一次commit之后所有的操作?;蛘哒f(shuō)是從HEAD commit里重新拉到暫存區(qū)覆蓋當(dāng)前的(被add亂掉的)文件。但是working copy里沒(méi)有任何變化。此時(shí)如果想丟掉working copy里的修改,執(zhí)行g(shù)it checkout --file.
> 2. git checkout --file:是以最新的存儲(chǔ)時(shí)間節(jié)點(diǎn)(add和commit)為參照,覆蓋工作區(qū)對(duì)應(yīng)文件file:如果上次commit之后沒(méi)有將任何修改add到暫存區(qū),則HEAD和暫存區(qū)是一致的,執(zhí)行命令后也會(huì)將工作區(qū)同化為一致,看起來(lái)像是從HEAD版本庫(kù)重拉了一遍到工作區(qū)。但如果上次commit之后往暫存區(qū)add了修改,那么工作區(qū)只能跟暫存區(qū)一致了,也就是從暫存區(qū)拉下來(lái)覆蓋到工作區(qū)。
## git reset --hard HEAD
> 影響同下面介紹的<git reset --hard? 目標(biāo)版本號(hào)>,只是HEAD位置看起來(lái)沒(méi)有變化。小技巧:上個(gè)版本用HEAD^或者HEAD~1,上上個(gè)版本HEAD^^或者HEAD~2,上100個(gè)版本HEAD~100
## git reset --hard? 目標(biāo)版本號(hào)
> 版本號(hào)指:commit生成的hash碼,可用 git log 命令查看
>
> 該命令修改HEAD的位置,即將HEAD指向的位置改變?yōu)橹按嬖诘哪硞€(gè)版本,最后需要用 git push -f 強(qiáng)推到遠(yuǎn)端
>
> --hard參數(shù)將會(huì)blow out everything.它將重置HEAD返回到另外一個(gè)commit,重置index以便反映HEAD的變化,并且重置working copy也使得其完全匹配起來(lái)。
`這是一個(gè)比較危險(xiǎn)的動(dòng)作,具有破壞性,數(shù)據(jù)因此可能會(huì)丟失!如果真是發(fā)生了數(shù)據(jù)丟失又希望找回來(lái),那么只有使用:[git reflog](http://blog.csdn.net/ibingow/article/details/7541402)命令了。`
## git reset --soft 目標(biāo)版本號(hào)
> --soft參數(shù)Git重置HEAD到另外一個(gè)commit,HEAD位置改變,但index,working copy都不會(huì)做任何變化,所有的在original HEAD和你重置到的那個(gè)commit之間的所有變更集都放在stage(index)區(qū)域中。
## git reset --mixed 目標(biāo)版本號(hào)
> --mixed是reset的默認(rèn)參數(shù),也就是當(dāng)你不指定任何參數(shù)時(shí)的參數(shù)。它將重置HEAD到另外一個(gè)commit,并且重置index以便和HEAD相匹配,但working copy不會(huì)被更改。所有該branch上從original HEAD(commit)到你重置到的那個(gè)commit之間的所有變更(未git add的操作)將作為local modifications保存在working area中,你可以接著coding,之后再進(jìn)行g(shù)it add, git commit.
`總結(jié):--hard --mixed(default) --soft? 分別覆蓋3個(gè)、2個(gè)、1個(gè)位置的代碼,--mixed(默認(rèn)的參數(shù))只會(huì)保留working copy里的代碼`
## git revert -n 目標(biāo)版本號(hào)
> 1. 與git reset不同的是,復(fù)制了一個(gè)目標(biāo)版本(某個(gè)想要回退到的歷史版本)加在當(dāng)前分支的最前端。而git reset是HEAD指針跳到目標(biāo)版本,但將跳過(guò)的版本丟棄掉了。(git log已經(jīng)看不到,但git rflog還是可以看到的)
> 2. use 'git commit -m "the name of the new release" ' to commit
> 3. use 'git push' to push
## git commit --amend
> 1. 改寫(xiě)commit,包括改寫(xiě)提交的文件和追加文件到提交中。
> 2. 還可以對(duì)這種改寫(xiě)回退,用git reflog得到相應(yīng)的版本號(hào),然后git reset --soft HEAD@{xxx}