第 9 章 附錄 A: Git的缺點(diǎn)

2018-02-24 15:45 更新

有一些Git的問題,我已經(jīng)藏在毯子下面了。有些可以通過腳本或回調(diào)方法輕易地解決, 有些需要重組或重定義項(xiàng)目,少數(shù)剩下的煩惱,還只能等待?;蛘吒玫?,投入進(jìn)來幫 忙。

SHA1 的弱點(diǎn)

隨著時(shí)間的推移,密碼學(xué)家發(fā)現(xiàn)越來越多的SHA1的弱點(diǎn)。已經(jīng)發(fā)現(xiàn)對(duì)對(duì)資源雄厚的組織 哈希沖撞是可能的。在幾年內(nèi),或許甚至一個(gè)一般的PC也將有足夠計(jì)算能力悄悄摧毀一 個(gè)Git倉(cāng)庫(kù)。

希望在進(jìn)一步研究摧毀SHA1之前,Git能遷移到一個(gè)更好的哈希算法。

微軟 Windows

Git在微軟Windows上可能有些繁瑣:

不相關(guān)的文件

如果你的項(xiàng)目非常大,包含很多不相關(guān)的文件,而且正在不斷改變,Git可能比其他系統(tǒng) 更不管用,因?yàn)楠?dú)立的文件是不被跟蹤的。Git跟蹤整個(gè)項(xiàng)目的變更,這通常才是有益的。

一個(gè)方案是將你的項(xiàng)目拆成小塊,每個(gè)都由相關(guān)文件組成。如果你仍然希望在同一個(gè)資 源庫(kù)里保存所有內(nèi)容的話,可以使用?git submodule?。

誰在編輯什么?

一些版本控制系統(tǒng)在編輯前強(qiáng)迫你顯示地用某個(gè)方法標(biāo)記一個(gè)文件。盡管這種要求很煩 人,尤其是需要和中心服務(wù)器通訊時(shí),不過它還是有以下兩個(gè)好處的:

  1. 比較速度快,因?yàn)橹挥斜粯?biāo)記的文件需要檢查。
  2. 可以知道誰在這個(gè)文件上工作,通過查詢?cè)谥行姆?wù)器誰把這個(gè)文件標(biāo)記為編輯狀 態(tài)。

使用適當(dāng)?shù)哪_本,你也可以使Git達(dá)到同樣的效果。這要求程序員協(xié)同工作,當(dāng)他編輯一 個(gè)文件的時(shí)候還要運(yùn)行特定的腳本。

文件歷史

因?yàn)镚it記錄的是項(xiàng)目范圍的變更,重造單一文件的變更歷史比其他跟蹤單一文件的版本 控制系統(tǒng)要稍微麻煩些。

好在麻煩還不大,也是值得的,因?yàn)镚it其他的操作難以置信地高效。例如,git checkoutcp -a都快,而且項(xiàng)目范圍的delta壓縮也比基于文件的delta集合的做法 好多了。

初始克隆

The initial cost is worth paying in the long run, as most future operations will then be fast and offline. However, in some situations, it may be preferable to create a shallow clone with the?--depth?option. This is much faster, but the resulting clone has reduced functionality.

當(dāng)一個(gè)項(xiàng)目歷史很長(zhǎng)后,與在其他版本系統(tǒng)里的檢出代碼相比,創(chuàng)建一個(gè)克隆的開銷會(huì) 大的多。

長(zhǎng)遠(yuǎn)來看,開始付出的代價(jià)還是值得付出的,因?yàn)榇蠖鄬淼牟僮鲗⒂纱俗兊煤芸?,?可以離線完成。然而,在一些情況下,使用--depth創(chuàng)建一個(gè)淺克隆比較劃算些。這種 克隆初始化的更快,但得到克隆的功能有所削減。

不穩(wěn)定的項(xiàng)目

變更的大小決定寫入的速度快慢是Git的設(shè)計(jì)。一般人做了小的改動(dòng)就會(huì)提交新版本。這 里一行臭蟲修改,那里一個(gè)新功能,修改掉的注釋等等。但如果你的文件在相鄰版本之 間存在極大的差異,那每次提交時(shí),你的歷史記錄會(huì)以整個(gè)項(xiàng)目的大小增長(zhǎng)。

任何版本控制系統(tǒng)對(duì)此都束手無策,但標(biāo)準(zhǔn)的Git用戶將遭受更多,因?yàn)橐话銇碚f,歷史 記錄也會(huì)被克隆。

