轉載整理自:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013743256916071d599b3aed534aaab22a0db6c4e07fd0000git
其實,咱們每次執行能夠改變暫存區或分支的git命令時,只要這個命令操做的文件的內容的散列值尚未在.git/objects目錄下做爲一個文件的文件名,這個文件就會被添加到.git/objects下,文件名(確切地說散列值的前兩個字符會做爲一級文件夾名)就是那個散列值,而暫存區和分支裏的不過是這個文件的指針而已。做爲版本控制的用戶,咱們主要應關注工做區、暫存區、版本庫的關係,.git/objects屬於git的底層實現了。程序員
咱們執行git init命令的那個目錄就是咱們的工做區。工做區有一個隱藏目錄.git
,這個不算工做區,而是Git的版本庫。Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲咱們自動建立的第一個分支master
,以及指向master
的一個指針叫HEAD
。spa
咱們把文件往Git版本庫裏添加的時候,是能夠分兩步執行的:版本控制
git add
把文件添加進去,實際上就是把文件修改添加到暫存區;git commit
提交更改,實際上就是把暫存區的全部內容提交到當前分支。由於咱們建立Git版本庫時,Git自動爲咱們建立了惟一一個master
分支,因此,如今,git commit
就是往master
分支上提交更改。你能夠簡單理解爲,須要提交的文件修改都經過git add(可連續屢次)放到暫存區,而後,一次性經過git commit提交暫存區的全部修改。指針
咱們要注意:在提交之後,工做區、暫存區、版本庫的內容都同樣了(暫存區、版本庫保存的實際上是指針)。git提供了兩條命令來比較工做區、暫存區和暫存區、版本庫當前分支的差別的命令,分別是code
提交之後咱們能夠分別執行一下這兩個命令,你會發現:「在提交之後,工做區、暫存區、版本庫的內容都同樣了」。blog
天然,每個程序員都會犯錯誤。版本控制系統除了提供咱們「版本管理」的功能,還應該能夠在咱們犯了錯之後讓咱們很方便地回退到前一個版本(丟棄工做區的修改)。相比與其餘版本控制系統,git還提供了暫存區功能,所以咱們還能夠回退到上一次修改而不用回退到上一個版本,提供了更大的自由度。it
從暫存區恢復,或稱「拿暫存區文件替換工做區文件」(譬如錯誤還在工做區)命令:ast
git checkout -- file版本管理
從當前分支的最新一次提交恢復,或稱「拿版本庫文件替換暫存區、工做區文件」(譬如錯誤已經add到了暫存區)命令:
git reset HEAD file
從當前分支的上上次的提交恢復(譬如錯誤已經被提交):
詳見分支管理篇
在咱們版本升級過程當中,除了文件內容的修改以外,文件名和文件夾名有時候也須要改變。有不少git命令須要瞭解更名歷史,譬如git diff。但git不是記錄更名,而是探測更名,每次須要瞭解更名歷史時(通常時-M[<n>]或--find-renames[=<n>]參數),git都會去探測更名,默認時50%類似度。