最近想要把git仓库的提交记录(commits)渲染到云设计项目的debugger信息中。考虑了两种方法,一种是本地git log然后使用webpack的插件DefinePlugin转换给web用。第二种是使用gitlab的api。虽然都有问题,但这里记录一些踩坑的过程。
Gitlab Api
gitlab关于commits的api文档参考:Commits API。比如我想获取一个月前的提交,可以这么写:
// 获取一个月前的ISO8601时间格式
const date = new Date();
date.setMonth(date.getMonth() - 1);
console.log('ISO8601', date);
let url = `${option.host}/api/v4/projects/${projectId}/repository/commits?private_token=${token}&since=${date.toISOString()}`;
const res = await axios.get(url);
然后第一个坑点就在这里,如果没有加任何限制的话,每页只显示20条记录。如图:

坑的是,这个api的文档里没有显示任何增加每页显示条数的方法。找了好久,才发现放到了Pagination。所以推测这是一个通用的api。不只是用于commit的请求返回。但是这有点太迷惑了。因此,如果我想要显示更多条数,比如1000条,可以这么写:
// url就是上面的url
url=`${url}/per_page=1000`
然后验证一下可知,它只显示100条。根据官方文档说的,每页最大只会显示100条。但是如果没有加since这个筛选条件的话,会发现不管是500还是1000都是可以显示的。所以突然想到。会不会是根据最大数量来判断的。比如我请求,查询到满足条件的有700条,那么如果我per_page限制为701。那么每页就只会返回100。经过试验,果然如此。所以如果想要返回全局满足条件的commit,可以做如下处理:
const res = await axios.get(url);
// 有多少条数据
const total = res.headers['x-total'];
let commitlog;
if (total) {
url = `${url}&per_page=${total - 1}`;
commitlog = await axios.get(url);
}
console.log('gitlab api commit log', commitlog);
先请求一次获取有多少条满足条件的数据。然后只要在请求一次把per_page限制在total-1就可以了。
虽然可以获取到满足条件的commits了。但是仔细想了一下发现这种通过gitlab api来获取请求的方式不符合需求,因为这个是实时获取gitlab仓库里的提交。但我要的是在项目发布那一刻的commits以确定是否有代码漏发布了。
还有一个小小的瑕疵是,我必须要把token暴露到请求里,这样随便一个人拿这个token都可以获取我仓库的代码提交信息以及根据api获取其它内容。虽然官方api提供了通过账户密码获取token的方式。但是这里的需求并不需要这样,所以就不考虑了。
本地git log的方式
这个方式是准备采用的方式。但是有两个问题,一个是提交记录如果太多,DefinePlugin会出错,报超出长度的错误。第二个是,没有办法获取到项目依赖包的提交记录。
虽然也尝试过sed的方式,但是也会报错,可能是因为有一些特殊字符的原因。这里先贴一下按照格式获取git log的方式:
const path = require('path')
const cwd = path.resolve(__dirname, '../');
const child_process = require('child_process')
const commitLog = child_process.execSync('git log --since="1 months" --pretty=format:"%h - %an,%ad - %ar,%s', { cwd, encoding: 'utf-8', maxBuffer: 2048 * 2048 })
module.exports = commitLog;
更多的可以参考git log文档