GIT 基本概念 物件,索引,提交

2021-07-12 01:47:37 字數 4189 閱讀 5463

git版本庫(實際上就是乙個資料庫)不僅僅提供版本庫中所有檔案的完整副本,還提供版本庫本身的副本。

git在每個版本庫里維護一組配置值,例如版本庫的使用者名稱和email位址,在把乙個版本庫轉殖或者複製到另乙個版本庫的時候配置設定是不跟著轉移的。

git物件型別:git放在物件庫只有4種型別,塊(blob),目錄樹(tree),提交(commit)和標籤(tag)。

blob:檔案的每乙個版本表示為乙個塊,乙個blob儲存乙個檔案的資料,但是不包含任何關於這個檔案的元資料,甚至連檔名都沒有。(也就是說,檔案每修改一次就會產生乙個blob,同乙個檔案可以擁有許多blob)

tree:乙個目錄樹物件代表一層目錄資訊。它記錄blob識別符號,路徑名和乙個目錄裡的所有檔案的一些元資料。(也就是說,乙個tree目錄物件包含乙個檔案的許多不同的blob,儲存blob資訊和元資料)

【注】技術上講,乙個樹物件只代表版本庫中的乙個目錄層級。它包含該目錄下的直接檔案和它的所有直接子目錄的資訊,但不包括所有子目錄的完整內容。然而,因為樹物件引用所有子目錄的樹物件,所以對應專案根目錄的樹物件實際上代表某個時刻的整個專案。

commit:乙個提交物件儲存版本庫中每一次變化的元資料,包括作者,提交者,提交日期和日誌訊息。每乙個提交物件指向乙個目錄樹物件。(也就是說,檔案提交一次就會產生乙個提交物件,儲存提交的資訊,並將該次提交指向乙個目錄樹物件中。)

tag:乙個標籤物件分配乙個任意的且人類可以讀懂的名字給乙個特定物件,通常是乙個提交物件。commit id 很難理解,所以可以通過tag物件來制定。(也就是說,提交一次,產生乙個提交id,就可以對應乙個tag物件。)

git 同時是乙個內容追蹤系統,首先,git追蹤物件庫中的檔案內容,而不是檔名和目錄名。其次,當檔案從乙個版本變化到下乙個版本的時候,git的內部資料庫有效的儲存每個檔案的每個版本,而不是它們之間的差異。

.git/objects資料夾中存放這個git版本庫中的物件(包括blob,tree,commit...),用它的sha1雜湊值作為檔名,例如,b3bf55b0c96720f676d55b2ceb0e3c0267a1c16e。可以通過git cat-file -p b3bf55b0c96720f676d55b2ceb0e3c0267a1c16e來展現物件中的內容。可以通過git rev-parse b3bf55b0c

來獲得物件的全名。

git 通過目錄樹tree的物件來跟蹤檔案的路徑名。 通過git write-tree 來捕獲index當前的快照的物件,得到的物件即目錄樹物件。例如d0edd8a129da644ca97a5d30082db1a684779342,通過git cat-file -p d0edd8a129da644ca97a5d30082db1a684779342 可以獲得該檔名和最新blob物件(當前最新的狀態檔案)的關聯,例如,100644 blob 18d9d082662e7e2ae6bcebb683cf494b8c10c2cb    first_git.txt。也可以通過 git ls-files -s 命令很容易的看到樹物件的內容。

樹層次結構:例子:

pervious version:

hello (dir)

| (樹物件:d0edd8a129da644ca97a5d30082db1a684779342)

hello.txt

current version:

hello(dir)

| \ (樹物件:49241326..)

hello.txt subdir(dir)

| (樹物件:d0edd8a129da644ca97a5d30082db1a684779342)

hello.txt(內容一樣)

git cat-file -p 4924132693

100644 blob 18d9d082662e7e2ae6bcebb683cf494b8c10c2cb    hello.txt

040000 tree  d0edd8a129da644ca97a5d30082db1a684779342 subdir

因為subdir與pervious version的內容完全一樣,所以樹物件sha1也是一樣的,印證了git追蹤物件庫中的檔案內容,而不是檔名和目錄名。因為hello.txt內容也沒有變,當然blob的sha1也不會改變。

提交提交物件指向乙個目錄樹物件,通過git commit-tree 49241326..提交乙個tree物件,得到乙個commit物件sha1。

標籤通過 git tag -m "tag info" [tag_name] [commit_sha1] 新增標籤 

關於索引

