文章目录

  • 创建仓库
  • 增加commit
  • 通过javascript解析git log
  • 写入CHANGELOG.md
  • 解决git log 中同一feature重复写入的问题
  • 解决git log显示重复问题后的新代码
  • 总结
  • 参考文档

我们在github 或者gitlab上做项目管理的时候需要对 对应的项目做历史版本的管理,同时包括每个版本中所做的一些改动:feature,bugfix,improv。

如果我们能够有一个统一的自动化管理方式,那么对于我们后续的版本回顾就能提供巨大的便捷,同时能够提供每个commit对应的commit链接,那就更好了。

最终的版本管理CHANGELOG.md文件的效果如下:

创建仓库

按照自己的方式或者根据github的创建仓库的过程进行仓库的创建,我这里是从github上new出来的仓库,clone到本地

  • 本地mkdir test_release && cd test_release

  • 将github上创建的仓库链接clone到本地, git clone https://github.com/BaronStack/release_notes.git

  • 填写对应的用户名和github的密码,或者提前在本地仓库进行配置git config --local user.name "xxxname",git config --local user.email "xxx.email"

  • 按照git给定的步骤添加readme文件,并向远端合入

    echo "# release_notes" >> README.md
    git init
    git add README.md
    git commit -m "first commit"
    git remote add origin https://github.com/BaronStack/release_notes.git #可以省略,默认已经添加进去了
    git push -u origin master
    
  • 我们当前是在master分支上,建议按照规范的开发流程checkout一个子分支,在子分支上做变更,后续合入到master之中
    git checkout -b develop-v0.1-feature-add_release_and_changelog

增加commit

这里多做一些变更, 多增加一些commit,方便后续的样例演示。

  1. 增加一个json文件,保存版本信息
    touch release_version.json
    向其中添加内容:

    {"version":"0.0"
    }
    
  2. 创建一个空的CHANGELOG.md文件,touch CHANGELOG.md
  3. 将以上两个文件作为一个commit进行提交,commit信息"feature: add version file and changelog.md file"
    git add .
    git commit -m"feature: add version file and changelog.md file"
    
  4. 再对README.md做一些简单修改, 并提交一个bugfix属性的commit
    git add README.md
    git commit -m"bugfix: fix some info for readme.md"
    

通过javascript解析git log

执行命令 git log,我们能够看到提交的commit信息以及对应的commit id(之前我们说过是64位的hash值,用来标识唯一的commit对象)

通过命令 git log --format=%B%H 可以对log的输出进行简化,仅仅保留commit信息和commitid的信息

feature: add release_version file and changelog.md file
683c1fd6e618cdabfceabd6cd5ea880314ade5ad
feature add somedetails for README
248d299dae85083d2bb3b92fd82c01d07e03ce55
add readme file
ec9e1fdb05c425dd775e6e1c0df2f5ced32e7a66

编写release_produce.js

const child = require('child_process');//增加一些用作区分上下行的标记
const output = child.execSync(`git log --format=%B%H----DELIMITER----`).toString('utf-8');//拆分标记到一个管理commit message 和 commit id的映射表中
const commitsArray = output.split('----DELIMITER----\n').map(commit => {const [message, sha] = commit.split('\n');return { sha, message };
}).filter(commit => Boolean(commit.sha));console.log({ commitsArray });

执行node release_produce.js最后的输出如下:

{commitsArray: [{sha: '683c1fd6e618cdabfceabd6cd5ea880314ade5ad',message: 'feature: add release_version file and changelog.md file'},{sha: '248d299dae85083d2bb3b92fd82c01d07e03ce55',message: 'feature add somedetails for README'},{sha: 'ec9e1fdb05c425dd775e6e1c0df2f5ced32e7a66',message: 'add readme file'}]
}

我们就发现已经能够获取到message和sha的信息了,接下来我们想要对上面组合的map数组进行解析,将结果按照feature以及message信息写入到CHANGELOG.md之中

写入CHANGELOG.md

这段代码是根据我们上面获取到的message和sha的数组写的,它能够将最终的结果写入到CHANGELOG之中。

const child = require("child_process");
const fs = require("fs");const output = child.execSync(`git log --format=%B%H----DELIMITER----`).toString("utf-8");const commitsArray = output.split("----DELIMITER----\n").map(commit => {const [message, sha] = commit.split("\n");return { sha, message };}).filter(commit => Boolean(commit.sha));const currentChangelog = fs.readFileSync("./CHANGELOG.md", "utf-8");
const currentVersion = Number(require("./release_version.json").version);
const newVersion = currentVersion + 1;// 用version和时间作为release 标记
let newChangelog = `# Version ${newVersion} (${new Date().toISOString().split("T")[0]
})\n\n`;const features = [];
const Bugfixes = [];// 分别维护features和bugfixes的内容,并将message和commit的链接进行绑定
commitsArray.forEach(commit => {if (commit.message.startsWith("feature: ")) {features.push(`* ${commit.message.replace("feature: ", "")} ([${commit.sha.substring(0,6)}](https://github.com/BaronStack/release_notes/commit/${commit.sha}))\n`);}if (commit.message.startsWith("chore: ")) {Bugfixes.push(`* ${commit.message.replace("chore: ", "")} ([${commit.sha.substring(0,6)}](https://github.com/BaronStack/release_notes/commit/${commit.sha}))\n`);}
});if (features.length) {newChangelog += `## Features\n`;features.forEach(feature => {newChangelog += feature;});newChangelog += '\n';
}if (Bugfixes.length) {newChangelog += `## Bugfixes\n`;bugfixes.forEach(bugfix => {newChangelog += bugfix;});newChangelog += '\n';
}// prepend the newChangelog to the current one
fs.writeFileSync("./CHANGELOG.md", `${newChangelog}${currentChangelog}`);

node relaease_produce.js 运行后查看对应的CHANGELOG.md文件,能够看到我们的CHANGELOG的结果如下

这里还是有一些问题的,当我们第二次进行变更的时候,将之前CHANGELOG的内容再次commit提交一个feature的信息
git add CHANGELOG.md , git commit -m "feature:mod some file for release-notes"

此时再次执行node relaease_produce.js,能够看到CHANGELOG.md内容变更为:

这里的同一个feature提交了两次,原因我们也很好理解,是因为我们直接解析的git log信息,而第一次和第二次git log内容是一样的,也就是同一个feature会被包含两次,就出现上面的现象了。

解决git log 中同一feature重复写入的问题

这个问题我们知道是由git log的统一显示导致的,因为git log默认显示的是当前分支所有的commit日志信息,但我们当前所需要的是让git log的显示和版本号绑定,即提交一个版本,只需要显示当前版本所做的变更,不需要将上一个版本的变更也显示进来。

那么这个时候就需要使用git tag命令来进行里程碑的标记,执行git tag -a -m "tag a version 0.1" version0.1 能够对之前所有的变更打一个tag,这个tag的名称叫做version0.1
此时再次通过git log能够看到当前的log信息的最新的commit中多了一个version0.1的信息

我们可以通过git describe --long 当前rep最新的tag

▶ git describe --long
version0.1-0-g1851661

以上输出含义如下:

  • version0.1 当前最新的tag名称
  • 数字’0‘ 表示最新的tag 和 HEAD 之间 commit的次数
  • g50df655 表示最新的tag所指向的最近一次的commit id,字母g是其前缀

其他git tag相关的命令还有如下几个

  • git tag -s 显示当前有多少个tag
  • git show <tag's name> 显示指定tag名称的描述信息
  • git tag -d <tag's name> 删除指定名称的tag
  • git tag -a -m"describe message" <tag's name> 前面描述过,这个是添加tag

此时我们可以通过tag查看当前tag起始commit 与最新的HEAD 所指向的commit之间都有哪一些提交日志
git log version0.1..HEAD ,可以看到我们只做了两次变更。

那么在打了tag的情况下我们就够获取本次相比于上次的tag之间的日志,而不会重复,这正是我们release-notes所想要提取的信息。

解决git log显示重复问题后的新代码

重新编写release_produce.js,需要增加如下功能

  1. 修改output的message获取方式为git decribe --log

    const latestTag = child.execSync('git describe --long').toString('utf-8').split('-')[0];
    const output = child.execSync(`git log ${latestTag}..HEAD --format=%B%H----DELIMITER----`).toString("utf-8");
    
  2. 在最后写入到CHANGELOG.md之后需要根据新的version打上tag,并将version版本号更新到json文件中,且还需要提交修改后的json文件。
    // update package.json
    fs.writeFileSync("./package.json", JSON.stringify({ version: String(newVersion) }, null, 2));// create a new commit
    child.execSync('git add .');
    child.execSync(`git commit -m "chore: Bump to version ${newVersion}"`);// tag the commit
    child.execSync(`git tag -a -m "Tag for version ${newVersion}" version${newVersion}`);
    

将以上代码添加到release_produce.js中之后我们再次提交一些信息,完成之后将当前分支提交到远端
git push origin develop-v0.1-feature-release_notes_changelog
同时也把我们打的tags添加到远端
git push origin --tags

github上查看对应的changelog.md ,会发现我们每次的version变更仅仅是当前的version和上一个version之间差异的信息。

对应的version tag信息也都同步到了github之上了。

总结

