W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
另外一種可以供你使用的是 Libgit2。 Libgit2 是一個(gè) Git 的非依賴性的工具,它致力于為其他程序使用 Git 提供更好的 API。 你可以在??找到它。
首先,讓我們來(lái)看一下 C API 長(zhǎng)啥樣。 這是一個(gè)旋風(fēng)式旅行。
// 打開(kāi)一個(gè)版本庫(kù)
git_repository *repo;
int error = git_repository_open(&repo, "/path/to/repository");
// 逆向引用 HEAD 到一個(gè)提交
git_object *head_commit;
error = git_revparse_single(&head_commit, repo, "HEAD^{commit}");
git_commit *commit = (git_commit*)head_commit;
// 顯示這個(gè)提交的一些詳情
printf("%s", git_commit_message(commit));
const git_signature *author = git_commit_author(commit);
printf("%s <%s>\n", author->name, author->email);
const git_oid *tree_id = git_commit_tree_id(commit);
// 清理現(xiàn)場(chǎng)
git_commit_free(commit);
git_repository_free(repo);
前兩行打開(kāi)一個(gè) Git 版本庫(kù)。 這個(gè)?git_repository
?類型代表了一個(gè)在內(nèi)存中帶有緩存的指向一個(gè)版本庫(kù)的句柄。 這是最簡(jiǎn)單的方法,只是你必須知道一個(gè)版本庫(kù)的工作目錄或者一個(gè)?.git
?文件夾的精確路徑。 另外還有?git_repository_open_ext
?,它包括了帶選項(xiàng)的搜索,git_clone
?及其同類可以用來(lái)做遠(yuǎn)程版本庫(kù)的本地克隆,?git_repository_init
?則可以創(chuàng)建一個(gè)全新的版本庫(kù)。
第二段代碼使用了一種 rev-parse 語(yǔ)法(要了解更多,請(qǐng)看?分支引用?)來(lái)得到 HEAD 真正指向的提交。 返回類型是一個(gè)?git_object
?指針,它指代位于版本庫(kù)里的 Git 對(duì)象數(shù)據(jù)庫(kù)中的某個(gè)東西。git_object
?實(shí)際上是幾種不同的對(duì)象的 “父” 類型,每個(gè) “子” 類型的內(nèi)存布局和git_object
?是一樣的,所以你能安全地把它們轉(zhuǎn)換為正確的類型。 在上面的例子中,git_object_type(commit)
?會(huì)返回?GIT_OBJ_COMMIT
?,所以轉(zhuǎn)換成?git_commit
?指針是安全的。
下一段展示了如何訪問(wèn)一個(gè)提交的詳情。 最后一行使用了?git_oid
?類型,這是 Libgit2 用來(lái)表示一個(gè) SHA-1 哈希的方法。
從這個(gè)例子中,我們可以看到一些模式:
如果你聲明了一個(gè)指針,并在一個(gè) Libgit2 調(diào)用中傳遞一個(gè)引用,那么這個(gè)調(diào)用可能返回一個(gè) int 類型的錯(cuò)誤碼。 值?0
?表示成功,比它小的則是一個(gè)錯(cuò)誤。
如果 Libgit2 為你填入一個(gè)指針,那么你有責(zé)任釋放它。
如果 Libgit2 在一個(gè)調(diào)用中返回一個(gè)?const
?指針,你不需要釋放它,但是當(dāng)它所指向的對(duì)象被釋放時(shí)它將不可用。
最后一點(diǎn)意味著你應(yīng)該不會(huì)在使用 Libgit2 時(shí)編寫(xiě) C 語(yǔ)言程序。 但幸運(yùn)的是,有許多可用的各種語(yǔ)言的綁定,能讓你在特定的語(yǔ)言和環(huán)境中更加容易的操作 Git 版本庫(kù)。 我們來(lái)看一下下面這個(gè)用 Libgit2 的 Ruby 綁定寫(xiě)成的例子,它叫 Rugged,你可以在?找到它。
repo = Rugged::Repository.new('path/to/repository')
commit = repo.head.target
puts commit.message
puts "#{commit.author[:name]} <#{commit.author[:email]}>"
tree = commit.tree
你可以發(fā)現(xiàn),代碼看起來(lái)更加清晰了。 首先, Rugged 使用異常機(jī)制,它可以拋出類似于ConfigError
?或者?ObjectError
?之類的東西來(lái)告知錯(cuò)誤的情況。 其次,不需要明確資源釋放,因?yàn)?Ruby 是支持垃圾回收的。 我們來(lái)看一個(gè)稍微復(fù)雜一點(diǎn)的例子:從頭開(kāi)始制作一個(gè)提交。
blob_id = repo.write("Blob contents", :blob)
index = repo.index
index.read_tree(repo.head.target.tree)
index.add(:path => 'newfile.txt', :oid => blob_id)
sig = {
:email => "bob@example.com",
:name => "Bob User",
:time => Time.now,
}
commit_id = Rugged::Commit.create(repo,
:tree => index.write_tree(repo),
:author => sig,
:committer => sig,
:message => "Add newfile.txt",
:parents => repo.empty? ? [] : [ repo.head.target ].compact,
:update_ref => 'HEAD',
)
commit = repo.lookup(commit_id)
創(chuàng)建一個(gè)新的 blob ,它包含了一個(gè)新文件的內(nèi)容。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: