<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## Libgit2 另外一種可以供你使用的是 Libgit2。 Libgit2 是一個 Git 的非依賴性的工具,它致力于為其他程序使用 Git 提供更好的 API。 你可以在?[*http://libgit2.github.com*](http://libgit2.github.com/)?找到它。 首先,讓我們來看一下 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); // 清理現場 git_commit_free(commit); git_repository_free(repo); ~~~ 前兩行打開一個 Git 版本庫。 這個?`git_repository`?類型代表了一個在內存中帶有緩存的指向一個版本庫的句柄。 這是最簡單的方法,只是你必須知道一個版本庫的工作目錄或者一個?`.git`?文件夾的精確路徑。 另外還有?`git_repository_open_ext`?,它包括了帶選項的搜索,`git_clone`?及其同類可以用來做遠程版本庫的本地克隆,?`git_repository_init`?則可以創建一個全新的版本庫。 第二段代碼使用了一種 rev-parse 語法(要了解更多,請看?[分支引用](http://git-scm.com/book/zh/v2/1-git-tools/_branch_references)?)來得到 HEAD 真正指向的提交。 返回類型是一個?`git_object`?指針,它指代位于版本庫里的 Git 對象數據庫中的某個東西。`git_object`?實際上是幾種不同的對象的 “父” 類型,每個 “子” 類型的內存布局和`git_object`?是一樣的,所以你能安全地把它們轉換為正確的類型。 在上面的例子中,`git_object_type(commit)`?會返回?`GIT_OBJ_COMMIT`?,所以轉換成?`git_commit`?指針是安全的。 下一段展示了如何訪問一個提交的詳情。 最后一行使用了?`git_oid`?類型,這是 Libgit2 用來表示一個 SHA-1 哈希的方法。 從這個例子中,我們可以看到一些模式: * 如果你聲明了一個指針,并在一個 Libgit2 調用中傳遞一個引用,那么這個調用可能返回一個 int 類型的錯誤碼。 值?`0`?表示成功,比它小的則是一個錯誤。 * 如果 Libgit2 為你填入一個指針,那么你有責任釋放它。 * 如果 Libgit2 在一個調用中返回一個?`const`?指針,你不需要釋放它,但是當它所指向的對象被釋放時它將不可用。 * 用 C 來寫有點蛋疼。 最后一點意味著你應該不會在使用 Libgit2 時編寫 C 語言程序。 但幸運的是,有許多可用的各種語言的綁定,能讓你在特定的語言和環境中更加容易的操作 Git 版本庫。 我們來看一下下面這個用 Libgit2 的 Ruby 綁定寫成的例子,它叫 Rugged,你可以在[*https://github.com/libgit2/rugged*](https://github.com/libgit2/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 ~~~ 你可以發現,代碼看起來更加清晰了。 首先, 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) ~~~ [![](image/561a25142a2cd.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-1) 創建一個新的 blob ,它包含了一個新文件的內容。 [![](image/561a250d39b5c.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-2) 將 HEAD 提交樹填入索引,并在路徑?`newfile.txt`?增加新文件。 [![](image/561a250a858f0.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-3) 這就在 ODB 中創建了一個新的樹,并在一個新的提交中使用它。 [![](image/561a24fed1af7.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-4) 我們在 author 欄和 committer 欄使用相同的簽名。 [![](image/561a24fdc1b9c.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-5) 提交的信息。 [![](image/561a24fcb8e13.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-6) 當創建一個提交時,你必須指定這個新提交的父提交。 這里使用了 HEAD 的末尾作為單一的父提交。 [![](image/561a24fb4af80.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-7) 在做一個提交的過程中, Rugged (和 Libgit2 )能在需要時更新引用。 [![](image/561a24f0071f6.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO1-8) 返回值是一個新提交對象的 SHA-1 哈希,你可以用它來獲得一個?`Commit`?對象。 Ruby 的代碼很好很簡潔,另一方面因為 Libgit2 做了大量工作,所以代碼運行起來其實速度也不賴。 如果你不是一個 Ruby 程序員,我們在?[其它綁定](http://git-scm.com/book/zh/v2/ch00/_libgit2_bindings)?有提到其它的一些綁定。 ### [高級功能](http://git-scm.com/book/zh/v2/%E5%B0%86-Git-%E5%B5%8C%E5%85%A5%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8-Libgit2#高級功能) Libgit2 有幾個超過核心 Git 的能力。 例如它的可定制性:Libgit2 允許你為一些不同類型的操作自定義的“后端”,讓你得以使用與原生 Git 不同的方式存儲東西。 Libgit2 允許為自定義后端指定配置、引用的存儲以及對象數據庫, 我們來看一下它究竟是怎么工作的。 下面的例子借用自 Libgit2 團隊提供的后端樣本集 (可以在[*https://github.com/libgit2/libgit2-backends*](https://github.com/libgit2/libgit2-backends)?上找到)。 一個對象數據庫的自定義后端是這樣建立的: ~~~ git_odb *odb; int error = git_odb_new(&odb); git_odb_backend *my_backend; error = git_odb_backend_mine(&my_backend, /*…*/); error = git_odb_add_backend(odb, my_backend, 1); git_repository *repo; error = git_repository_open(&repo, "some-path"); error = git_repository_set_odb(odb); ~~~ *(注意:這個錯誤被捕獲了,但是沒有被處理。我們希望你的代碼比我們的更好。)* [![](image/561a24ee65d8b.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO2-1) 初始化一個空的對象數據庫( ODB ) “前端”,它將被作為一個用來做真正的工作的 “后端” 的容器。 [![](image/561a24e791845.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO2-2) 初始化一個自定義 ODB 后端。 [![](image/561a24e59cad8.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO2-3) 為這個前端增加一個后端。 [![](image/561a24e425699.png)](http://git-scm.com/book/zh/v2/ch00/co___git________CO2-4) 打開一個版本庫,并讓它使用我們的 ODB 來尋找對象。 但是?`git_odb_backend_mine`?是個什么東西呢? 嗯,那是一個你自己的 ODB 實現的構造器,并且你能在那里做任何你想做的事,前提是你能正確地填寫?`git_odb_backend`?結構。 它看起來*應該*是這樣的: ~~~ typedef struct { git_odb_backend parent; // 其它的一些東西 void *custom_context; } my_backend_struct; int git_odb_backend_mine(git_odb_backend **backend_out, /*…*/) { my_backend_struct *backend; backend = calloc(1, sizeof (my_backend_struct)); backend->custom_context = …; backend->parent.read = &my_backend__read; backend->parent.read_prefix = &my_backend__read_prefix; backend->parent.read_header = &my_backend__read_header; // …… *backend_out = (git_odb_backend *) backend; return GIT_SUCCESS; } ~~~ `my_backend_struct`?的第一個成員必須是一個?`git_odb_backend`?結構,這是一個微妙的限制:這樣就能確保內存布局是 Libgit2 的代碼所期望的樣子。 其余都是隨意的,這個結構的大小可以隨心所欲。 這個初始化函數為該結構分配內存,設置自定義的上下文,然后填寫它支持的?`parent`?結構的成員。 閱讀 Libgit2 的?`include/git2/sys/odb_backend.h`?源碼以了解全部調用簽名,你特定的使用環境會幫你決定使用哪一種調用簽名。 ### [其它綁定](http://git-scm.com/book/zh/v2/%E5%B0%86-Git-%E5%B5%8C%E5%85%A5%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8-Libgit2#其它綁定) Libgit2 有很多種語言的綁定。 在這篇文章中,我們展現了一個使用了幾個更加完整的綁定包的小例子,這些庫存在于許多種語言中,包括 C++、Go、Node.js、Erlang 以及 JVM ,它們的成熟度各不相同。 官方的綁定集合可以通過瀏覽這個版本庫得到:https://github.com/libgit2[] 。 我們寫的代碼將返回當前 HEAD 指向的提交的提交信息(就像?`git log -1`?那樣)。 LibGit2Sharp 如果你在編寫一個 .NET 或者 Mono 應用,那么 LibGit2Sharp ([*https://github.com/libgit2/libgit2sharp*](https://github.com/libgit2/libgit2sharp)) 就是你所需要的。 這個綁定是用 C# 寫成的,并且已經采取許多措施來用令人感到自然的 CLR API 包裝原始的 Libgit2 的調用。 我們的例子看起來就像這樣: ~~~ new Repository(@"C:\path\to\repo").Head.Tip.Message; ~~~ 對于 Windows 桌面應用,一個叫做 NuGet 的包會讓你快速上手。 objective-git 如果你的應用運行在一個 Apple 平臺上,你很有可能使用 Objective-C 作為實現語言。 Objective-Git ([*https://github.com/libgit2/objective-git*](https://github.com/libgit2/objective-git)) 是這個環境下的 Libgit2 綁定。 一個例子看起來類似這樣: ~~~ GTRepository *repo = [[GTRepository alloc] initWithURL:[NSURL fileURLWithPath: @"/path/to/repo"] error:NULL]; NSString *msg = [[[repo headReferenceWithError:NULL] resolvedTarget] message]; ~~~ Objective-git 與 Swift 完美兼容,所以你把 Objective-C 落在一邊的時候不用恐懼。 pygit2 Python 的 Libgit2 綁定叫做 Pygit2 ,你可以在?[*http://www.pygit2.org/*](http://www.pygit2.org/)?找到它。 我們的示例程序: ~~~ pygit2.Repository("/path/to/repo") # 打開版本庫 .head # get the current branch .peel(pygit2.Commit) # walk down to the commit .message # read the message ~~~ ### [擴展閱讀](http://git-scm.com/book/zh/v2/%E5%B0%86-Git-%E5%B5%8C%E5%85%A5%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8-Libgit2#擴展閱讀) 當然,完全闡述 Libgit2 的能力已超出本書范圍。 如果你想了解更多關于 Libgit2 的信息,可以瀏覽它的 API 文檔:?[*https://libgit2.github.com/libgit2*](https://libgit2.github.com/libgit2), 以及一系列的指南:[*https://libgit2.github.com/docs*](https://libgit2.github.com/docs). 對于其它的綁定,檢查附帶的 README 和測試文件,那里通常有簡易教程,以及指向拓展閱讀的鏈接。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看