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