2013-07-01 108 views
2

說,我有內容的文件:git如何管理其文件版本?

1111 
2222 
3333 

然後我將它修改爲:

1111 
2222 
4444 
3333 

不混帳產生的更新版本,一個新的文件?我很困惑,如果它創建了新文件,那麼整個存儲庫大小會很快增長嗎?

另一個想法是,Git不會創建新文件,只是存儲要添加的位置或刪除行的位置,以及存儲新行的內容。

哪一個是正確的?

回答

1

Git只是存儲跨項目的內容更改。增量差異。在任何給定的時間點,任何與某個先前文件相同的文件被記錄爲指向描述該先前文件內容的對象的指針。它在文件內容上使用散列來知道何時文件發生了變化,並且找到與之前版本相匹配的文件,因此不必多次存儲相同的東西。

它也有一個簡單的數據庫,描述所有的變化及其關係。

這裏是關於存儲庫是如何組織的一些文檔:

https://www.kernel.org/pub/software/scm/git/docs/gitrepository-layout.html


附加說明大約節省空間:Git的大空間節約原來是不存儲在同一個文件的兩倍。其他內容管理器不像Gi​​t那樣使用指向文件版本的指針,這會在項目版本的生命週期中節省大量成本。由於對於項目的移動版本,只有少數文件會發生更改。

+0

我知道一個文件與之前的文件一樣會被記錄爲一個文件,但是如果一個文件只是改了幾行,它的哈希碼將會不同,Git是否也只是存儲了新的行? – MrROY

+0

沒有整個文件 - 但是當你轉移(例如,當上傳到github)時,它會進行壓縮。與CVS等相比,節省空間處於項目級別。 – Hogan

+0

對不起......我不是母語......「不是整個文件」是指「不是整個文件」? :D – MrROY

1

對於普通文件,git將它們存儲爲blob對象,而git將文件的每個版本分別存儲爲blob s。所以他們分開存儲。這樣做的好處是您可以快速檢出一些提交(而不是回溯並執行所有修補操作)。

對於存儲庫大小問題,git提供了一個對象打包機制並自動(或根據您的需求)壓縮數據。在大多數情況下這不是一個大問題。

+0

在'git ls-files'和'git cat-file'的幫助下,您可以實際查看每個單獨對象的內容,並且您會發現這是事實。 –

4

許多較老的源代碼管理系統,如RCS和CVS,在文件版本之間專門存儲區別。例如,給定源文件的信息可能會以包含最新版本全文的形式存儲在存儲庫中,另外還有用於生成早期版本的「說明」。

Git至少在概念上將存儲庫中每個文件的每個版本的全部內容存儲起來。它通過僅存儲相同文件的一個副本來節省一些空間,因爲用於存儲它的名稱是通過對內容進行散列來確定的。

很明顯,如果這是整個故事,Git倉庫將非常快速地變得非常大。但Git會自動打包或壓縮存儲的對象。坦率地說,我不知道所有的細節,但它在減少存儲空間和允許任意版本快速重新創建方面做得很好。

例如,Git源自身存儲在Git存儲庫中,該存儲庫可能包含數千個不同的對象。所有文件的所有版本的目錄.git/objects/pack,目前包含以下下保存(上市是一個克隆的我的系統上):

$ ls -l .git/objects/pack 
total 48900 
-r--r--r-- 1 kst kst 4196172 Mar 20 15:44 pack-0e69de7b7728ad0fde80423ded259dbff7760016.idx 
-r--r--r-- 1 kst kst 36698393 Mar 20 15:44 pack-0e69de7b7728ad0fde80423ded259dbff7760016.pack 
-r--r--r-- 1 kst kst 125896 Jun 30 22:17 pack-2848a675d3c196391f06cc7cdd6cebf67fb7119e.idx 
-r--r--r-- 1 kst kst 3570770 Jun 30 22:17 pack-2848a675d3c196391f06cc7cdd6cebf67fb7119e.pack 
-r--r--r-- 1 kst kst 178452 May 16 08:22 pack-bfd75de39dff6ac03adcc775f7b5715480b54637.idx 
-r--r--r-- 1 kst kst 5292998 May 16 08:22 pack-bfd75de39dff6ac03adcc775f7b5715480b54637.pack 

相比較早的系統有什麼關於Git的不同(至少對我使用的早期系統)是,在高層次上,存儲庫中所有文件的所有版本都是完整存儲的,但壓縮是由單獨的層提供的。

+0

「Git在存儲庫中存儲每個文件的每個版本的全部內容」,你能提供關於這個的任何鏈接嗎?非常感謝! – MrROY

+0

壓縮方案的一些細節在[git book](http://git-scm.com/book)中描述,但簡短版本是:壓縮個別「文件」(這包括樹和提交條目!)使用zlib,然後包可以將增量壓縮應用於其中的對象。 Gory在這裏詳細說明:http://stackoverflow.com/questions/9478023/is-the-git-binary-diff-algorithm-delta-storage-standardized – torek

+0

「Git將每個文件的每個版本的全部內容存儲在存儲庫中」不完全是。 Git不存儲同一對象的重複項。 –