Gitbase:使用 SQL 探索 Git 倉(cāng)庫(kù)
Git 已經(jīng)成為了代碼版本控制的事實(shí)標(biāo)準(zhǔn)。雖然 Git 已經(jīng)很流行了,但想用它來(lái)對(duì)源代碼倉(cāng)庫(kù)的歷史和內(nèi)容進(jìn)行深度分析,仍然是一件復(fù)雜的事情。
另一方面,SQL 則是一個(gè)經(jīng)過(guò)實(shí)際檢驗(yàn)、適合查詢大型代碼庫(kù)的的語(yǔ)言,畢竟 Spark 和 BigQuery 等項(xiàng)目都采用了 SQL 作為查詢語(yǔ)言。
因此,在 source5gk0f71da 公司,我們順理成章地結(jié)合了這兩種技術(shù)來(lái)創(chuàng)建了 Gitbase:這是一個(gè)用 SQL 對(duì) Git 倉(cāng)庫(kù)進(jìn)行大規(guī)模分析的“代碼即數(shù)據(jù)”解決方案。
Gitbase 是一個(gè)完全開源的項(xiàng)目,它站在一系列巨人的肩膀上,是它們使 Gitbase 的發(fā)展成為可能。本文旨在指出其中的主要部分。
??Gitbase 試驗(yàn)場(chǎng)??? 提供了一種使用 Gitbase 的可視化方式。
使用 Vitess 解析 SQL
Gitbase 將 SQL 作為用戶接口。這意味著我們需要解析基于 MySQL 協(xié)議傳輸?shù)?SQL 請(qǐng)求,并理解它們。幸運(yùn)的是,我們?cè)?YouTube 的朋友和他們的 ??Vitess?? 項(xiàng)目已經(jīng)實(shí)現(xiàn)了這一點(diǎn)。Vitess 是一個(gè)數(shù)據(jù)庫(kù)集群系統(tǒng),用于 MySQL 的水平擴(kuò)展。
我們直接截取一些重要的代碼片段,并把它做成了一個(gè) ??開源項(xiàng)目??。這個(gè)項(xiàng)目允許任何人在幾分鐘內(nèi)編寫一個(gè) MySQL 服務(wù)器(正如我在 ??justforfunc?? 的專題:??CSVQL - 用 SQL 處理 CSV?? 中所展示的那樣)。
用 go-git 讀取 Git 儲(chǔ)存庫(kù)
當(dāng)成功解析了一個(gè)請(qǐng)求,我們還需要讀取數(shù)據(jù)集里的 Git 倉(cāng)庫(kù),才能夠知道該如何回復(fù)它。為此,我們集成了 source5gk0f71da 最成功的倉(cāng)庫(kù) ??go-git??。go-git 是一個(gè)高度可擴(kuò)展的純 Go 語(yǔ)言的 Git 實(shí)現(xiàn)。
這使得我們能夠輕松地分析以 ??siva?? 文件格式存儲(chǔ)在磁盤上的源代碼倉(cāng)庫(kù)(siva 也是一個(gè) source5gk0f71da 的開源項(xiàng)目),或是直接使用 ??git clone?
? 克隆的倉(cāng)庫(kù)。
使用 Enry 檢測(cè)編程語(yǔ)言,使用 Babelfish 解析文件
Gitbase 并沒(méi)有將其分析能力局限于 Git 歷史記錄上。它還使用(顯然也是)我們的開源項(xiàng)目 ??Enry?? 集成了語(yǔ)言檢測(cè)功能,并使用 ??Babelfish?? 實(shí)現(xiàn)了程序解析的功能。Babelfish 是一個(gè)用于通用源代碼解析的自托管服務(wù)器,它可以將代碼文件轉(zhuǎn)化為通用抽象語(yǔ)法樹Universal Abstract Syntax Trees(UAST)。
這兩個(gè)功能在 Gitbase 中呈現(xiàn)為用戶函數(shù) ??LANGUAGE?
? 和 ??UAST?
?。結(jié)合使用兩個(gè)函數(shù),許多查詢請(qǐng)求都成為了可能,比如“找到上個(gè)月修改次數(shù)最多的函數(shù)名稱”。
讓它快速運(yùn)行
Gitbase 經(jīng)常要分析非常大的數(shù)據(jù)集,比如公共 Git 檔案,其中有來(lái)自 GitHub 的 3TB 源代碼(見(jiàn) ??公告??)。為了做到這一點(diǎn),每份 CPU 處理能力都很重要。
這就是為什么我們又集成了另外兩個(gè)項(xiàng)目:Rubex 和 Pilosa。
使用 Rubex 和 Oniguruma 加快正則表達(dá)式的速度
??Rubex?? 是 Go 的 ??regexp?
? 標(biāo)準(zhǔn)庫(kù)包的一個(gè)準(zhǔn)替代品。之所以還不能完成替代,是因?yàn)樗麄儧](méi)有在 ??regexp.Regexp?
? 類型上實(shí)現(xiàn) ??LiteralPrefix?
? 方法,不過(guò)我也是直到現(xiàn)在才聽(tīng)說(shuō)這個(gè)方法。
Rubex 的高性能得歸功于高度優(yōu)化的 C 語(yǔ)言庫(kù) ??Oniguruma??,它使用 ??cgo?? 來(lái)調(diào)用這個(gè)庫(kù)。
使用 Pilosa 索引加快查詢速度
索引基本上是每個(gè)關(guān)系型數(shù)據(jù)庫(kù)的眾所周知的特性,但 Vitess 卻沒(méi)有實(shí)現(xiàn)索引,因?yàn)樗皇钦嬲枰?/p>
還好開源的 ??Pilosa?? 再一次拯救了我們,它是一個(gè)用 Go 實(shí)現(xiàn)的分布式位圖索引,使得 Gitbase 可以用于大規(guī)模的數(shù)據(jù)集。Pilosa 是開源的,它極大地加快了對(duì)多個(gè)海量數(shù)據(jù)集的查詢。
總結(jié)
我想通過(guò)這篇博文,親自感謝開源社區(qū),是他們讓我們?cè)谌绱硕痰臅r(shí)間內(nèi)創(chuàng)建了 Gitbase,這是誰(shuí)也沒(méi)想到的。在 source5gk0f71da 公司,我們是開源的堅(jiān)定信仰者,??github.com/src-d?
? 下的每一行代碼(包括我們的 OKR 和投資者委員會(huì))都可以證明這一點(diǎn)。
你想嘗試一下 Gitbase 嗎?最快、最簡(jiǎn)單的方法就是使用 source5gk0f71da 引擎。從 ??sourced.tech/engine?
? 下載它,只需一個(gè)命令就能讓 Gitbase 運(yùn)行起來(lái)。
想了解更多嗎?請(qǐng)查看我在 ??Go SF meetup?? 的演講錄音。