Created
November 24, 2017 01:39
-
-
Save wingyiu/42f275b1be86615fe78996fc9adcbd0e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
SCRIPT_DIR=`readlink -f $(dirname $0)` | |
CONFNAME=git.conf | |
CFG_FILE=${SCRIPT_DIR}/${CONFNAME} | |
# 默认配置 | |
DIR=/tmp/boss/publish | |
# 加载自定义配置 | |
if [[ -f ${CFG_FILE} ]];then | |
source ${CFG_FILE} | |
fi | |
SOURCE_REPO=$2 | |
PROJECT=`echo ${SOURCE_REPO}|awk -F'/' 'gsub(/.git/,"",$2){print $2}'` | |
PRO_DIR=${DIR}/${PROJECT} | |
TIMESTAMP=`date +"%Y%m%d%H%M%S"` | |
#func | |
Usage() { | |
echo "Usage:" | |
echo " $0 <function> <git_repo> [parameter1] [parameter2] ..." | |
echo " [function] Specify the function you need" | |
echo " [git_repo] Specify the git address" | |
echo " [parameter] Specify the other parameters you need" | |
echo "Example:" | |
echo " $0 branch_head [email protected]:java/ps-hello.git master" | |
echo " $0 branch_tail [email protected]:java/ps-hello.git master" | |
echo " $0 online_head [email protected]:java/ps-hello.git" | |
echo " $0 branches [email protected]:java/ps-hello.git" | |
echo " $0 branch_commits [email protected]:java/ps-hello.git dev 0 15" | |
echo " $0 diffs [email protected]:java/ps-hello.git 797666c d3bd4bd" | |
echo " $0 diff_files [email protected]:java/ps-hello.git 797666c d3bd4bd" | |
echo " $0 diff_file_content [email protected]:java/ps-hello.git 797666c d3bd4bd pom.xml" | |
echo " $0 release [email protected]:wingyiu.li/ps-asdfsf.git e932c47 /data/boss/cmdb/log/publish_1073.log" | |
echo " $0 recover_release [email protected]:wingyiu.li/ps-asdfsf.git /data/boss/cmdb/log/publish_1073.log" | |
echo " $0 rollback_release [email protected]:wingyiu.li/ps-asdfsf.git /data/boss/cmdb/log/publish_1073.log" | |
echo " $0 archive [email protected]:wingyiu.li/ps-asdfsf.git /data/boss/cmdb/log/publish_1073.log" | |
echo " $0 rollback_online [email protected]:wingyiu.li/ps-asdfsf.git e298328 /data/boss/cmdb/log/publish_1073.log" | |
echo " $0 commit_file [email protected]:wingyiu.li/ps-asdfsf.git e298328 pom.xml" | |
echo " $0 commit_tree [email protected]:wingyiu.li/ps-asdfsf.git e298328" | |
} | |
function log() { | |
echo "`date +"%F %T"` $@" | |
# echo "`date +"%F %T"` $@" >> ${SCRIPT_DIR}/git.log | |
} | |
function ensure_repo() { | |
if [[ ! -d ${DIR} ]];then | |
mkdir -p ${DIR} | |
fi | |
cd ${DIR} | |
if [[ ! -d ${PRO_DIR} ]];then | |
git clone ${SOURCE_REPO} | |
if [[ $? -ne 0 ]];then | |
log "[ERROR] <${SOURCE_REPO}> clone fail" | |
exit 1 | |
fi | |
fi | |
cd ${PRO_DIR} | |
git fetch origin | |
} | |
function ensure_branch() { | |
local branch=$1 | |
local remote_br="remotes/origin/${branch}" | |
ensure_repo | |
cd ${PRO_DIR} | |
ck_result=`git branch -a | grep ${remote_br}` | |
if [[ -n ${ck_result} ]];then | |
# git checkout ${branch} | |
git update-ref refs/heads/${branch} origin/${branch} | |
else | |
git checkout -b ${branch} | |
fi | |
} | |
#function: release | |
#description: 发布,返回合并后的SHA | |
function release() { | |
local commit=$1 | |
local logfile=$2 | |
echo '--------------拉release,合并到release------------------' &>> ${logfile} | |
ensure_branch master &>> ${logfile} | |
cd ${PRO_DIR} | |
# TODO 如果已经有release,表示有正在进行的发布,不应该允许再来一个 | |
git checkout -b release &>> ${logfile} | |
# TODO 判断master和online是否在一起? | |
# TODO 如果release 和 commit在同一个commit | |
merge_log=`git merge --no-ff --commit ${commit}` | |
if [[ $? -ne 0 ]];then | |
log "[ERROR] merge ${commit} fail: ${merge_log}" | |
log ${merge_log} | |
exit 1 | |
fi | |
echo $merge_log &>> ${logfile} | |
git push origin release &>> ${logfile} | |
merged=`git log --pretty=format:"%H" --max-count=1 release` | |
echo "合并后COMMIT:${merged}" &>> ${logfile} | |
echo ${merged} | |
echo '----------------------------------------------' &>> ${logfile} | |
} | |
#function: recover_release | |
#description: merge失败后恢复 | |
function recover_release() { | |
local logfile=$1 | |
echo '--------------恢复------------------' &>> ${logfile} | |
ensure_branch master &>> ${logfile} | |
cd ${PRO_DIR} | |
git checkout master &>> ${logfile} | |
git reset --hard HEAD | |
git branch -D release | |
echo '----------------恢复完毕------------------------' &>> ${logfile} | |
} | |
#function: archive | |
#description: master和online回归 | |
function archive() { | |
local logfile=$1 | |
echo '--------------master和online归档------------------' &>> ${logfile} | |
ensure_repo &>> ${logfile} | |
cd ${PRO_DIR} | |
git checkout master &>> ${logfile} | |
git pull origin master &>> ${logfile} | |
git merge --ff origin/release &>> ${logfile} | |
if [[ $? -ne 0 ]];then | |
log "[ERROR] merge origin/release fail" | |
exit 1 | |
fi | |
TAG="tag-${TIMESTAMP}" | |
git tag $TAG &>> ${logfile} | |
git push --tags origin master &>> ${logfile} | |
git push origin --delete release &>> ${logfile} | |
git branch -D release &>> ${logfile} | |
local check_online=`git branch -a | grep 'online'` | |
if [[ -z ${check_online} ]];then | |
git checkout -b online &>> ${logfile} | |
git merge --ff origin/master &>> ${logfile} | |
git push --tags origin online &>> ${logfile} | |
else | |
git checkout online &>> ${logfile} | |
git merge --ff origin/master &>> ${logfile} | |
git push --tags origin online &>> ${logfile} | |
fi | |
echo "打标签为:$TAG" &>> ${logfile} | |
echo $TAG | |
echo '----------------------------------------------' &>> ${logfile} | |
} | |
#function: rollback_release | |
#description: 回滚发布分支 | |
function rollback_release() { | |
local logfile=$1 | |
echo '--------------回滚release------------------' &>> ${logfile} | |
cd ${PRO_DIR} | |
local check_release=`git branch -a | grep 'release'` | |
if [[ -n ${check_release} ]];then | |
git checkout master &>> ${logfile} | |
git push origin --delete release &>> ${logfile} | |
git branch -D release &>> ${logfile} | |
else | |
log "[ERROR] release branch not existed" | |
exit 1 | |
fi | |
echo '----------------------------------------------' &>> ${logfile} | |
} | |
#function: rollback_online | |
#description: 回滚线上分支,需指定回滚到那个commit | |
function rollback_online() { | |
local last_commit=$1 | |
local logfile=$1 | |
echo '--------------回滚online------------------' &>> ${logfile} | |
ensure_repo &>> ${logfile} | |
cd ${PRO_DIR} | |
git checkout online &>> ${logfile} | |
git reset --hard ${last_commit} &>> ${logfile} | |
git push --force origin online &>> ${logfile} | |
echo '----------------------------------------------' &>> ${logfile} | |
} | |
#function: diff_files | |
#description: 两个commit间的差异文件 | |
function diff_files() { | |
local sha_start=$1 | |
local sha_end=$2 | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git diff --name-status ${sha_start} ${sha_end} | |
} | |
#function: diff_file_content | |
#description: 两个commit间的某文件的内容差异 | |
function diff_file_content() { | |
local sha_start=$1 | |
local sha_end=$2 | |
local file=$3 | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git diff ${sha_start} ${sha_end} -- ${file} | |
} | |
#function: diffs | |
#description: 两个commit间的差异 | |
function diffs() { | |
local sha_start=$1 | |
local sha_end=$2 | |
local file=$3 | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git diff ${sha_start} ${sha_end} | |
} | |
#function: branches | |
#description: 所有分支(远端) | |
function branches() { | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git branch -r | grep -v HEAD | sed s/\ //g | |
} | |
#function: branch_commits | |
#description: 某个分支的commit log,树形,分页 | |
function branch_commits() { | |
local branch=$1 | |
local offset=$2 | |
local limit=$3 | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git log --graph --date-order --pretty=format:"<%H | %cn | %ci | %s>" --skip=${offset} --max-count=${limit} origin/${branch} -- | |
} | |
#function: branch_head | |
#description: 当前某个分支的最新commit | |
function branch_head() { | |
local branch=$1 | |
ensure_branch ${branch} &> /dev/null | |
cd ${PRO_DIR} | |
git log --pretty=format:"%H" --max-count=1 origin/${branch} -- | |
} | |
#function: branch_tail | |
#description: 当前某个分支的最旧commit | |
function branch_tail() { | |
local branch=$1 | |
ensure_branch ${branch} &> /dev/null | |
cd ${PRO_DIR} | |
git log --pretty=format:"%H" origin/${branch} | tail -n 1 | |
} | |
#function: commit_file | |
#description: commit中某个文件的内容 | |
function commit_file() { | |
local commit=$1 | |
local path=$2 | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git show ${commit}:${path} | |
} | |
#function: commit_tree | |
#description: commit中所有文件 | |
function commit_tree() { | |
local commit=$1 | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git ls-tree -r --name-only ${commit} | |
} | |
#function: current_publog | |
#description: 某个app最新的发布过程日志文件名 | |
function current_publog() { | |
local appid=$1 | |
local dir=$2 | |
cd ${dir} | |
local ticket=`find . -type f -name "${appid}_*.log" | awk -F'[/_.]' '{ print $4}' | sort -r | head -n 1` | |
echo ${appid}_${ticket}.log | |
} | |
#function: log_content | |
#description: 分行获取某个日志文件名的内容,有多少拿多少 | |
function log_content() { | |
local file=$1 | |
local offset=$2 | |
tail -c +${offset} ${file} | |
} | |
#function: release_vue | |
#description: 发布VUE,返回x后的SHA | |
function release_vue() { | |
local branch=$1 | |
local previous_master=$2 | |
local commit=$3 | |
local logfile=$4 | |
echo '-----------------合并到master------------------' &>> ${logfile} | |
ensure_branch master &>> ${logfile} | |
ensure_branch ${branch} &>> ${logfile} | |
cd ${PRO_DIR} | |
git checkout ${branch} &>> ${logfile} | |
diff_files=`git diff --name-status ${previous_master} ${commit}` | |
local fss=(`git diff --name-status ${previous_master} ${commit} | awk '{print $1}'`) | |
local fns=(`git diff --name-status ${previous_master} ${commit} | awk '{print $2}'`) | |
for i in ${!fss[@]} | |
do | |
if [[ ${fss[$i]} == "D" ]]; then | |
git rm ${fns[$i]} &>> ${logfile} | |
else | |
git checkout ${commit} -- ${fns[$i]} &>> ${logfile} | |
fi | |
done | |
git commit -am "+${commit}" &>> ${logfile} | |
git push origin ${branch} &>> ${logfile} | |
merged=`git log --pretty=format:"%H" --max-count=1 ${branch} -- ` | |
echo "新COMMIT:${merged}" &>> ${logfile} | |
echo ${merged} | |
echo '----------------------------------------------' &>> ${logfile} | |
} | |
#function: rollback_vue | |
#description: 回滚VUE,返回x后的SHA | |
function rollback_vue() { | |
local branch=$1 | |
local previous_master=$2 | |
local commit=$3 | |
local logfile=$4 | |
echo '-----------------合并到master------------------' &>> ${logfile} | |
ensure_branch master &>> ${logfile} | |
ensure_branch ${branch} &>> ${logfile} | |
cd ${PRO_DIR} | |
git checkout ${branch} &>> ${logfile} | |
diff_files=`git diff --name-status ${commit} ${previous_master}` | |
local fss=(`git diff --name-status ${commit} ${previous_master} | awk '{print $1}'`) | |
local fns=(`git diff --name-status ${commit} ${previous_master} | awk '{print $2}'`) | |
for i in ${!fss[@]} | |
do | |
if [[ ${fss[$i]} == 'D' ]]; then | |
git rm ${fns[$i]} &>> ${logfile} | |
else | |
git checkout ${previous_master} -- ${fns[$i]} &>> ${logfile} | |
fi | |
done | |
git commit -am "-${commit}" &>> ${logfile} | |
git push origin ${branch} &>> ${logfile} | |
merged=`git log --pretty=format:"%H" --max-count=1 ${branch}` | |
echo "新COMMIT:${merged}" &>> ${logfile} | |
echo ${merged} | |
echo '----------------------------------------------' &>> ${logfile} | |
} | |
#function: archive_vue | |
#description: 发布VUE,返回x后的SHA | |
function archive_vue() { | |
local branch=$1 | |
local previous_master=$2 | |
local commit=$3 | |
local logfile=$4 | |
echo '-----------------合并到master------------------' &>> ${logfile} | |
ensure_branch master &>> ${logfile} | |
ensure_branch ${branch} &>> ${logfile} | |
cd ${PRO_DIR} | |
git checkout master &>> ${logfile} | |
merge_log=`git merge --no-ff --commit ${commit}` | |
if [[ $? -ne 0 ]];then | |
log "[ERROR] merge ${commit} fail: ${merge_log}" | |
log ${merge_log} | |
exit 1 | |
fi | |
echo $merge_log &>> ${logfile} | |
git push origin master &>> ${logfile} | |
merged=`git log --pretty=format:"%H" --max-count=1 ${branch} -- ` | |
echo "新COMMIT:${merged}" &>> ${logfile} | |
echo ${merged} | |
echo '----------------------------------------------' &>> ${logfile} | |
} | |
#function: commit_info | |
#description: commit基本信息 | |
function commit_info() { | |
local commit=$1 | |
ensure_repo &> /dev/null | |
cd ${PRO_DIR} | |
git log ${commit} -1 --abbrev=40 | |
} | |
function listfunc() { | |
echo -e "\nAvailable functions example:\n" | |
local func_list=(`grep '^#function:' $0 | awk '{print $2}'`) | |
local func_desc=(`grep '^#description:' $0 | awk '{print $2}'`) | |
for i in ${!func_list[@]} | |
do | |
printf "%-20s %s %s\n" ${func_list[$i]} \#${func_desc[$i]} | |
done | |
} | |
case $1 in | |
release) | |
release $3 $4 | |
;; | |
release_vue) | |
release_vue $3 $4 $5 $6 | |
;; | |
recover_release) | |
recover_release $3 | |
;; | |
archive) | |
archive $3 | |
;; | |
rollback_release) | |
rollback_release $3 | |
;; | |
rollback_online) | |
rollback_online $3 $4 | |
;; | |
rollback_vue) | |
rollback_vue $3 $4 $5 $6 | |
;; | |
branches) | |
branches | |
;; | |
diffs) | |
diffs $3 $4 | |
;; | |
diff_files) | |
diff_files $3 $4 | |
;; | |
diff_file_content) | |
diff_file_content $3 $4 $5 | |
;; | |
branch_commits) | |
branch_commits $3 $4 $5 | |
;; | |
branch_head) | |
branch_head $3 | |
;; | |
branch_tail) | |
branch_tail $3 | |
;; | |
commit_file) | |
commit_file $3 $4 | |
;; | |
commit_info) | |
commit_info $3 | |
;; | |
commit_tree) | |
commit_tree $3 | |
;; | |
current_publog) | |
current_publog $2 $3 | |
;; | |
log_content) | |
log_content $2 $3 $4 | |
;; | |
-h) | |
Usage | |
listfunc | |
exit 0 | |
;; | |
*) | |
log "[ERROR] error options" | |
Usage | |
listfunc | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment