1 回答

TA貢獻2011條經驗 獲得超2個贊
git中文件內容并沒有真正存儲在索引(.git/index)或者提交對象中,而是以blob的形式分別存儲在數據庫中(.git/objects),并用SHA-1值來校驗。 索引文件用識別碼列出相關的blob文件以及別的數據。對于提交來說,以樹(tree)的形式存儲,同樣用對于的哈希值識別。樹對應著工作目錄中的文件夾,樹中包含的 樹或者blob對象對應著相應的子目錄和文件。每次提交都存儲下它的上一級樹的識別碼。
如果用detached HEAD提交,那么最后一次提交會被the reflog for HEAD引用。但是過一段時間就失效,最終被回收,與git commit --amend或者git rebase很像。
git 模型可以抽象為 遠程倉庫——remote, 本地三級倉庫: level1——working directory level2——stage(index) level3——repository(History)
git 各個命令可以理解為在各個倉庫間轉移數據,各個命令對應對每個倉庫輸入輸出。
便于記憶可以簡單分為 低level輸入和 高level輸入, 注意各level并不一定是相鄰的level間轉移,可以跨level轉移,通過git命令的參數選項來實現,
如常見的 git checkout git reset git commit
低level輸入 高level 輸入
working directory 手工創建 git checkout/git stash
stage(index) git add git reset
History(repository) git commit git pull
remote git push -
根據上述表格,結合git命令各種參數的結合,可以數據在各倉庫間的轉移,
需要注意的是不論參數如何變化,, 除了git reset 外,上述各命令目的倉庫按照如上表所示是確定的,參數和選項來決定數據的來源
基本用法
上面的四條命令在工作目錄、暫存目錄(也叫做索引)和倉庫之間復制文件。
git add files 把當前文件放入暫存區域。
git commit 給暫存區域生成快照并提交。
git reset -- files 用來撤銷最后一次git add files,你也可以用git reset 撤銷所有暫存區域文件。(操作對象是HEAD)
git checkout -- files 把文件從暫存區域復制到工作目錄,用來丟棄本地修改。(目的是working Directory)
你可以用 git reset -p, git checkout -p, or git add -p進入交互模式。
也可以跳過暫存區域直接從倉庫取出文件或者直接提交代碼, 如下
git commit -a 相當于運行 git add 把所有當前目錄下的文件加入暫存區域再運行。git commit.
git commit files 進行一次包含最后一次提交加上工作目錄中文件快照的提交。并且文件被添加到暫存區域。
git checkout HEAD -- files 回滾到復制最后一次提交。
diff
有許多種方法查看兩次提交之間的變動。下面是一些示例。
本質上就是在前言中表述的4個level中任意指定2個倉庫進行比較
4
commit
提交時,git用暫存區域的文件創建一個新的提交,并把此時的節點設為父節點。然后把當前分支指向新的提交節點。下圖中,當前分支是master。 在運行命令之前,master指向ed489,提交后,master指向新的節點f0cec并以ed489作為父節點
5
下圖中,在master分支的祖父節點maint分支進行一次提交,生成了1800b。 這樣,maint分支就不再是master分支的祖父節點。此時,合并 (或者 衍合) 是必須的。
6
如果想更改一次提交,使用 git commit --amend。git會使用與當前提交相同的父節點進行一次新提交,舊的提交會被取消
7
checkout
checkout命令用于從歷史提交(或者暫存區域)中拷貝文件到工作目錄,也可用于切換分支。
當給定某個文件名(或者打開-p選項,或者文件名和-p選項同時打開)時,git會從指定的提交中拷貝文件到暫存區域和工作目錄。比如,git checkout HEAD~ foo.c會將提交節點HEAD~(即當前提交節點的父節點)中的foo.c復制到工作目錄并且加到暫存區域中。(如果命令中沒有指定提交節點,則會從暫存區域中拷貝內容。)
注意當前分支不會發生變化(HEAD指向原處)。
8
當不指定文件名,而是給出一個(本地)分支時,那么HEAD標識會移動到那個分支(也就是說,我們“切換”到那個分支了),然后暫存區域和工作目錄中的內容會和HEAD對應的提交節點一致。新提交節點(下圖中的a47c3)中的所有文件都會被復制(到暫存區域和工作目錄中);只存在于老的提交節點(ed489)中的文件會被刪除;不屬于上述兩者的文件會被忽略,不受影響。
9
如果既沒有指定文件名,也沒有指定分支名,而是一個標簽、遠程分支、SHA-1值或者是像master~3類似的東西,就得到一個匿名分支,稱作detached HEAD(被分離的HEAD標識)。這樣可以很方便地在歷史版本之間互相切換。比如說你想要編譯1.6.6.1版本的git,你可以運行git checkout v1.6.6.1(這是一個標簽,而非分支名),編譯,安裝,然后切換回另一個分支,比如說git checkout master。然而,當提交操作涉及到“分離的HEAD”時,其行為會略有不同,詳情見在下面。
10
HEAD標識處于分離狀態時的提交操作
當HEAD處于分離狀態(不依附于任一分支)時,提交操作可以正常進行,但是不會更新任何已命名的分支。(你可以認為這是在更新一個匿名分支。)
11
一旦此后你切換到別的分支,比如說master,那么這個提交節點(可能)再也不會被引用到,然后就會被丟棄掉了。注意這個命令之后就不會有東西引用2eecb。
12
但是,如果你想保存這個狀態,可以用命令git checkout -b name來創建一個新的分支。
- 1 回答
- 0 關注
- 3312 瀏覽
添加回答
舉報