W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
如果你想在一個 Java 程序中使用 Git ,有一個功能齊全的 Git 庫,那就是 JGit 。 JGit 是一個用 Java 寫成的功能相對健全的 Git 的實(shí)現(xiàn),它在 Java 社區(qū)中被廣泛使用。 JGit 項目由 Eclipse 維護(hù),它的主頁在??。
有很多種方式可以讓 JGit 連接你的項目,并依靠它去寫代碼。 最簡單的方式也許就是使用 Maven 。你可以通過在你的 pom.xml 文件里的?<dependencies>
?標(biāo)簽中增加像下面這樣的片段來完成這個整合。
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>3.5.0.201409260305-r</version>
</dependency>
在你讀到這段文字時?version
?很可能已經(jīng)更新了,所以請瀏覽?以獲取最新的倉庫信息。 當(dāng)這一步完成之后, Maven 就會自動獲取并使用你所需要的 JGit 庫。
如果你想自己管理二進(jìn)制的依賴包,那么你可以從??獲得預(yù)構(gòu)建的 JGit 二進(jìn)制文件。 你可以像下面這樣執(zhí)行一個命令來將它們構(gòu)建進(jìn)你的項目。
javac -cp .:org.eclipse.jgit-3.5.0.201409260305-r.jar App.java
JGit 的 API 有兩種基本的層次:底層命令和高層命令。 這個兩個術(shù)語都來自 Git ,并且 JGit 也被按照相同的方式粗略地劃分:高層 API 是一個面向普通用戶級別功能的友好的前端(一系列普通用戶使用 Git 命令行工具時可能用到的東西),底層 API 則直接作用于低級的倉庫對象。
大多數(shù) JGit 會話會以?Repository
?類作為起點(diǎn),你首先要做的事就是創(chuàng)建一個它的實(shí)例。 對于一個基于文件系統(tǒng)的倉庫來說(嗯, JGit 允許其它的存儲模型),用?FileRepositoryBuilder
完成它。
// 創(chuàng)建一個新倉庫
Repository newlyCreatedRepo = FileRepositoryBuilder.create(
new File("/tmp/new_repo/.git"));
newlyCreatedRepo.create();
// 打開一個存在的倉庫
Repository existingRepo = new FileRepositoryBuilder()
.setGitDir(new File("my_repo/.git"))
.build();
無論你的程序是否知道倉庫的確切位置,builder 中的那個流暢的 API 都可以提供給它尋找倉庫所需所有信息。 它可以使用環(huán)境變量 (.readEnvironment()
) ,從工作目錄的某處開始并搜索 (.setWorkTree(…).findGitDir()
) , 或者僅僅只是像上面那樣打開一個已知的?.git
?目錄。
當(dāng)你擁有一個?Repository
?實(shí)例后,你就能對它做各種各樣的事。 下面是一個速覽:
// 獲取引用
Ref master = repo.getRef("master");
// 獲取該引用所指向的對象
ObjectId masterTip = master.getObjectId();
// Rev-parse
ObjectId obj = repo.resolve("HEAD^{tree}");
// 裝載對象原始內(nèi)容
ObjectLoader loader = repo.open(masterTip);
loader.copyTo(System.out);
// 創(chuàng)建分支
RefUpdate createBranch1 = repo.updateRef("refs/heads/branch1");
createBranch1.setNewObjectId(masterTip);
createBranch1.update();
// 刪除分支
RefUpdate deleteBranch1 = repo.updateRef("refs/heads/branch1");
deleteBranch1.setForceUpdate(true);
deleteBranch1.delete();
// 配置
Config cfg = repo.getConfig();
String name = cfg.getString("user", null, "name");
這里完成了一大堆事情,所以我們還是一次理解一段的好。
第一行獲取一個指向?master
?引用的指針。 JGit 自動抓取位于?refs/heads/master
?的?真正的?master 引用,并返回一個允許你獲取該引用的信息的對象。 你可以獲取它的名字 (.getName()
) ,或者一個直接引用的目標(biāo)對象 (.getObjectId()
) ,或者一個指向該引用的符號指針 (.getTarget()
) 。 引用對象也經(jīng)常被用來表示標(biāo)簽的引用和對象,所以你可以詢問某個標(biāo)簽是否被 “削除” 了,或者說它指向一個標(biāo)簽對象的(也許很長的)字符串的最終目標(biāo)。
第二行獲得以?master
?引用的目標(biāo),它返回一個 ObjectId 實(shí)例。 不管是否存在于一個 Git 對象的數(shù)據(jù)庫,ObjectId 都會代表一個對象的 SHA-1 哈希。 第三行與此相似,但是它展示了 JGit 如何處理 rev-parse 語法(要了解更多,請看?分支引用?),你可以傳入任何 Git 了解的對象說明符,然后 JGit 會返回該對象的一個有效的 ObjectId ,或者?null
?。
接下來兩行展示了如何裝載一個對象的原始內(nèi)容。 在這個例子中,我們調(diào)用ObjectLoader.copyTo()
?直接向標(biāo)準(zhǔn)輸出流輸出對象的內(nèi)容,除此之外 ObjectLoader 還帶有讀取對象的類型和長度并將它以字節(jié)數(shù)組返回的方法。 對于一個(?.isLarge()
?返回?true
的)大的對象,你可以調(diào)用?.openStream()
?來獲得一個類似 InputStream 的對象,它可以在沒有一次性將所有數(shù)據(jù)拉到內(nèi)存的前提下讀取對象的原始數(shù)據(jù)。
接下來幾行展現(xiàn)了如何創(chuàng)建一個新的分支。 我們創(chuàng)建一個 RefUpdate 實(shí)例,配置一些參數(shù),然后調(diào)用?.update()
?來確認(rèn)這個更改。 刪除相同分支的代碼就在這行下面。 記住必須先.setForceUpdate(true)
?才能讓它工作,否則調(diào)用?.delete()
?只會返回?REJECTED
?,然后什么都沒有發(fā)生。
最后一個例子展示了如何從 Git 配置文件中獲取?user.name
?的值。 這個 Config 實(shí)例使用我們先前打開的倉庫做本地配置,但是它也會自動地檢測并讀取全局和系統(tǒng)的配置文件。
這只是底層 API 的冰山一角,另外還有許多可以使用的方法和類。 還有一個沒有放在這里說明的,就是 JGit 是用異常機(jī)制來處理錯誤的。 JGit API 有時使用標(biāo)準(zhǔn)的 Java 異常(例如IOException
?),但是它也提供了大量 JGit 自己定義的異常類型(例如NoRemoteRepositoryException
、?CorruptObjectException
?和NoMergeBaseException
)。
底層 API 更加完善,但是有時將它們串起來以實(shí)現(xiàn)普通的目的非常困難,例如將一個文件添加到索引,或者創(chuàng)建一個新的提交。 為了解決這個問題, JGit 提供了一系列高層 API ,使用這些 API 的入口點(diǎn)就是?Git
?類:
Repository repo;
// 構(gòu)建倉庫。。。
Git git = new Git(repo);
Git 類有一系列非常好的?構(gòu)建器?風(fēng)格的高層方法,它可以用來構(gòu)造一些復(fù)雜的行為。 我們來看一個例子——做一件類似?git ls-remote
?的事。
CredentialsProvider cp = new UsernamePasswordCredentialsProvider("username", "p4ssw0rd");
Collection<Ref> remoteRefs = git.lsRemote()
.setCredentialsProvider(cp)
.setRemote("origin")
.setTags(true)
.setHeads(false)
.call();
for (Ref ref : remoteRefs) {
System.out.println(ref.getName() + " -> " + ref.getObjectId().name());
這是一個 Git 類的公共樣式,這個方法返回一個可以讓你串連若干方法調(diào)用來設(shè)置參數(shù)的命令對象,當(dāng)你調(diào)用?.call()
?時它們就會被執(zhí)行。 在這情況下,我們只是請求了?origin
?遠(yuǎn)程的標(biāo)簽,而不是頭部。 還要注意用于驗(yàn)證的?CredentialsProvider
?對象的使用。
在 Git 類中還可以使用許多其它的命令,包括但不限于add
、blame
、commit
、clean
、push
、rebase
、revert
?和?reset
。
這只是 JGit 的全部能力的冰山一角。 如果你對這有興趣并且想深入學(xué)習(xí),在下面可以找到一些信息和靈感。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: