shell脚本实现git草稿功能
git是个很强大的代码管理工具,提供了版本回溯的功能,在切换不同设备时,使用git同步代码十分方便,然而,有时会需要临时切换到其他设备继续写代码,这种情况的提交往往十分碍眼,因为正在写的某个模块可能只写到一半。因此,在上一次写代码的时候,我没有使用git管理代码,直接使用容器,打算最后完成之后再上传到git服务器,结果,容器挂了,代码没了。
为了避免再次发生这个问题,我决定重新使用git管理代码,同时,为了避免提交过于混乱,我写了一个简单的shell脚本,实现了草稿的功能。
并且在写完之后,发现github的merge就有将多次提交合并为一次提交的功能,算是重复造轮子了。但是merge里的依然会保留原来错乱的提交记录(仍然可以找到),所以我依然写下这篇文章来分享这个工具。
需求分析及功能设计
- 提交混乱的问题:
采用draft和finalization两个仓库,其中draft是代码编辑区,一般在draft下编写代码,临时提交只需提交到draft仓库即可,某次工作结束后,再将draft的更改同步到finalization中(仅同步文件内容,不同步提交记录)。
- 环境检测:
必须要用到的程序是git,因此在程序运行时,需要检测git是否已安装,根据命令的不同,还需要确定draft和finalization是不是一个git仓库。
核心功能代码实现
环境检测
-
声明三个变量记录环境检测的结果。
check1=0 # git的安装情况 check2=0 # draft的情况 check3=0 # finalization的情况
-
检测git是否已安装
if [[ -x "$(command -v git)" ]] # 如果已安装git,command -v git会输出一个文件路径,-x判断输出的路径是否是一个可执行文件,如果是的话,那么git已安装。 then echo "$(git version)" else echo -e "\033[35mmissing git!\033[0m" check1=1 fi
-
检测工作区是否符合要求
为了节省内存,兼顾可读性, 只需要用一个变量来存储文件夹的情况就行了,check2二进制最低位表示目录是否存在,次低位表示是否为git仓库,那么check2的值在0时对应正常,1对应不存在此目录,2对应此目录不是git仓库。
if [[ -d draft ]] # 先判断draft目录是否存在 then echo "directory draft exit" cd draft if [[ $check1 = 1 ]] then echo -e "\033[35mdraft cannot be judged as a git repo because git is missing!\033[0m" elif [[ $(git rev-parse --is-inside-work-tree) ]] then echo "draft is a git repo." else echo -e "\033[35mdraft is not a git repo!\033[0m" check2=$[check2+2] fi cd .. else echo -e "\033[35mmissing directory draft!\033[0m" check2=$[check2+1] fi
finalization同理
提交draft到finalization
保存草稿
cd draft
git add * && git commit -a -m "auto commit by project manager"
git push --all origin
cd ..
提交到finalization
cp -r ./draft/* ./finalization/
处理工作区
除了核心功能外,还需要考虑迁移工作的需要,如刚开始一个新项目,或者在其他机器继续工作。
初始化工作区
git init draft
git init finalization
克隆工作区
read -p "please input draft repo: " draft_repo_url draft
read -p "please input finalization repo: " finalization_repo_url finalization
git clone $draft_repo_url
git clone $finalization_repo_url
拉取工作区的代码
cd draft
git fetch
git pull
cd ../finalization
git fetch
git pull
cd ..
完整代码
将上述核心功能用case-in语句书写,加上防错输入措施,写成一下的完整程序。
#!/bin/bash
check1=0
check2=0
check3=0
if [[ -x "$(command -v git)" ]]
then
echo "$(git version)"
else
echo -e "\033[35mmissing git!\033[0m"
check1=1
fi
if [[ -d draft ]]
then
echo "directory draft exit"
cd draft
if [[ $check1 = 1 ]]
then
echo -e "\033[35mdraft cannot be judged as a git repo because git is missing!\033[0m"
elif [[ $(git rev-parse --is-inside-work-tree) ]]
then
echo "draft is a git repo."
else
echo -e "\033[35mdraft is not a git repo!\033[0m"
check2=$[check2+2]
fi
cd ..
else
echo -e "\033[35mmissing directory draft!\033[0m"
check2=$[check2+1]
fi
if [[ -d finalization ]]
then
echo "directory finalization exit"
cd finalization
if [[ $check1 == 1 ]]
then
echo -e "\033[35mfinalization cannot be judged as a git repo because git is missing!\033[0m"
elif [[ $(git rev-parse --is-inside-work-tree) ]]
then
echo "finalization is a git repo."
else
echo -e "\033[35mfinalization is not a git repo!\033[0m"
check3=$[check3+2]
fi
cd ..
else
echo -e "\033[35mmissing directory finalization!\033[0m"
check3=$[check3+1]
fi
if [[ "$1" == "test" ]]
then
if [[ $[check1+check2+check3] == 0 ]]
then
echo -e "\033[32mtest passed !!!\033[0m"
else
echo -e "\033[31mtest failed !!!\033[0m"
fi
exit 0
elif [[ $check1 == 1 ]]
then
echo -e "\033[31m[error 1]: missing git.\033[0m"
exit 1
fi
case $1 in
init|\-i)
git init draft
git init finalization
;;
clone)
read -p "please input draft repo: " draft_repo_url draft
read -p "please input finalization repo: " finalization_repo_url finalization
git clone $draft_repo_url
git clone $finalization_repo_url
;;
config)
case $2 in
draft)
cd draft
git remote add origin $3
cd ..
;;
finalization)
cd finalization
git remote add origin $3
cd ..
;;
esac
;;
pull|\-p)
if [[ [$check2%2] == 1 ]]
then
echo -e "\033[31mderetory draft doesn't exist!\033[0m"
elif [[ $check2 -ge 2 ]]
then
echo -e "\033[31mdraft is not a git repo!\033[0m"
else
cd draft
git fetch
git pull
fi
if [[ [$check3%2] == 1 ]]
then
echo -e "\033[31mderetory finalization doesn't exist!\033[0m"
elif [[ $check3 -ge 2 ]]
then
echo -e "\033[31mfinalization is not a git repo!\033[0m"
else
cd ../finalization
git fetch
git pull
cd ..
fi
;;
draft|\-d) # to finish if and fi
if [[ [$check2%2] == 1 ]]
then
echo -e "\033[31mderetory draft doesn't exist!\033[0m"
elif [[ $check2 -ge 2 ]]
then
echo -e "\033[31mdraft is not a git repo!\033[0m"
else
echo "project manager is saving draft!"
cd draft
git add * && git commit -a -m "auto commit by project manager"
git push --all origin
cd ..
fi
;;
finalization|\-f)
if [[ [$check3%2] == 1 ]]
then
echo -e "\033[31mderetory finalization doesn't exist!\033[0m"
else
echo "project manager is saving publish"
cp -r ./draft/* ./finalization/
fi
;;
"")
echo -e "\033[31mmissing operation\033[0m"
;;
*)
echo "invalid operation!"
exit 1
;;
esac