介绍

随着DevOps兴起,在做CD代码上线交付时候,代码全量更新是很费时间的。下面代码就可以帮助我们从指定分支两个Tag中获取差异文件,进行代码的增量更新。

环境

  • Jenkins
  • Git代码管理

获取指定分支最新得两个tag

使用到了 git tag -l 命令,git tag -l 名称* 模糊查询标签列表。利用 名称* 方式我们可以区分不同分支的tag。

生成远程执行更新脚本

主要做文件删除。

--diff-filter说明

--diff-filter=[(A|C|D|M|R|T|U|X|B)…[*]]

只选择那些添加 (A), 赋值 (C), 删除 (D), 修改 (M), 重命名 (R)的文件, 它们的类型(如 普通文件, 符号链接, 子模块, …) 是否改变 (T), 是否未合并 (U), 是未知 (X), 或它们的对崩溃(B). 任何过滤字符的组合(包括none)均可使用。当组合中包括All或none,如果任一文件匹配了其他选项,就选择了所有路径。如果没有文件匹配其他选项,什么都不做。

Diff现在支持接受小写字母参数,含义为展示所有非指定类型的变化。

被删除的文件

由最新的 Tag 和上一个 Tag 做对比,用 --diff-filter=D

delete_file_list=($(git diff $second_real_tag $first_real_tag --name-only --diff-filter=D))
echo "----------------把要删除得文件写入shell脚本-----------------"
for item in ${delete_file_list[@]};
do
echo $item
echo "rm -rf ${item}" >> update_dir/jenkins_update.sh
done

被重命名的文件

这里有个小技巧,由上一个的 Tag 和最新 Tag 做反向对比,用 --diff-filter=R

rename_file_list=($(git diff $first_real_tag $second_real_tag --name-only --diff-filter=R))
echo "----------------把重命名的文件也加入删除shell脚本-----------------"
for item in ${rename_file_list[@]};
do
echo $item
echo "rm -rf ${item}" >> update_dir/jenkins_update.sh
done

完整shell脚本

#!/bin/bash

# 创建更新目录
rm -rf update_dir
mkdir update_dir

# 获取最新得两个tag
last_two_tags=($(git tag -l release_*))
last_two_tags_len=${#last_two_tags[*]}


# 获取去除tag其他标识
first_real_tag=${last_two_tags[$last_two_tags_len-1]}
second_real_tag=${last_two_tags[$last_two_tags_len-2]}

echo "----------------当前对比两个版本-----------------"
echo $first_real_tag
echo $second_real_tag

# 创建删除文件列表shell
touch ./update_dir/jenkins_update.sh
echo "#!/bin/bash" >> update_dir/jenkins_update.sh

# 把要删除得文件写入shell脚本
delete_file_list=($(git diff $second_real_tag $first_real_tag --name-only --diff-filter=D))
echo "----------------把要删除得文件写入shell脚本-----------------"
for item in ${delete_file_list[@]};
do
echo $item
echo "rm -rf ${item}" >> update_dir/jenkins_update.sh
done

# 把重命名的文件也加入删除shell脚本
rename_file_list=($(git diff $first_real_tag $second_real_tag --name-only --diff-filter=R))
echo "----------------把重命名的文件也加入删除shell脚本-----------------"
for item in ${rename_file_list[@]};
do
echo $item
echo "rm -rf ${item}" >> update_dir/jenkins_update.sh
done

echo "----------------拷贝要更新的文件到update_dir文件夹-----------------"
# 复制当前版本差异到 update_dir 限制 Add Create Modify Rename 操作
new_file=($(git diff $second_real_tag $first_real_tag --name-only --diff-filter=ACMR))
new_file_len=${#new_file[*]}
if (($new_file_len>0)); then
    cp -pv --parents $(git diff $second_real_tag $first_real_tag --name-only --diff-filter=ACMR)  ./update_dir/
fi