git與phabricator

本文摘錄自本人的《Git聊天入門》

arc 為何物

  • arc 全稱是 arcanist,百度給出的中文翻譯是:巧匠。
  • arc 是Facebook的Phabricator系統中用戶端的命令行工具,配合pha提交變更評審的。
  • arc 的安裝還有點折騰,要先在本機安裝PHP,和一個php的工具集:libphutil
    • windows的安裝后,目錄下包括下面3個主要部件:
    Phabricator/--arc/--arcanist
                |     |-libphutil
                |-xampplite-win32-1.7.3
    
      + arcantist是arc的主程序:https://github.com/phacility/arcanist.git
      + libphutil是php的工具集:https://github.com/phacility/libphutil.git
      + xampplite是apache+php+mysql+perl的一個打包,160+M,要知道phabricator整個才180+M。
    
  • arc 包含很多子命令,
    • arc help:列出來子命令看看
    • arc diff:調用svn diffgit diff生成差異并發送給phabricator生成評審單
    • arc list:列出當前peding的revision —— revision要說明一下:pha生產的每個評審單都對應一個revision,可以理解為svn/git的一次提交,但又不在用戶的svn/git上體現,可以理解為pha上也駐留這一個svn/git,來存儲評審單信息,每單對應一個revision。
    • arc patch:將pha上的revision變更patch到本地工作拷貝上
    • arc amend:更新git commit的message,即:可以把pha上某個revision的message應用到本地git的某個commit上
    • arc commit:svn專用,pha上評審完畢后,將本地的變更做svn commit
    • arc land:git專用,pha上評審完畢后,將本地分支做git push,所以需要有 origin
    • arc lint:靜態代碼分析,不要以為arc只是生成評審單的,它還內嵌了一堆的lint工具,python的、java的、js的……五花八門,在Phabricator\arc\arcanist\src\lint\linter\__tests__這個目錄下列出了這些lint工具
    • arc unit:執行單元測試,這個就需要用戶自己來指定單元測試工具了
    • arc close-revision:使用arc關閉某個revision,而不必上pha上鼠標點點點啦
    • …… 還有n多,不一一列舉了,頭暈
  • arc 的 configuration
    • 和git類似,git有git config --[global/system/local] xxx ...,arc也有arc set-config --[user/local] xxx ...
    • 和git類似,git查看config有git config -l,arc也有arc get-config

arc的安裝和配置

Windows下的安裝

Ubuntu下的安裝

  • 安裝
    • sudo apt-get install php5 php5-curl
    • cd somewhere //arc的安裝目錄
    • git clone https://github.com/phacility/libphutil.git
    • git clone https://github.com/phacility/arcanist.git
    • sudo ln -s arcanist/bin/arc /usr/local/bin/arc
    • vi ~/.bashrc
      • source $somewhere/arcanist/resources/shell/bash-completion
  • 配置
    • arc set-config $pha-server //eg: arc set-config http://pha.etz.com.cn
    • arc install-certificate
      • 到 $pha-server 上查找幫助,找到tocken,填到這里
      • 注意proxy的屏蔽

arc diff 初步

  • SVN中,arc diff會把未提交的本地工作拷貝中的變更生成評審單,執行arc diff之前不需要也不能執行svn commit,最終評審完,用arc commit來代替svn commit
  • git中則完全不一樣,arc diff <startCommit>之前需要首先git add&git commit如果本地工作拷貝中有變更,arc diff會自動替你add和commit,因為arc diff是把git中兩個commit之間(即:一個range)的變更提交到pha上生成評審單,所以問題來了:兩個commit節點是如何指定的?
    • 兩個commit節點是:startCommit 和 HEAD
    • startCommit如果缺失,則默認使用 git merge-base origin/master HEAD
      • 這又是個啥東東?git help merge-base,意思是找到 origin/master 和 HEAD 之間的最近祖先節點。
      • git help merge-base中有幾個例子,其中一個是:
           o---o---o---B
          /
      ---o---1---o---o---o---A
      
        * `git merge-base A B `將返回節點1,好好體會一下,呵呵。
      
      • 所以為了不出亂子,最好自己指定 startCommit
  • arc diff需要填寫一些信息,所以執行過程中會跳入到一個編輯器中,windows版的arc會打開一個簡陋的窗口,ubuntu版的arc就直接打開默認的編輯器(如vi)了。需要填寫的信息有:
    • Test Plan - 必填,詳細說明你的測試計劃;
    • Reviewers - 必填,審查人的賬戶,多個使用","隔開;
      • 在ubuntu下,用vi編輯此信息時,不會自動不全人名,則需要到phabricator網站上的搜索窗口,找到需要的人,把TA的賬號寫在此處
    • Subscribers - 非必填訂閱人,多個使用","隔開。

實戰一下:

  • 創建一個temp的git repo
10036143@A20939270 MINGW32 /f/temp (master)
$ git log
 *  75c616b | 2016-06-08 15:55:19 +0800 |  wkevin  hah
 *  7584e84 | 2016-06-08 15:55:01 +0800 |  wkevin  create
  • arc diff
    • 會提示錯誤,沒有指定 origin/master,因為默認startComiit是git merge-base origin/master HEAD
  • arc diff 7584
    • 可以創建評審單的,因為是拿 HEAD(即75c6)與7584比較
    • git show HEAD 可以查看 HEAD 指向哪個節點
  • arc diff 7584 --preview
    • 可以在pha上創建評審單,但跳過指定評委等步驟,單子已經在pha上有了,可以先看看,后續在pha上慢慢指定評委等
    • 這是專門給處女座準備的啊
  • 有一點需要說明:
    • arc diff會根據工作拷貝的相關信息(比如 path, branch name, local commit hashes, and local tree hashes)來自動創建和關聯一個pha上的revision,這讓一些掌控欲比較強的人可能有些惱火,可以手工指定
      • arc diff --create <startCommit>:在pha上創建一個新的revision
      • arc diff --update Dxxxx <startCommit>:在pha上一個已有的revision(編號Dxxxx)上做增量

arc diff 為什么把我已有的commit log修改了

在上面的步驟中有一個奇怪的地方:執行完arc diff xxxx后,原有的HEAD節點被arc重新創建的一個節點所替代

  • 執行arc diff 7584后,75c6被替代為了26c0
$ git l
 *  26c0efc | 2016-06-08 15:55:19 +0800 |  wkevin  hah
 *  7584e84 | 2016-06-08 15:55:01 +0800 |  wkevin  create
  • 再次執行arc diff 7584后,26c0被替代為了e6db
$ git l
 *  e6db93c | 2016-06-08 15:55:19 +0800 |  wkevin  hah
 *  7584e84 | 2016-06-08 15:55:01 +0800 |  wkevin  create
  • 再次執行arc diff 7584后,e6db被替代為了7c29
$ git l
 *  7c29204 | 2016-06-08 15:55:19 +0800 |  wkevin  hah
 *  7584e84 | 2016-06-08 15:55:01 +0800 |  wkevin  create
  • 但其實75c6、26c0、e6db都還是存在的,git show可以看到
$ git show 75c6
commit 75c616b3a6de15e7004c231486a91e338ae023a6
Author: wkevin <wkevin27@gmail.com>
Date:   Wed Jun 8 15:55:19 2016 +0800

    hah

事情變得很蹊蹺,arc為什么要新建一個commit呢?

下面再來驗證一下:如果本地有modified(待add)或stagging(待commit)文件的話,arc diff是不是也會新建一個commit呢?

  • 當前狀態
$ git l
 *  1cce5be | 2016-06-08 16:05:27 +0800 |  wkevin  neww
 *  7c29204 | 2016-06-08 15:55:19 +0800 |  wkevin  hah
 *  7584e84 | 2016-06-08 15:55:01 +0800 |  wkevin  create
  • 做一些有本地修改,但不 git commit -a
  • arc diff HEAD^,會首先把未提交的變更進行提交,并且更新(amend)當前commit的message,然后向已有的revision進行update
$ arc diff HEAD^
You have uncommitted changes in this working copy.
  Working copy: F:\temp\
  Unstaged changes in working copy:
    README.md
    Do you want to amend this change to the current commit? [y/N] y
Linting...
No lint engine configured for this project.
Running unit tests...
No unit test engine is configured for this project.
SKIP STAGING Unable to determine repository for this change.
Updated an existing Differential revision:
        Revision URI: http://pha.zte.com.cn/D30449
Included changes:
  M       README.md
  • 1cce5be 又被 20ae4c5 替代了,而不是在 1cce5be 的基礎上新建一個commit
$ git l
 *  20ae4c5 | 2016-06-08 16:05:27 +0800 |  wkevin  neww
 *  7c29204 | 2016-06-08 15:55:19 +0800 |  wkevin  hah
 *  7584e84 | 2016-06-08 15:55:01 +0800 |  wkevin  create

為了解開這個謎團,我們來跟蹤一下arc diff的操作

arc diff --trace <startCommit>

摘錄一部分打印:

>>> [1] <http> http://pha.zte.com.cn/api/user.whoami
>>> [2] <exec> $ git diff --no-ext-diff --no-textconv --raw 'HEAD' --
>>> [3] <exec> $ git ls-files --others --exclude-standard
>>> [4] <exec> $ git diff-files --name-only
>>> [6] <exec> $ git rev-parse 'HEAD'
>>> [7] <exec> $ git merge-base 'f8c1' 'd6efce6e8804ecb027762e0151ed071bc7d63b6d'
>>> [8] <exec> $ git log --first-parent --format=medium 'f8c101daaf75121dd4f1f1380b4dc5c1ed85cea0'..'d6efce6e8804ecb027762e0151ed071bc7d63b6d'

首先到phabricator服務器上驗證tocken,并根據 startCommit 做出一些判斷

>>> [16] <event> diff.willBuildMessage <listeners = 0>
>>> [17] <conduit> differential.getcommitmessage() <bytes = 295>
>>> [18] <http> http://pha.zte.com.cn/api/differential.getcommitmessage
>>> [19] <exec> $ git symbolic-ref --quiet HEAD
>>> [20] <exec> $ which 'editor'
>>> [21] <exec> $ editor  '/tmp/edit.cjol8q3bi1sg0kwk/new-commit'

然后到phabricator服務器上創建一個單,并根據pha的請求,打開editor,編輯評審單的信息

>>> [22] <exec> $ git commit --amend --allow-empty -F '/tmp/8qihi3x4l2ww4o8w/10039-Vbjrxm'

關鍵是這里了,無條件的更新了當前 HEAD 節點的 message。

其實 git commit --amend 的官方help中是這樣解釋的: Replace the tip of the current branch by creating a new commit.

這樣arc diff <startCommit>步驟就明朗了:

  1. 提示用戶填寫評審單信息(Test Plans、Reviewers、Subscribers……),然后使用這些信息 git commit --amend 到當前分支的 HEAD 節點
  2. 新的節點(即:新的HEAD) 成為 endCommit
  3. 再拿 HEAD(即endCommit)與 startCommit 執行 git diff,輸出的內容提交到 pha

arc 為什么要這么做?為什么要“玷污”我的現有節點?如果這個節點是其他分支的基礎節點怎么辦?…… —— 這個事情可以這么看:arc diff只是新建了一個commit,用來存儲評審單的相關信息,并且把當前分支的HEAD指向了新建的commit,想好了這一點,事情其實很好辦,下一節我們來規避它。

如何避免arc diff玷污現有節點

創建專用于評審的分支

  • git branch review
  • git checkout review
  • arc diff <xxx>arc diff --preview <xxx> //創建評審單或預審單(到pha網站上進行下一步的操作,可用于ubuntu下不能自動補全人名的環境)
  • git checkout master
  • git branch -D review //評審單一旦創建,review分支就沒有存在的必要性了

如何創建只包含部分文件的評審單

可能只希望評審方案文件(假設: design.md),但commit中包含相關的圖片、svg、等文件,不需要提交到pha,如下處理:

  • git branch review <oneOldCommit> //從 design.md 創建或修改前的節點創建一個分支
  • git checkout review
  • git checkout master design.md //將master分支上的 design.md check 到 review 分支
  • git commit -am "review for design.md"
  • arc diff HEAD^arc diff --preview HEAD^
  • git checkout master
  • git branch -D review
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容