背景
-
自动提取分支号需求
- 团队git分支要求和工单号对应, 格式
feature/rm102345_...
- 团队要求分支commit message中要包含工单号, 便于今后代码追踪
.git/hooks/prepare-commit-msg
可以做这个事情, 但是hooks不属于版本库(无法提交供团队使用)
- 团队git分支要求和工单号对应, 格式
-
nodejs 代码增加commit前jshint检测
rails 方案
-
config/environments/development.rb
最后增加# 执行脚本添加prepare-commit-msg require(File.join(Rails.root, 'script/symbol_link_prepare_commit_msg.rb'))
-
script/symbol_link_prepare_commit_msg.rb
, 用于添加链接文件, 之所以使用链接文件, 是便于项目今后方便修改prepare-commit-msg hook#!/usr/bin/env ruby # encoding: utf-8 require 'fileutils' old = File.expand_path('../prepare-commit-msg', __FILE__) new = File.expand_path('../../.git/hooks/prepare-commit-msg', __FILE__) unless File.exist?(new) FileUtils.ln_s(old, new). puts "成功添加链接文件 #{new}" end
-
script/prepare-commit-msg
想放到hook里的shell文件, 用于分析提取准备工单号#!/bin/sh BRANCH=`git rev-parse --abbrev-ref HEAD` RM_NUMBER=`echo $BRANCH | grep -o -e 'rm[0-9]*' || echo $BRANCH` echo -n "[$RM_NUMBER] " > "$1.msg" cat "$1" >> "$1.msg" cat "$1.msg" > "$1"
node 方案
-
启动脚本中
if (app.isDevelopment) { //将script/pre-commit 链接到.git/hooks/pre-commit //这个脚本是处理pre-commit, 实现commit时 jshint检测 app.requireModule('script/symbol_link_pre-commit'); //将script/prepare-commit-msg 链接到.git/hooks/prepare-commit-msg //这个脚本是处理prepare-commit-msg, 实现提取工单号 app.requireModule('script/symbol_link_prepare-commit-msg.js'); }
-
script/symbol_link_pre-commit.js
#!/usr/bin/env node var fs = require('fs'); var path = require('path'); var srcFile = path.join(__dirname, 'pre-commit'); var targetFile = path.join(__dirname, '../.git/hooks/pre-commit'); fs.exists(targetFile, function (exists) { if (!exists) { fs.symlink(srcFile, targetFile, function(err) { if (err) { console.log("添加链接文件失败: " + targetFile); } else { console.log("成功添加链接文件: " + targetFile); } }); } });
-
script/symbol_link_prepare_commit_msg.rb
#!/usr/bin/env ruby # encoding: utf-8 require 'fileutils' old = File.expand_path('../prepare-commit-msg', __FILE__) new = File.expand_path('../../.git/hooks/prepare-commit-msg', __FILE__) unless File.exist?(new) FileUtils.ln_s(old, new). puts "成功添加链接文件 #{new}" end
-
script/prepare-commit-msg
同 ruby -
script/pre-commit
#!/usr/bin/env bash files=$(git diff --cached --name-only --diff-filter=ACM | grep -v "^test\|^node_modules\|^public/assets\|^app/assets" | grep ".js$") if [ "$files" = "" ]; then exit 0 fi PARENT_COMMAND="$(ps -o args= $PPID)" #获得父命令以及参数, 目的是检测提交message中是否指示跳过jshint验证 if [[ $PARENT_COMMAND == *escape_jshint* ]]; then #特殊用途!!! 如合并代码 exit 0 fi if ! type "jshint" > /dev/null; then echo -e "\t请按照此命令安装指定版本的jshint: \033[31m npm install [email protected] -g \033[0m" exit 1 fi version=$((jshint -v) 2>&1) if ! [[ "$version" == 'jshint v2.4.4' ]]; then echo -e "\tjshint版本不对, 请卸载后安装版本2.4.4: \033[31m npm install [email protected] -g \033[0m" exit 1 fi pass=true echo -e "\nValidating JavaScript:\n" for file in ${files}; do result=$(jshint ${file}) if [ "$result" = "" ]; then echo -e "\t\033[32mJSHint Passed: ${file}\033[0m" else echo -e "\t\033[31mJSHint Failed: ${file}\033[0m" pass=false fi done echo -e "\nJavaScript validation complete\n" if ! $pass; then echo -e "\033[41mCOMMIT FAILED:\033[0m Your commit contains files that should pass JSHint but do not. Please fix the JSHint errors and try again.\n" exit 1 else echo -e "\033[42mCOMMIT SUCCEEDED\033[0m\n" fi
git commit规范
Why 为什么要有git commit规范?
- 加快 Reviewing Code 的过程
- 方便代码git blame时进行工单追踪
- 5年后帮你快速想起来某个分支,tag 或者 commit 增加了什么功能,改变了哪些代码
- 好的提交信息能帮助提高项目整体质量
commit 规范
-
使用git add时,请使用-p参数,这样可以强制检查要提交的修改,例如: git add -p .
-
commit 消息一律使用中文, 提高可读性,大家英文水平不一,容易写错,也不易读懂。
-
commit 消息前统一加上工单号, 格式为 “[rm工单号] 具体说明” 如 “[rm12345] 重构XXX代码”
关于这点, 我们已经要求了很久, 但是执行结果还不是很理想,最近我们增加了一个脚本来自动完成这个工作, 请大家合并最新的develop获得该功能, 说明:
原理: git 提供了若干hooks, 其中 prepare-commit-msg 可以修改提交信息. 唯一的问题是这些hooks不属于版本库(无法提交供团队使用)
我们rails项目 中的解决办法是: 在加载rails development模式时,检查有没有.git/hooks/prepare-commit-msg如果没 有的话将软连接script/symbol_link_prepare_commit_msg.rb到.git/hooks/prepare-commit-msg
具体代码见config/environments/development.rb 中require(File.join(Rails.root, ‘script/symbol_link_prepare_commit_msg.rb’))
使用: 请 大家合并最新的develop, 然后rails c 或者手动执行./script/symbol_link_prepare_commit_msg.rb, 完成之后大家提交时无需再手动写入’rm工单号’, 这一步就自动了, 这对于git commit -m XXX(inline提交) 和git commit(vi编辑提交内容) 都有效
-
在完成同一个工单时,可能会多次commit同一个模块的内容,这 样会造成git日志的重复以及日志里代码修改的分裂显示,这时候大家可以用 git commit –amend来解决
–amend这个参数可以将本次提交追加到上次提交里,并可以修 改上次提交的message。
请注意:只能对没有push的commit使用 git commit –amend命令,如果一个commit已经push到remote server,使用git commit –amend就会有非常大的概率造成代码冲突,所以请大家不要对已经push的代 码使用git commit –amend命令。
-
对于一个大的模块提交, 要是用完整提交模式(即 git commit 然后vi编辑message模式), 并注意格式:
- 第一行是本次提交的简介,需要加上工单号,如feature分支应 该是 [rm12345], 然后空格(脚本自动),然后加上简介。应该少于50个字
- 第二行是空行
- 第三行开始是本次修改的详细情况,主要要说明这些问题:
- 为什么这次修改是必要的?
- 如何解决的问题?
- 这些变化可能影响哪些地方?