云效代码管理的AGit-Flow模式,支持使用git pr
来通过命令行直接创建代码评审,解决了创建评审的效率问题。使用该模式需要开发者在本地安装git-repo
工具,并执行指定的命令。另一方面,不少开发者也会关注是否可以针对提交的代码进行审核,通过审核的代码才可以被推送进目标分支。那么有没有这样一种方式,在不需要安装任何工具的情况下,执行git push
就可以自动创建评审,并且能够支持对提交进行评审?使用推送评审模式,可以实现这一目标。
推送评审模式及其优势
推送评审模式,是Codeup新推出的一种代码协同方式,可以为用户带来全新、高效的代码评审体验:
从开发者的角度,发起代码评审不再需要创建新分支,也不必在开发完成后切换至浏览器来创建代码评审,直接执行
git push
即可一键发起评审。从管理者的角度,可以设置让开发人员向仓库
push
代码时,不再直接更新分支的代码,而是自动创建代码评审,通过评审的方式,保障代码质量。
推送评审模式与现有分支模式对比:
分支开发模式 | 推送评审模式 | |
提交代码 | 在特性分支中提交 | 直接在主干上提交 |
发起代码评审 | Codeup网页端操作 | 执行 |
更新代码评审 | 更新特性分支 | 继续执行 |
贡献代码所需权限 | 开发者及以上角色 | 浏览者及以上权限 |
代码质量 | 仅保护分支受管控 | 所有分支的 push 均受管控 |
在代码库设置中开启推送评审模式后,具有以下优势:
向仓库贡献代码,发起代码评审,不再需要创建新的分支,直接在主干上进行修改并提交即可,避免了冗余的分支管理成本。
git push
不再直接推送分支内容,而是创建/更新代码评审。如果代码需要修补,提交后继续执行
git push
,已发起的评审会自动更新。向仓库贡献代码不再需要授予开发者权限,拥有仓库的浏览者权限即可贡献代码,而且贡献的代码需要经过评审才能正式合入代码库。因此可以将直接写库的权限最小化到少数管理者手中,而大部分开发者仅需要读权限即可,降低了代码库被意外修改的风险。
支持指定
push option
来控制具体的推送行为,见 使用推送评审模式进行协作 一节。
开启方式
在
中,可以看到推送评审模式的开关,单击此开关即可开启/关闭推送评审模式的功能:开启推送评审模式后,会改变git push
的行为,请先知悉并理解后再开启推送评审模式:
开启推送评审模式后,执行
git push
不再直接更新远端的代码(即便拥有仓库的开发者权限),而是自动创建/更新代码评审。仓库的浏览者,可以通过
git push
发起评审,但请放心此时代码还未合入分支,需要根据分支评审和合并要求通过后才可手动合入。由于
git push
并不直接更新代码而是创建评审,因此不会触发推送事件的webhook。用户可以在Codeup网页端以评审的方式新建,编辑或删除文件。
使用推送评审模式进行协作
下面,用几个实际的例子,说明如何使用推送评审模式进行开发协作。
自动创建评审
假设现在接到了一个开发任务,需要开发一个新的特性,使用传统的分支模式,需要检出一个分支,并在分支上进行开发,推送分支后再发起特性分支至主干的评审。在使用推送评审模式后,这个过程被简化为只需要两步:
在主干上进行开发。
git push
。
在示例仓库的master分支上开发,并创建了一个提交27e76f58
。
$ git log
commit 27e76f582ca7207a695dd8762b66ef443adcc572 (HEAD -> master)
Author: Codeup User <codeup.user@example.com>
Date: Tue Oct 11 10:16:18 2022 +0800
feat: new feature
Signed-off-by: Codeup User <codeup.user@example.com>
commit 44094ec92eb122deab5a0367552bd081540c4353 (origin/master, origin/HEAD)
Author: Codeup User <codeup.user@example.com>
Date: Tue Oct 11 10:09:39 2022 +0800
Initial commit
然后,将改动推送至远端,执行git push
:
$ git push
枚举对象中: 4, 完成.
对象计数中: 100% (4/4), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 310 字节 | 310.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
remote: +-----------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-----------------------------------------------------------------------------------+
remote: | Merge request #31620 has been created, please visit: |
remote: | https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31620 |
remote: +-----------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
* [new reference] master -> refs/merge-requests/31620/head
可以看到,开启了推送评审模式后,git push
没有直接更新远端的代码,而是创建了一个代码评审,ID 是31620
。此代码评审的源为本地最新的提交,目标则是当前的分支。可以通过代码评审的详情来确认:
通过这种方式,不再需要创建特性分支,也不必切换至浏览器创建评审,极大简化了创建代码评审的步骤。同时,git push
不再直接更新代码,而是必须经过评审后才能合入,保障代码质量。
自动更新评审
在代码评审的过程中,往往需要根据评审者的意见,多次反复修改代码,才能最终达到代码的准入标准。那么,在修改了代码后,相应的代码评审要如何更新呢?这可以通过再次执行git push
来完成。下面来看看实际的例子。
在27e76f58
的基础上,根据评审意见修改了一些代码,并增加了一个提交e00db452
。
$ git log
commit e00db4522f2d6ca5b42377ca76c7b3a7e12db8a5 (HEAD -> master)
Author: Codeup User <codeup.user@example.com>
Date: Tue Oct 11 11:09:42 2022 +0800
feat: fix comment
Signed-off-by: Codeup User <codeup.user@example.com>
commit 27e76f582ca7207a695dd8762b66ef443adcc572
Author: Codeup User <codeup.user@example.com>
Date: Tue Oct 11 10:16:18 2022 +0800
feat: new feature
Signed-off-by: Codeup User <codeup.user@example.com>
commit 44094ec92eb122deab5a0367552bd081540c4353 (origin/master, origin/HEAD)
Author: Codeup User <codeup.user@example.com>
Date: Tue Oct 11 10:09:39 2022 +0800
Initial commit
然后,再次执行git push
。
$ git push
枚举对象中: 4, 完成.
对象计数中: 100% (4/4), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 340 字节 | 340.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
remote: +-----------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-----------------------------------------------------------------------------------+
remote: | Merge request #31620 has been updated, please visit: |
remote: | https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31620 |
remote: +-----------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
27e76f582c..e00db4522f master -> refs/merge-requests/31620/head
提示信息中可以看出,这次推送更新了 ID为31620
的代码评审。查看评审详情,看到代码评审的源版本已经变为了e00db4522
,并且提交历史也变为了2。
如果代码仍然需要修改,重复以上流程即可。
创建新的评审
重复执行git push
命令,会自动更新已经存在的评审。如果并不想更新评审,而是想要创建一个新的评审,那要如何操作呢?这可以通过在 push 命令中添加push option
来实现。具体来说,执行 git push -o review=new
,就可以创建新的代码评审。
在本地改动一些代码,再次执行git push -o review=new
,成功创建了 ID 为31626的代码评审。
$ git push -o review=new
枚举对象中: 4, 完成.
对象计数中: 100% (4/4), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 361 字节 | 361.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
remote: +-----------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-----------------------------------------------------------------------------------+
remote: | Merge request #31626 has been created, please visit: |
remote: | https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31626 |
remote: +-----------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
* [new reference] master -> refs/merge-requests/31626/head
需要注意的是,如果推送时已经存在源与目标完全相同的评审,那么将无法创建新的评审。
$ git push -o review=new
总共 0(差异 0),复用 0(差异 0),包复用 0
remote: +-----------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-----------------------------------------------------------------------------------+
remote: | Merge request create failed. There exists a same merge request in progress: |
remote: | https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31620 |
remote: +-----------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
! [remote rejected] master -> master (create MR failed)
error: 无法推送一些引用到 'https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git'
更新指定的评审
在同时有多个开启的代码评审的情况下,执行git push
时,会因无法判断想要更新哪一个评审而失败。
$ git push
枚举对象中: 5, 完成.
对象计数中: 100% (5/5), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 294 字节 | 294.00 KiB/s, 完成.
总共 3(差异 1),复用 0(差异 0),包复用 0
remote: +-------------------------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-------------------------------------------------------------------------------------------------+
remote: | You need to manually specify the merge request to update because there are already |
remote: | multiple merge requests that you created earlier for the same target branch: |
remote: | |
remote: | * [ID: 31626] https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31626 |
remote: | * [ID: 31620] https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31620 |
remote: | |
remote: | Then, update specific merge request based on it's ID (MR-ID): |
remote: | git push -o review=<MR-ID> |
remote: | |
remote: | Or you can create a new one: |
remote: | git push -o review=new |
remote: +-------------------------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
! [remote rejected] master -> master (unable to determine which mr to update)
error: 无法推送一些引用到 'https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git'
给出的提示信息中显示,存在指向同一目标分支的两个评审,ID分别为31626
以及31620
,因此无法判断想要更新的是哪一个评审。此时有两种解决方式:
使用
-o review=new
,创建一个新的代码评审。使用
-o review=<MR-ID>
,显式的给出想要更新的评审的ID。
第一种方式在 创建新的评审 一节中已经演示过了,我们来看如何更新指定的评审。
假如此时要更新31626
这个评审,那么具体的命令为: git push -o review=31626
。
$ git push -o review=31626
枚举对象中: 5, 完成.
对象计数中: 100% (5/5), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 303 字节 | 303.00 KiB/s, 完成.
总共 3(差异 1),复用 0(差异 0),包复用 0
remote: +-----------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-----------------------------------------------------------------------------------+
remote: | Merge request #31626 has been updated, please visit: |
remote: | https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31626 |
remote: +-----------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
0ba010f2ff..037578c634 master -> refs/merge-requests/31626/head
这样,就更新了 ID为31626
的代码评审。
更新评审的冲突解决
有时,想要更新代码评审时,会发现评审可能已经被其他用户更新了。此时,为了避免其他用户的更新被覆盖,更新会失败。假设此时要更新31644
这个评审,执行:git push -o review=31644
$ git push -o review=31644
枚举对象中: 4, 完成.
对象计数中: 100% (4/4), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 326 字节 | 326.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
remote: +--------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +--------------------------------------------+
remote: | MR is diverged with this push |
remote: +--------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
! [remote rejected] master -> master (MR is diverged with this push)
error: 无法推送一些引用到 'https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git'
提示信息中此次push会引起评审的冲突,更新失败了。此时有两种选择:
拉取其他用户的更新,在本地解决后再更新评审。
强制刷新评审。
先来看第一种方式。拉取更新在本地解决后再更新评审。
首先,需要执行 git fetch origin refs/merge-requests/<mr-id>/head
,这里mr-id
为31644
,所以需要执行的命令是:git fetch origin refs/merge-requests/31644/head
$ git fetch origin refs/merge-requests/31644/head
来自 https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo
* branch refs/merge-requests/31644/head -> FETCH_HEAD
然后,rebase本地的改动到评审对应的引用上。执行git rebase FETCH_HEAD
。rebase操作可能会出现冲突,请根据实际情况解决。
$ git rebase FETCH_HEAD
成功变基并更新 refs/heads/master。
这样,本地就拥有了远端的代码,然后重新执行push。
$ git push -o review=31644
枚举对象中: 4, 完成.
对象计数中: 100% (4/4), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 331 字节 | 331.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
remote: +-----------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-----------------------------------------------------------------------------------+
remote: | Merge request #31644 has been updated, please visit: |
remote: | https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31644 |
remote: +-----------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
a4a2cad45c..8da076fb44 master -> refs/merge-requests/31644/head
这样,就更新了31644这个代码评审。
强制刷新评审
有时,不想合并其他用户的改动,想要把评审强制刷新成本地的版本,这个时候应该如何操作呢?
此时,需要知道两个值。
一个是代码评审的ID,即代码评审URL的最后一段数字。例如,代码评审的URL是
https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31644
,那么这个评审的ID即为31644
另一个是代码评审的源版本。在代码评审的详情页可获得。这里对应的源版本即为
8da076fb
然后,可以执行 git push -o review=<mr-id> -o old-oid=<old-oid>
,对应这个例子,命令为git push -o review=31644 -o old-oid=8da076fb
这样,就将31644
这个评审刷新成了本地的版本。这个过程中,其他用户的修改会被覆盖,所以只有在明确的想要强制刷新版本时,再执行这个命令,以免丢失其他用户的修改。
$ git push -o review=31644 -o old-oid=8da076fb
总共 0(差异 0),复用 0(差异 0),包复用 0
remote: +-----------------------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +-----------------------------------------------------------------------------------+
remote: | Merge request #31644 has been updated, please visit: |
remote: | https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo/merge_request/31644 |
remote: +-----------------------------------------------------------------------------------+
To https://codeup.aliyun.com/61234c2d1bd96aa110f27b9c/demo.git
8da076fb44..8da076fb44 master -> refs/merge-requests/31644/head
跳过评审,直接更新代码
有时,可能仅仅做了一些微小的提交,例如改了代码注释中的错别字,想要跳过代码评审,应该如何操作呢?此时,可以使用 git push -o review=no
命令来跳过创建代码评审。命令的行为与未开启推送评审模式时执行git push
一致。需要注意的是,必须有相应分支的推送权限才可以使用review=no
直接推送代码。
一些其他的说明
更新评审需要是评审者或是评审的作者,否则更新会失败。
remote: +---------------------------------------------------------------------+
remote: | The following tips are provided by Codeup: |
remote: +---------------------------------------------------------------------+
remote: | Merge request #31644 update failed. |
remote: | You need to be the author or reviewer to update this merge request. |
remote: +---------------------------------------------------------------------+