Слияние кода завершено, страница обновится автоматически
#!/bin/bash
#帮助
function usage()
{
echo "Usage examples:"
echo "$0 --repo2git <git_code>"
echo "$0 --format <tag1> <tag2>"
echo "$0 --apply <git_code>"
echo "$0 --list <tag1> <tag2>"
echo "$0 --checkTag <tag>"
echo "$0 --dos2unix <path>"
echo "$0 --patch <commit-id>"
echo "$0 --init"
echo "$0 --tag "
echo "$0 --modify"
exit 0
}
function usage_detail(){
echo "Usage detail:"
echo "#repo代码仓库转为大git仓库"
echo "$0 --repo2git <git_code>"
echo "#生成两个tag之间的补丁"
echo "$0 --format <tag1> <tag2>"
echo "#将补丁打入指定的git大仓库"
echo "$0 --apply <git_code>"
echo "#列出两个tag之间的提交"
echo "$0 --list <tag1> <tag2>"
echo "#校验repo所有仓库某个tag是否存在"
echo "$0 --checkTag <tag>"
echo "#指定类型文件转换成unix格式"
echo "$0 --dos2unix <path>"
echo "#初始化repo仓库的第一版"
echo "$0 --init"
echo "#根据commit-id号码生成大git仓库类型补丁"
echo "$0 --patch <commit-id>"
echo "#xxxx还没想到"
echo "$0 --tag "
echo "#修改repo生成的补丁,适应打入git"
echo "$0 --modify"
exit 0
}
function conflict_help(){
printf "两种解决冲突的方法:
1.解决冲突1
强制合入git apply PATCH --reject
根据生成的.rej文件合入冲突地方.edit edit edit修复冲突
译注:根据.rej文件手动解决所有冲突)
git add FIXED_FILES
git am --resolved
然后mv xxx.patch xxx.patch-fail
然后apply继续打补丁
2.解决冲突2
出现冲突后,用git apply --check检查下哪些文件导致无法打入patch,然后找出解决方案
一般都是由于文件类型问题,check后
然后fromdos这些文件
然后git add -A
然后am --resolved
然后mv xxx.patch xxx.patch-fail
然后apply继续打补丁
git apply 0001-add-line.patch --check
fromdos xxxfile
git apply 0001-add-line.patch
git add -A
git am --resolved
在解决完冲突以后,比如用git add来让git知道你已经解决完冲突了.
"
exit 1
}
#格式化输出
RED="\033[0;31m"
YELLOW="\033[1;33m"
GREEN="\033[0;32m"
NO_COLOR="\033[0m"
BOLD="\033[1m"
UNDERLINE="\033[4m"
warn_debug=true
die() {
echo -e "==> ${RED}${@}${NO_COLOR}"
exit 1
}
warn() {
if [[ "$warn_debug" = true ]]; then
echo -e "==> ${YELLOW}${@}${NO_COLOR}"
fi
}
good() {
echo -e "==> ${GREEN}${*}${NO_COLOR}"
}
function showTime(){
currentTime=$(date +%s)
echo $(date)
return $currentTime
}
function isRepo(){
if [ ! -d "./.repo" ];then
echo "This command must be executed in repo directory."
exit -1
fi
}
#转换文本dos格式
function change_from_dos(){
local ENCRYPT_FILE_TYPE="README|NOTICE|.*\.mt6750$\|.*\.custom$\|.*\.drivers$\|.*\.rc$\|.*\.patch$\|Makefile$\|makefile\|.*\.sh$|.*\.mk$\|.*\.xml$\|.*\.java$\|.*\.[cC]$\|.*\.cpp$\|.*\.h$\|.*\.hpp$\|.*\.[sS]$\|.*\.cc$"
local path=$1
for dfile in `find ${path} -regex "$ENCRYPT_FILE_TYPE"`
do
fromdos $dfile
echo $dfile
done
unset dfile
unset path
}
#获取android代码的主目录
function gettop
{
local TOPFILE=build/core/envsetup.mk
if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
# The following circumlocution ensures we remove symlinks from TOP.
(cd $TOP; PWD= /bin/pwd)
else
if [ -f $TOPFILE ] ; then
# The following circumlocution (repeated below as well) ensures
# that we record the true directory name and not one that is
# faked up with symlink names.
PWD= /bin/pwd
else
local HERE=$PWD
T=
while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
\cd ..
T=`PWD= /bin/pwd -P`
done
\cd $HERE
if [ -f "$T/$TOPFILE" ]; then
echo $T
fi
fi
fi
}
function getGit()
{
TOPFILE=build/core/envsetup.mk
local HERE=$PWD
T=
while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
T=$PWD
if [ -d "$T/.git" ]; then
echo ${T}
return
fi
cd ..
done
cd ${HERE}
#echo "can't find .git"
}
#判断tag是否缺失
function is_lose_tag(){
local tag=$1
for project in $(cat .repo/project.list)
do
cd $project
pwd
hasTag $tag
good $tag exist
cd - >/dev/null
done
unset project
}
#根据commit设置tag
function set_tag_of_commit(){
#local TAG_NAME=$1
#local TAG_TIME=$(date +%Y-%m-%d" "%T)
#local commit_id=$2
local date=$1
local project
for project in $(cat .repo/project.list)
do
cd $project
echo $(pwd)
commit_id=$(git log --reverse --oneline --pretty=%h | head -2 | tail -1)
#git tag -a "$TAG_NAME" -m "$TAG_TIME" $commit_id
git tag -a "ali_base_${date}" -m "${date}" $commit_id
cd - > /dev/null
done
unset project
}
#获取tag对应的commit
function get_commit_from_tag(){
local tag_name=$1
for project in $(cat .repo/project.list)
do
cd $project
echo -n $project"|"
commit_id=$(git log -1 --oneline $tag_name --format=%H)
#commit_id=$(git log -1 --oneline $tag_name --format=%H-%s)
echo $commit_id
cd - > /dev/null
done
}
#根据文件设置tag
function set_tag(){
local file=$2
local tag_name=$1
local TAG_TIME=$(date +%Y-%m-%d" "%T)
for content in $(cat $file)
do
project_path=$(echo $content| awk -F"|" '{print $1}')
project_commit=$(echo $content| awk -F"|" '{print $2}')
echo $project_path
echo $project_commit
cd $project_path
git tag -a "$tag_name" -m "$TAG_TIME" $project_commit
cd - > /dev/null
done
}
#判断git是否存在
function hasTag(){
local tag=$1
if [ -z "`git tag -l | grep -w ${tag}`" ];then
die "未找到$tag"
return 1
else
return 0
fi
}
#对比两个tag之间的差异
function get_tag_diff_list(){
local before_tag_name=$1
local after_tag_name=$2
for project in $(cat .repo/project.list)
do
#echo $project
cd $project
hasTag $before_tag_name
hasTag $after_tag_name
commit_list=$(git log --oneline ${before_tag_name}..${after_tag_name})
if [ -n "$commit_list" ];then
echo PATH: $project
echo COMMIT:
echo "$commit_list"
echo
fi
cd - > /dev/null
done
}
#第一次设置大git仓库
function repo2git_init(){
local project
for project in $(cat .repo/project.list)
do
#cd到每个仓库下面
cd $project
echo $(pwd)
#找到初始化时候的commit id
init_commit_id=$(git log --reverse --oneline --pretty=%h | head -2 | tail -1)
#将代码checkout到阿里初始化的状态
git checkout $init_commit_id 1>/dev/null 2>/dev/null
#判断当前checkout是否成功,如果成功删除当前.git仓库
if [ $(git log --oneline | wc -l) -le 2 ];then
echo "git checkout sucess"
if [ -d .git ];then
echo "find .git dir!"
#rm -rfv .git
fi
fi
cd - > /dev/null
done
unset project
}
#修改补丁(旧方法修改patch的表头,弃用)
function modify_format_patch(){
cd $OUT_DIR
for patch_path in $(find . -name "*.patch" -type f)
do
cd $(dirname $patch_path)
patch=$(basename $patch_path)
cur_dir=$(pwd)
add_path=${cur_dir:${#OUT_DIR}+1}
echo
good "当前路径:$cur_dir"
good "修改补丁文件:$patch"
good "该补丁文件大小:$(du -sh $patch | awk '{print $1}') "
good "准备修改路径:$add_path"
du -sh $patch | awk -F" " '{if($1~/M/)print "==> 补丁文件较大,请稍等..."}'
test -s $patch || mv $patch ${patch}-error
#warn "补丁文件可能过于大,耗时比较长,请稍等....."
#修改表头
sed -i "/^diff --git/{s#\ba/#a/${add_path}/# ; s#\bb/#b/${add_path}/#}" $patch
sed -i "/^--- a/{s#---\ a/#---\ a/${add_path}/#}" $patch
sed -i "/^+++ b/{s#+++\ b/#+++\ b/${add_path}/#}" $patch
good "修改补丁文件完成!"
cd $OUT_DIR
done
cd $CUR_DIR
}
#打入补丁
function git_apply_patch(){
local git_code=$1
local cur_dir=$(pwd)
cd $git_code
for patch in $(find $OUT_DIR -name "*.patch" -type f | sort )
do
fromdos $patch
good "Applying $patch"
#git am $patch --whitespace=nowarn
#git apply --check $patch
#由于commit-id的改变导致-3-way方式还是已经合入的patch无法检测出来
#git revert 反打的patch无法合入...有点蛋疼
#git am -3 -k $patch
git am -3 $patch
result=$?
echo "$git_code result=$?"
#.rej 文件手动对比合入
if [ ${result} = 1 ];then
warn "冲突:${git_code}/xxxxx路径下解决冲突后,git am --resolved"
conflict_help
else
mv $patch $patch-sucess
fi
echo $patch >> $OUT_DIR/patch_list
done
mv -v $OUT_DIR ${OUT_DIR}_${THIS_TAG}
test -d updatelist || mkdir updatelist
cp -fv ${OUT_DIR}_${THIS_TAG}/update_list.txt updatelist/${THIS_TAG}.txt
git add updatelist
git commit -m "common:add updatelist ${THIS_TAG}"
good "Patch已经完成,请记得在$git_code打上tag"
good "请确认完成后到${git_code}下执行git tag -a ${THIS_TAG} -m ${DATE}"
unset patch
cd $cur_dir
}
#单步生成标准补丁文件,用于适用单步提取补丁
function format_commit_patch(){
local T=$(gettop)
local gitDir=$(getGit)
local commit=$1
good ${T}
good ${gitDir}
test -z "${gitDir}" && die "未找到.git仓库"
local dir=${gitDir:${#T}+1}
good "${dir}"
git format-patch -1 --src-prefix="a/${dir}/" --dst-prefix="b/${dir}/" ${commit} # -o $OUT_DIR/$dir
}
#批量生成标准补丁文件,并且将补丁格式改变为适用git大仓库
function format_tag_patch(){
local last_tag=$1
local this_tag=$2
good "删除输出路径,重新创建"
rm -rf $OUT_DIR
mkdir -p $OUT_DIR
good "正在生成repo仓库下补丁"
local cur_dir=$(pwd)
for dir in $(cat .repo/project.list)
do
cd $dir
mkdir -p $OUT_DIR/$(dirname $dir)
#准确匹配tag生成patch
#git format-patch -k -p -b -w --src-prefix="a/${dir}/" --dst-prefix="b/${dir}/" ${last_tag}..${this_tag} -o $OUT_DIR/$dir
git format-patch --src-prefix="a/${dir}/" --dst-prefix="b/${dir}/" ${last_tag}..${this_tag} -o $OUT_DIR/$dir
#git format-patch ${last_tag}..${this_tag} -o $OUT_DIR/$dir
#git format-patch -s $tag_name -o $OUT_DIR/$dir
cd $cur_dir
done
unset dir
unset cur_dir
}
#主函数入口
function repo2git(){
local git_code="$1"
pushd . > /dev/null
cd $git_code
last_tag=$(git tag -l | tail -1 )
popd > /dev/null
isRepo
test -z $last_tag && die "没有获取到上一版的tag标志"
showTime
startTime=$?
good "CURRENT_DIR = $CUR_DIR"
#生成补丁
format_tag_patch $last_tag $THIS_TAG
good "总共生成了$(find $OUT_DIR -name "*.patch" -type f| wc -l)个patch文件"
good "总共生成了$(du -sh $OUT_DIR | awk '{print $1}' )"
#read -p "是否需要修改补丁内容,点击enter继续(取消请按ctrl+c)...."
#修改补丁内容,适配路径
#modify_format_patch
good "修改完成!"
#生成更新文件列表
get_tag_diff_list ${last_tag} ${THIS_TAG} 2>&1 | tee ${OUT_DIR}/update_list.txt
#将补丁打入git大仓库
read -p "是否需要将补丁打入仓库,点击enter继续(取消请按ctrl+c)...."
#打入补丁
git_apply_patch $git_code
showTime
endTime=$?
countTime=$(echo "$endTime-$startTime" |bc)
good "耗时:$countTime秒"
}
#同步更新repo代码
function repo_sync_code(){
isRepo
#同步代码
repo sync -c
#强制更新两次,避免出错导致代码提交结束,没有更新完成
repo sync -c
#判断成功
local reply
read -p "是否已经更新完成,确认后打入tag:[y/n]" reply
if [ "${reply}" = n ];then
good "repo forall -c git tag -a ${THIS_TAG} -m ${DATE}"
die "更新未成功."
fi
#打上今天日期的tag
repo forall -c git tag -a "${THIS_TAG}" -m "${DATE}"
#check tag是否完成
is_lose_tag ${THIS_TAG}
}
#参数获取区域
###################################################[main]###########################################################################################
ARGS=$(getopt -o b:h -al repo2git,init,sync,dos2unix,tag,format,patch,modify,apply,list,checkTag,test,help -- "$@")
[ $? -ne 0 ] && usage
eval set -- "${ARGS}"
#echo "caicai_debug: $@"
while true ;do
case "$1" in
--repo2git) vRepo2git="yes";;
#初始化第一次生成大git
--init) vInit="yes";;
#转码
--dos2unix) vDos2unix="yes";;
#同步代码
--sync) vSync="yes";;
#head or tail ##git push tag##
--tag) vTag="yes";;
#检查tag是否打全
--checkTag) vcheckTag="yes";;
#生成补丁
--format) vFormat="yes";;
#修改指定位置补丁
--patch) vPatch="yes";;
--modify) vModify="yes";;
#打入指定位置的补丁到指定位置
--apply) vApply="yes";;
#查看两个tag之间的提交
--list) vList="yes";;
#内调函数
--test) vTest="yes";;
-b) branch="$2";shift;;
-h|--help) usage_detail;;
--) arg1="$2"; arg2="$3"; arg3="$4"; break;;
esac
shift
done
#############################################################
#初始化变量
CUR_DIR=$(pwd)
OUT_DIR="$CUR_DIR/out_patch"
DATE=$(date +%Y%m%d)
THIS_TAG="ali_base_${DATE}"
#THIS_TAG="ali_base_20160531"
#############################################################
if [ "$vRepo2git" == "yes" -a -n "$arg1" ];then
#repo2git "$arg1" 2>&1 | tee ${OUT_DIR}/repo2git_log_${DATE}.txt #OUT目录还未生成
repo2git "$arg1"
exit 0
fi
if [ "$vSync" == "yes" ];then
repo_sync_code
exit 0
fi
if [ "$vInit" == "yes" ];then
repo2git_init
exit 0
fi
if [ "$vDos2unix" == "yes" -a -n "$arg1" ];then
change_from_dos "$arg1"
exit 0
fi
if [ "$vTag" == "yes" -a -n "$arg1" ];then
repo2git_tag "$arg1"
exit 0
fi
if [ "$vFormat" == "yes" -a -n "$arg1" ];then
if [ -z "$arg2" ];then
arg2=$THIS_TAG
fi
format_tag_patch "$arg1" "$arg2"
exit 0
fi
if [ "$vPatch" == "yes" -a -n "$arg1" ];then
format_commit_patch "$arg1"
exit 0
fi
if [ "$vModify" == "yes" ];then
modify_format_patch
exit 0
fi
if [ "$vApply" == "yes" -a -n "$arg1" ];then
git_apply_patch "$arg1"
exit 0
fi
if [ "$vcheckTag" == "yes" -a -n "$arg1" ];then
is_lose_tag "$arg1"
exit 0
fi
if [ "$vTest" == "yes" ];then
good "执行内调函数$@"
$arg1 $arg2 $arg3
exit 0
fi
if [ "$vList" == "yes" -a -n "$arg1" ];then
if [ -z "$arg2" ];then
arg2=$THIS_TAG
fi
get_tag_diff_list "$arg1" "$arg2"
exit 0
fi
#repo仓库 tag的转移
#get_commit_from_tag $tag > $file
#set_tag $THIS_TAG $file
usage
#######################################################################################################################################################
#1.流程:
#1.同步代码,打上当日同步日期的tag
#2.获取这次版本更新内容,并且保留列表,方便查看
#3.获取git仓库最后更新的内容,选择性更新repo的内容
#out_patch:
#1.两个tag之间的patch详情 get_tag_diff_list
#2.patch打入情况标识 project.list 和 success fail标识
#3.patch大小,个数统计,时间
#4.patch对应的commit标识
#5.repo的tag对应的commit_id list
#打完后保存out_patch为tag名称out_patch,以便后续查看
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )