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阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容