日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Git2.29让Git成功“牵 手”Gerrit

發(fā)布時間:2024/9/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Git2.29让Git成功“牵 手”Gerrit 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

GitHub 和 Gerrit 都是誕生于 2008 年的代碼平臺,兩個平臺各自形成了相互獨立的生態(tài)。GitHub 及其模仿者們成為行業(yè)主流,托管著大多數(shù)開源項目和商業(yè)項目的源代碼,而 Gerrit 也有一眾“粉絲”,像大名鼎鼎的安卓(Android)、OpenStack、Golang等。雖然 GitHub 和 Gerrit 都是 Git 倉庫的托管和研發(fā)協(xié)同平臺,但是二者背后的技術(shù)大相徑庭。采用 GitHub 模式的代碼平臺的后端使用原生 Git(cgit)實現(xiàn),而 Gerrit 則采用 JGit(用 java 重新實現(xiàn) Git 接口)實現(xiàn)。再有兩者理念不同,一種采用分布式協(xié)同,一種是集中式協(xié)同。二者的詳細對比參考下面的表格:

我們可以看出 GitHub 模式和 Gerrit 模式各有優(yōu)劣。那么能否有兩全其美的代碼平臺呢?Git 2.29 讓這成為可能。

1.Git2.29的新功能,讓Git“牽手”Gerrit

Git 2.29.0 于 2020年10月發(fā)布,其中包含了兩個阿里巴巴貢獻的新特性。阿里巴巴貢獻的新特性讓 Git 牽手 Gerrit,讓 GitHub 模式的代碼平臺可以像 Gerrit 一樣工作。

1.1服務(wù)端新鉤子proc-receive

Git 2.29 在服務(wù)端增加了 proc-receive 鉤子。對Git原理熟悉的用戶可能知道 Git 服務(wù)端經(jīng)常使用的兩個鉤子:pre-receive 和 post-receive,在 git 推送時服務(wù)端運行的這兩個鉤子會進行前置檢查(授權(quán)檢查等)和后處理(發(fā)送通知、觸發(fā)構(gòu)建等)。而新引入的 proc-receive 鉤子的執(zhí)行順序,是介于這兩個鉤子之間,用于替代 Git 內(nèi)置功能完成分支(引用)的更新操作。這個新鉤子提供給 Git 代碼平臺更為強大的服務(wù)端定制能力,存在豐富的想象空間。

例如:一個用戶使用如下命令向服務(wù)端推送:

git push origin HEAD:refs/for/master

服務(wù)端如果是 Git 2.29 之前的版本,會直接在服務(wù)端倉庫中創(chuàng)建名為 refs/for/master 的引用。而 Git 2.29 版本引入的 proc-receive 鉤子,會接管 Git 更新引用的操作。proc-receive 鉤子能做什么,完全取決于開發(fā)者的想象:

  • 創(chuàng)建一個代碼評審,并在倉庫中產(chǎn)生名為 refs/pull/123/head 的引用,便于用戶下載相關(guān)代碼。
  • 或者,推送包含的每一個提交都產(chǎn)生一個獨立的代碼評審,就像 Gerrit 那樣。每個評審都產(chǎn)生類似 refs/changes/<num> 的引用。
  • 或者,不在服務(wù)端產(chǎn)生任何引用,而是將用戶新增提交以郵件方式發(fā)到郵件列表,類似 GitGitGadget [1] 那樣。

那么如何能開發(fā)一個 proc-receive 鉤子呢?相比 pre-receive 和 post-receive 鉤子,proc-receive 鉤子實現(xiàn)難度稍微大一些,因為它和 Git 服務(wù)端程序 git-receive-pack 有著復(fù)雜的雙向通訊:服務(wù)端程序調(diào)用鉤子,將 git push 的命令以及 push-options(如果有的話)發(fā)送給鉤子,然后鉤子調(diào)用 API 替代 Git 完成引用的更新。如下圖所示:

1.2客戶端新能力report-status-v2

阿里巴巴在給 Git 社區(qū)貢獻的第一個版本中,只在服務(wù)端引入新的鉤子,并未修改客戶端相關(guān)代碼。為了能讓社區(qū)接受修改,我以實現(xiàn) Gerrit 的類似功能作為賣點向社區(qū)進行“推銷”。Junio(Git 維護者,Google)第一時間承認(rèn)這個貢獻的價值:

And I think it is reasonable to add a new hook that takes over the whole flow in "git receive-pack" to do so.

同時指出疑問:向 Gerrit 推送一個引用A (refs/for/master),Gerrit 創(chuàng)建了另外的引用B (refs/changes/1/123),那么 Gerrit 是如何告訴客戶端正確地更新本地跟蹤分支的?

How do Gerrit folks deal with the "we pushed to the server, so let's pretend to have turned around and fetched from the same server immediately after doing so" client-side hack, by the way?

只有屈指可數(shù)的人才能像 Junio 這樣發(fā)出靈魂的拷問!