應(yīng)該檢查一下變更巨大的原因?;蛟S文件格式需要改變一下。小修改應(yīng)該僅僅導(dǎo)致幾個(gè) 文件的細(xì)小改動(dòng)。

或許,數(shù)據(jù)庫(kù)或備份/打包方案才是正選,而不是版本控制系統(tǒng)。例如,版本控制就不適 宜用來管理網(wǎng)絡(luò)攝像頭周期性拍下的照片。

如果這些文件實(shí)在需要不斷更改,他們實(shí)在需要版本控制,一個(gè)可能的辦法是以中心的 方式使用Git??梢詣?chuàng)建淺克隆,這樣檢出的較少,也沒有項(xiàng)目的歷史記錄。當(dāng)然,很多 Git工具就不能用了,并且修復(fù)必須以補(bǔ)丁的形式提交。這也許還不錯(cuò),因?yàn)樗坪鯖]人需 要大幅度變化的不穩(wěn)定文件歷史。

另一個(gè)例子是基于固件的項(xiàng)目,使用巨大的二進(jìn)制文件形式。用戶對(duì)固件文件的變化歷 史沒有興趣,更新的壓縮比很低,因此固件修訂將使倉(cāng)庫(kù)無謂的變大。

這種情況,源碼應(yīng)該保存在一個(gè)Git倉(cāng)庫(kù)里,二進(jìn)制文件應(yīng)該單獨(dú)保存。為了簡(jiǎn)化問題, 應(yīng)該發(fā)布一個(gè)腳本,使用Git克隆源碼,對(duì)固件只做同步或Git淺克隆。

全局計(jì)數(shù)器

一些中心版本控制系統(tǒng)維護(hù)一個(gè)正整數(shù),當(dāng)一個(gè)新提交被接受的時(shí)候這個(gè)整數(shù)就增長(zhǎng)。Git則是通過哈希值來記錄所有變更,這在大多數(shù)情況下都工作的不錯(cuò)。

但一些人喜歡使用整數(shù)的方法。幸運(yùn)的是,很容易就可以寫個(gè)腳本,這樣每次更新,中心Git倉(cāng)庫(kù)就增大這個(gè)整數(shù),或使用tag的方式,把最新提交的哈希值與這個(gè)整數(shù)關(guān)聯(lián)起來。

每個(gè)克隆都可以維護(hù)這么個(gè)計(jì)數(shù)器,但這或許沒什么用,因?yàn)橹挥兄行膫}(cāng)庫(kù)以及它的計(jì)數(shù)器對(duì)每個(gè)人才有意義。

空子目錄

空子目錄不可加入管理??梢酝ㄟ^創(chuàng)建一個(gè)空文件以繞過這個(gè)問題。

Git的當(dāng)前實(shí)現(xiàn),而不是它的設(shè)計(jì),是造成這個(gè)缺陷的原因。如果運(yùn)氣好,一旦Git得到 更多關(guān)注,更多用戶要求這個(gè)功能,這個(gè)功能就會(huì)被實(shí)現(xiàn)。

初始提交

傳統(tǒng)的計(jì)算機(jī)系統(tǒng)從0計(jì)數(shù),而不是1。不幸的是,關(guān)于提交,Git并不遵從這一約定。很 多命令在初始提交之前都不友好。另外,一些極少數(shù)的情況必須作特別地處理。例如重 訂一個(gè)使用不同初始提交的分支。

Git將從定義零提交中受益:一旦一個(gè)倉(cāng)庫(kù)被創(chuàng)建起來,HEAD將被設(shè)為包含20個(gè)零字節(jié) 的字符串。這個(gè)特別的提交代表一棵空的樹,沒有父節(jié)點(diǎn),早于所有Git倉(cāng)庫(kù)。

然后運(yùn)行g(shù)it log,比如,通知用戶至今還沒有提交過變更,而不是報(bào)告致命錯(cuò)誤并退出。 這與其他工具類似。

每個(gè)初始提交都隱式地成為這個(gè)零提交的后代。

不幸的是還有更糟糕的情況。如果把幾個(gè)具有不同初始提交的分支合并到一起,之后的 重新修訂不可避免的需要人員的介入。

接口怪癖

對(duì)提交A和提交B,表達(dá)式“A..B”和“A…B”的含義,取決于命令期望兩個(gè)終點(diǎn)還是一 個(gè)范圍。參見?git help diff?和?git help rev-parse?。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)