git 的索引不包含任何檔案內容, 它僅僅追蹤你想要提交的那些內容。當執行git commit命令的時候,git 會通過檢查索引而不是工作目錄來找到提交的內容。任何時候,都可以通過git status命令來查詢索引的狀態,它會明確展現出哪些檔案git是暫存的。通過 git ls-files -s 可以看到git庫頂級樹下所有的檔案。

git庫內容變更分三個階段:(1)在git庫的工作目錄中修改(2)暫存 stage (3)提交變更

(1)中可以通過

git diff 顯示仍留在工作目錄中但是還沒有暫存的變更。(2)通過git add 將工作目錄的變更新增的cache中,通過

git diff --cached 顯示已經暫存並且等待提交的變更。(3)提交後,cache中為空,可以通過

git diff [commit_sha1] \[commit_sha1] 來檢視變更。

可以通過新增乙個.gitignore 檔案來忽略那些不需要被追蹤的檔案。

.gitignore 定義規則:

(1)空行會被忽略。

(2)#開頭的行用於注釋。

(3)乙個簡單檔名將匹配任何目錄中的同名檔案。

(4)目錄名以/ 結尾將匹配同名的目錄和子目錄,但不匹配檔案。

(5)* 萬用字元匹配,但是不能跨目錄匹配。

(6)!開頭表示取反。

例如:root dir   cat .gitignore :   *.out

root dir/subdir     cat .gitignore:    !driver. out

意思是除了 subdir/drvier.out 檔案,其它的.out 檔案都被忽略。

同一檔案,當修改了檔案的內容,修改前的sha1和修改後的sha1不一樣,因為git追蹤的是內容,而非檔名和目錄名。如果git 庫中已經追蹤了的檔案(也就是被git add),修改了這些檔案後,即使沒有再次git add,通過

git commit -a,git也會遞迴遍歷整個版本庫,自動暫存(git add)它們,然後提交。而那些全新的沒有在版本庫中被追蹤的檔案或者目錄,執行git commit -a也不會提交或追蹤它們。 通過

git rm [file_name] 可以將檔案從索引和工作目錄中都刪除,而

git rm --cached [file_name]會刪除索引中的檔案而把它保留在工作目錄中。

通過 git log --following [file_name]可以實現顯示指定的檔名的相關日誌。

通過 git log -l --pretty=oneline head可以顯示到目前為止版本庫中的所有提交id,head 始終指向當前分支的最近提交,當切換分支時,head會更新為指向新分支的最近提交。通過 git show-branch --more=10 可以檢視最近10次提交。^ 代表當前提交的不同的父提交,~ 代表當前提交的父輩提交。

通過 git log master 將以當前最近的提交開始回溯到最原始的提交,通過

git log [commit_id] 將從指定的提交開始回溯到最原始的提交。通過

git log --pretty=short master~12..master~10 可以顯示回溯第10次和第11次的提交。--pretty=oneline, shore, full  --abbrev-commit :簡單的請求縮寫sha1 id。 --stat:列舉提交中所更改的檔案以及每個更改的檔案有多少行做了改變。

通過 git show head~2 顯示當前提交資訊,並且顯示版本庫中檔案的改變。

關於提交

提交圖:有向無環圖(dag),時間軸是從左到右的,左邊的提交是右邊提交的父提交。通過

gitk命令可以檢視該版本庫的dag圖。對於合併提交(merge commit)擁有多個父提交。

識別乙個檔案的特定提交資訊工具:git blame -l 1, [file_name] (1代表從第一行開始到最後一行)

GIT基本概念

工作區是個工作目錄,實質上就是我們的在開發過程中對其進行新增 編輯的源 包括標頭檔案 原始檔和配置檔案 在工作區中有乙個隱藏檔案 git 它不屬於工作區,而是git版本庫。該檔案下包括很多其他檔案,其中重要的是暫存區 git index 物件庫 git objects 分支 master分支和其他分...

git 基本概念

理解git首先要對它自己的主要概念理解清楚,這個我看了一邊後又重新梳理了一邊思路,提取了幾個自己很容易誤解和難區分的概念,在這裡詳細介紹下 工作區 就是你在電腦裡能看到的目錄,比如我的learngit資料夾就是乙個工作區。暫存區 工作區有乙個隱藏目錄.git,這個不算工作區,而是git的版本庫。gi...

git基本概念

為了便於管理,git要求每個遠端主機都必須指定乙個主機名。git remote命令就用於管理主機名。不帶選項的時候,git remote命令列出所有遠端主機。一旦遠端主機的版本庫有了更新 git術語叫做commit 需要將這些更新取回本地,這時就要用到git fetch命令。預設情況下,git fe...