于是在后續(xù)的代碼評審中,與 Junio 以及 GitHub 的 Jeff King (Peff) 之間進行了多次交流,代碼迭代了19個版本[2],為 Git 服務(wù)端和客戶端新增了一個能力:report-status-v2。

簡單的說,在老版本的 report-status 能力下,如果客戶端發(fā)送推送命令要求服務(wù)器更新 A 分支(如: refs/for/master),而服務(wù)端轉(zhuǎn)而創(chuàng)建了分支 B(refs/changes/1/123)。這種情況下,服務(wù)端也只能通知客戶端分支A被創(chuàng)建,而非分支B,否則客戶端會報錯:“服務(wù)端沒有按照我的要求去執(zhí)行”。

擴展后的 report-status-v2,服務(wù)端可以報告給客戶端實際修改的分支,可以報告不同的分支初始指向和最新指向,甚至客戶端的一條命令可以對應(yīng)多條分支的更新。支持該能力的客戶端也能正確地將服務(wù)端實際更新的分支顯示出來。

2.云效Codeup是業(yè)界第一個支持git 2.29新功能的代碼平臺

阿里云云效Codeup(https://codeup.aliyun.com)是業(yè)界首個支持 Git 2.29 新功能的代碼平臺。當(dāng)用戶執(zhí)行 git push 命令時,特殊的目標(biāo)分支會觸發(fā)服務(wù)端 proc-receive 鉤子,完成特定功能。

2.1命令行創(chuàng)建代碼評審

在云效Codeup的“新建合并請求”按鈕的下方,有一條低調(diào)的提示,如圖:


參照提示信息的說明,用戶會看到用標(biāo)準(zhǔn)的 Git 命令行就可以直接在倉庫中創(chuàng)建代碼評審。例如用戶執(zhí)行下面命令將當(dāng)前(HEAD)的更改推送到服務(wù)端,向服務(wù)端的 master 分支創(chuàng)建代碼評審: git push origin HEAD:refs/for/master/local/branch

說明:

1.引用表達式的目標(biāo)分支包含特殊的前綴“refs/for/",用于向遠程倉庫特定分支“master”發(fā)起代碼評審。其中的“l(fā)ocal/branch”通常寫做客戶端的本地分支名。多次git push請求,如果是相同用戶、相同的目標(biāo)分支、相同的“l(fā)ocal/branch",則對應(yīng)用同一個pull request。

2.此外Codeup還支持“refs/drafts/"、“refs/for-review/”等特殊前綴。前綴“refs/drafts/”的格式和“refs/for/”類似,也是針對目標(biāo)分支創(chuàng)建或者更新pull request,區(qū)別在于創(chuàng)建的pull request處于草稿狀態(tài),只能發(fā)表評審意見,不能合入。前綴“refs/for-review/”后面跟指定的pull request ID,用于更新指定的pull request。

2.2AGit-Flow工作流

使用上面介紹的命令行創(chuàng)建代碼評審,可以實現(xiàn)無需倉庫派生、無需特性分支、無需特殊授權(quán)設(shè)置,完成代碼評審的創(chuàng)建和合入。阿里巴巴代碼平臺上支持的這種代碼協(xié)同模式,我們稱之為AGit-Flow。

圖中的兩個角色,一個是開發(fā)者,另外一個是評審者。

開發(fā)者通過如下操作,創(chuàng)建和更新pullrequest:

1.開發(fā)者克隆倉庫。

2.本地倉庫內(nèi)開發(fā),創(chuàng)建提交。

3.工作區(qū)中執(zhí)行命令,推送本地提交到服務(wù)器。

4.服務(wù)器自動創(chuàng)建新的代碼評審(例如:pullrequest#123)。

5.開發(fā)者根據(jù)評審意見,在本地工作區(qū)繼續(xù)開發(fā),新增或修改提交。

6.工作區(qū)中再次執(zhí)行g(shù)itpr命令,推送本地提交到服務(wù)器。

7.服務(wù)器發(fā)現(xiàn)目標(biāo)分支上已經(jīng)存在來自同一用戶、同一本地分支的pullrequest,因此用戶此次推送沒有創(chuàng)建新的pullrequest,而是更新已經(jīng)存在的pullrequest。

代碼評審者,不但可以給出評審意見,也可以直接發(fā)起對評審代碼的修改,更新pullrequest:

8.代碼評審者執(zhí)行g(shù)itdownload123下載編號為123的pullrequest到本地倉庫。

9.代碼評審者本地修改代碼后,執(zhí)行g(shù)itpr--change123命令,將本地修改推送到服務(wù)端。

10.服務(wù)端接收到代碼評審者的特殊gitpush命令,更新之前由開發(fā)者創(chuàng)建的pullrequest。

11.項目管理者通過點擊pullrequest評審界面的合并按鈕,將pullrequest合入master分支。master分支被更新,同時關(guān)閉pullrequest。

2.3GitHub是否會引入Git2.29的新功能?

GitHub 引入 Git 2.29 新功能沒有那么快,原因是 GitHub 的架構(gòu)是分布式三副本架構(gòu),使用的是定制版本的 Git,不能通過升級到 2.29 來支持 proc-receive 鉤子,需要另行開發(fā)。

當(dāng) proc-receive 特性在 Git 社區(qū)評審過程中,我邀請了 GitHub 的 Jeff King 參與代碼評審。我在郵件中提到了如何在分布式多副本架構(gòu)中引入 proc-receive 鉤子的建議,因為我知道 GitHub 的分布式三副本和阿里巴巴的代碼平臺的分布式架構(gòu)都面臨 proc-receive 鉤子可能被多次執(zhí)行的問題。我們采用的路徑是對 Git 協(xié)議進行擴展以實現(xiàn) proc-receive 鉤子執(zhí)行的冪等性。Jeff King 在回復(fù)中介紹了 GitHub 的后端實現(xiàn):

We do run receive-pack on each replica backend. We have a hacky patch for a config option that tells receive-pack to just skip the actual ref-transaction, leaving it up to the proxy layer to do. I've been pushing for us to actually abandon receive-pack entirely, since most of its heavy lifting can be done by sub-programs (for-each-ref for the advertisement, index-pack to receive the pack, and update-ref to update refs). But it's a non-trivial change, and the benefits are only moderate, so it hasn't quite been worth the effort yet.

就是說 GitHub 的分布式多副本服務(wù)器上的 git-receive-pack 是修改版本,并不執(zhí)行引用更新的操作,而是由代理層執(zhí)行,主要目的是為了避免 pre-receive、post-receive 等鉤子的多次執(zhí)行。阿里巴巴的多副本方案和 GitHub 多副本實現(xiàn)不同,我們的實現(xiàn)可以復(fù)用大部分 git-receive-pack 的功能。相關(guān)討論如下:

Thanks to Peff for providing technical details of the architecture. I understand that "receive-pack" of GitHub backend is not involved in ?references update (executing the commands), so the "proc-receive" hook won't be turned on for GitHub's architecture. While in our ?architecture (inspired by "spokes" of GitHub), the proxy will deliver > not only packfile, but also commands to all three replicas. The proxy will execute "receive-pack" on the replica with a special argument, so the proxy can talk with "receive-pack" with an extended protocol. After running pre-receive hook and release the packfile from quarantine, the replica will stop and wait for the proxy to coordinate. After creating a distributed lock, the proxy will tell all? the replicas continue to update the references. One problem we met is the proc-receive and the post-receive hook must be executed once. We > can make the execution of the hooks idempotent, or let only one of the > replica run the hook. We choose the latter. OK, that makes more sense. We solve that by not updating the refs at all via receive-pack (which gives us flexibility to run our own hooks separately on just one replica, etc).
OK, that makes more sense. We solve that by not updating the refs at all via receive-pack (which gives us flexibility to run our own hooks separately on just one replica, etc).

2.4對于Gerrit會有什么影響么?

Gerrit 擁有兩個核心特性,一個是集中式的工作流,一個是逐提交評審。集中式工作流可以通過 Git 2.29 的新功能在 GitHub 生態(tài)中推廣,而 Gerrit 獨特的逐提交評審界面依舊具有強大的生命力。
Git 2.29 版本包含的 report-status-v2 特性,可以為 Gerrit 用戶帶來新的體驗。可以預(yù)見 Gerrit 會在服務(wù)端增加 report-status-v2 相關(guān)實現(xiàn)以便更好地適配 Git 新客戶端。

3.用git-repo擴展Git命令集

Gerrit 生態(tài)包含多款客戶端工具,例如:Google 為安卓項目開發(fā)了名為 repo 的客戶端工具實現(xiàn)多倉庫管理;OpenStack 社區(qū)開發(fā)了名為 git-review 的工具,以便簡化 Gerrit 工作流的命令行操作。

我們也為阿里巴巴的 AGit-Flow 工作流設(shè)計了一款名為 git-repo 的客戶端工具,這款工具既能像 OpenStack 社區(qū)的相關(guān)工具那樣對單倉庫執(zhí)行,也能像 Android 社區(qū)的 repo 那樣實現(xiàn)多倉庫項目的協(xié)同。

我們將git-repo開源,倉庫地址:https://github.com/alibaba/git-repo-go

關(guān)于git-repo的安裝和使用,訪問網(wǎng)址:https://git-repo.info

git-repo 除了可以適配阿里巴巴的代碼平臺(如:云效Codeup)、Gerrit 之外,還可以通過擴展支持其他實現(xiàn)了 Git 2.29 新特性的代碼平臺,詳見 git-repo 相關(guān)文檔。

未來已來,全新的Git體驗,訪問云效Codeup。

[1]:https://github.com/gitgitgadget/gitgitgadget

[2]:https://public-inbox.org/git/20200827154551.5966-1-worldhello.net@gmail.com/

總結(jié)

以上是生活随笔為你收集整理的Git2.29让Git成功“牵 手”Gerrit的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。