通过对git命令的灵活运用,我们能够完成对项目的版本管理。能够清晰的看到每一个版本都提交了哪些信息,开发了哪一些新特性,优化了什么功能。

希望能对大家有所帮助~

参考文档

git tags
git log
git describe

git 的release-notes以及对应的changelog管理相关推荐

  1. Python: Git Log自动生成Release Notes,并调用Outlook发送至邮件

    Python: Git Log自动生成Release Notes,并调用Outlook发送至邮件 主要功能 先上图 生成ReleaseNotes 邮件: 生成ReleaseNotes Text: 关键 ...

  2. OpenDaylight系类教程(十二)-- Release Notes

    2019独角兽企业重金招聘Python工程师标准>>> Release Notes Target Environment For Execution The OpenDaylight ...

  3. Release notes for VPP 22.10

    本次发布新增了212个提交,包括118个修复. 关于本次发布的更多信息,请访问:https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blob;f=docs/aboutv ...

  4. Release notes for VPP 22.06

    本次发布新增了485个提交,包括230个修复. 发布亮点 针对5G的VPP Flow API增强: 通过DPDK插件中的通用流实现5G增强 为5G启用RSS队列组操作 为CSIT添加测试场景,包括: ...

  5. Salt2019.2.0 Release Notes (Codename Fluorine) 新版本功能特性

    SaltStack是基础设施管理的革命性方法,能够以速度取代复杂性. SaltStack足够简单,可以在几分钟内运行,可扩展到足以管理数以万计的服务器,并且速度足以在几秒钟内与每个系统进行通信.从服务 ...

  6. Altiris™ IT Management Suite 7 Release Notes

    Introduction Altiris™ IT Management Suite from Symantec is the industry's most comprehensive and int ...

  7. Tesla FSD 自动驾驶软件升级版本说明书解析二(Beta v10.12 Release Notes)

    Tesla FSD软件的版本说明书写得十分技术流,里面会详细列举新增了什么feature.修复了什么bug.采用了什么方法(算法还是数据等)提升了多少指标之类的信息,有助于从业人员了解Tesla的底层 ...

  8. Release Notes

    发行说明 (Release Notes) 尽早发布,经常发布 - Eric S. Raymond, The Cathedral and the Bazaar 版本 (Versioning) 次要版本号 ...

  9. Tesla FSD 自动驾驶软件升级版本说明书解析一(Beta v10.11.2 Release Notes)

    Tesla FSD软件的版本说明书写得十分技术流,里面会详细列举新增了什么feature.修复了什么bug.采用了什么方法(算法还是数据等)提升了多少指标之类的信息,有助于从业人员了解Tesla的底层 ...

  10. 第 10 章 Release Notes

    Release Notes 撰写说明 当一个项目升级时,需要写一个文档纪录这次变动,内容包括,新增了什么,更改了什么,修复了什么,未解决得问题,改善了什么,忽略了什么 常用信息类型 New Chang ...

最新文章

  1. iframe,window,滚动栏的一些问题
  2. fftw_plan_dft_2d异常 使用技巧
  3. 2017.3.1 xiaoyimi测试
  4. 传华为将有2万名CNBG员工转岗CBG 回应:该消息不属实
  5. java大数据组件HBase
  6. python contextlib
  7. Android内容提供者(群发短信)
  8. Android 访问权限设置
  9. oracle执行runstats,Oracle编程艺术--配置环境:runstats脚本
  10. Net下的AppDomain编程 [摘录]
  11. ICM-20602 IMU ACCEL/GYRO/TEMP I2C/SPI LGA
  12. DNK开发—Eclipse环境变量配置
  13. 百位LOL英雄联盟角色合集
  14. Android 去掉Power键屏保功能,但保留长按关机功能。
  15. 2022元宇宙共享大会|倪健中:我们正在开启元宇宙新时代
  16. 什么是JIT,JDK17移除了JIT?
  17. 计算机网络(10)奈氏准则和香农定理
  18. 机器学习经典书籍和论文集合
  19. 分布式系统中间件整理
  20. Mongo实战-分片集群的查询与索引

热门文章

  1. 计算机软件二次开发是否侵权,软件著作权的共有权人能否进行二次开发
  2. python整型数据源码分析_Python2 基本数据结构源码解析
  3. 问题 A: DS二叉树—二叉树构建与遍历
  4. 51单片机_13-2 DS18B20温度报警器
  5. 成功自媒体人怎能不懂运营规划?
  6. php怎么实现拼图功能,布局拼图功能实现
  7. 财务室扫描仪(XT100)--驱动找不到
  8. 编译android版本sdl2
  9. android 手势密码锁 GestureLock
  10. 欢天喜地接元宝python_python 拼接字