本文目录导读:

我来提供一个自动更新代码仓库的Shell脚本,支持Git和SVN两种版本控制系统。
Git仓库自动更新脚本
#!/bin/bash
# Git仓库自动更新脚本
# 用法: ./auto_update_git.sh [仓库路径]
# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 默认配置
REPO_PATH="${1:-.}" # 默认当前目录
LOG_FILE="/var/log/repo_update.log"
MAX_RETRIES=3
RETRY_DELAY=5
# 日志函数
log_message() {
local level=$1
local message=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
case $level in
"INFO") echo -e "[${timestamp}] [${GREEN}INFO${NC}] ${message}" ;;
"WARN") echo -e "[${timestamp}] [${YELLOW}WARN${NC}] ${message}" ;;
"ERROR") echo -e "[${timestamp}] [${RED}ERROR${NC}] ${message}" ;;
esac
# 写入日志文件
echo "[${timestamp}] [${level}] ${message}" >> "$LOG_FILE"
}
# 错误处理
handle_error() {
local error_msg=$1
log_message "ERROR" "$error_msg"
exit 1
}
# 检查Git是否安装
check_git() {
if ! command -v git &> /dev/null; then
handle_error "Git is not installed"
fi
}
# 检查是否是Git仓库
check_repo() {
if [ ! -d "$REPO_PATH/.git" ]; then
handle_error "Not a Git repository: $REPO_PATH"
fi
}
# 获取当前分支
get_current_branch() {
git symbolic-ref --short HEAD 2>/dev/null || echo "HEAD"
}
# 备份未提交的更改
backup_changes() {
local stash_name="auto_update_backup_$(date +%Y%m%d_%H%M%S)"
if ! git diff --quiet || ! git diff --cached --quiet; then
log_message "WARN" "Local changes found, stashing changes as: ${stash_name}"
git stash push -u -m "$stash_name" || handle_error "Failed to stash changes"
log_message "INFO" "Changes stashed successfully"
return 0
fi
return 1
}
# 拉取最新代码
pull_latest() {
local branch=$(get_current_branch)
log_message "INFO" "Pulling latest changes for branch: ${branch}"
for ((i=1; i<=MAX_RETRIES; i++)); do
if git pull --rebase origin "$branch" 2>&1; then
log_message "INFO" "Successfully pulled latest changes"
return 0
else
if [ $i -lt $MAX_RETRIES ]; then
log_message "WARN" "Pull failed (attempt $i/$MAX_RETRIES), retrying in ${RETRY_DELAY}s..."
sleep $RETRY_DELAY
else
handle_error "Failed to pull changes after $MAX_RETRIES attempts"
fi
fi
done
}
# 更新子模块
update_submodules() {
if [ -f .gitmodules ]; then
log_message "INFO" "Updating submodules..."
git submodule update --init --recursive 2>&1 || log_message "WARN" "Failed to update some submodules"
fi
}
# 清理无用分支
clean_branches() {
log_message "INFO" "Cleaning up local branches..."
git fetch --prune 2>&1 | while read -r line; do
log_message "INFO" "Pruned: $line"
done
}
# 恢复stash(如果有)
restore_stash() {
if git stash list | grep -q "auto_update_backup"; then
log_message "INFO" "Restoring stashed changes..."
git stash pop 2>&1 || log_message "WARN" "Failed to restore stashed changes"
fi
}
# 发送通知
send_notification() {
local status=$1
local message=$2
# 示例:使用curl发送Slack通知
# SLACK_WEBHOOK_URL="your_webhook_url"
# curl -X POST -H 'Content-type: application/json' \
# --data "{\"text\":\"[${status}] ${message}\"}" \
# $SLACK_WEBHOOK_URL
# 示例:发送邮件(需要配置邮件工具)
# echo "$message" | mail -s "Git Auto Update: $status" admin@example.com
log_message "INFO" "Notification sent with status: $status"
}
# 主函数
main() {
log_message "INFO" "=== Starting Git repository auto-update ==="
log_message "INFO" "Repository path: $REPO_PATH"
# 切换到仓库目录
cd "$REPO_PATH" || handle_error "Cannot access repository: $REPO_PATH"
# 执行检查
check_git
check_repo
# 记录开始时间
START_TIME=$(date +%s)
# 获取当前状态
CURRENT_BRANCH=$(get_current_branch)
log_message "INFO" "Current branch: ${CURRENT_BRANCH}"
# 备份本地更改
backup_changes
# 拉取最新代码
pull_latest
# 更新子模块
update_submodules
# 清理分支
clean_branches
# 恢复stash
restore_stash
# 计算执行时间
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
log_message "INFO" "=== Update completed successfully in ${DURATION}s ==="
# 发送成功通知
send_notification "SUCCESS" "Git repository updated successfully (${DURATION}s)"
}
# 执行主函数
main
# 使用示例:
# 1. 更新当前目录的仓库
# ./auto_update_git.sh
# 2. 更新指定路径的仓库
# ./auto_update_git.sh /path/to/your/repo
# 3. 添加到crontab(每天凌晨2点执行)
# 0 2 * * * /path/to/auto_update_git.sh /path/to/your/repo
SVN仓库自动更新脚本
#!/bin/bash
# SVN仓库自动更新脚本
# 用法: ./auto_update_svn.sh [仓库路径]
# 配置
REPO_PATH="${1:-.}"
SVN_USER="your_username" # SVN用户名
SVN_PASS="your_password" # SVN密码(建议使用密钥认证)
LOG_FILE="/var/log/svn_update.log"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 日志函数
log_message() {
local level=$1
local message=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
case $level in
"INFO") echo -e "[${timestamp}] [${GREEN}INFO${NC}] ${message}" ;;
"WARN") echo -e "[${timestamp}] [${YELLOW}WARN${NC}] ${message}" ;;
"ERROR") echo -e "[${timestamp}] [${RED}ERROR${NC}] ${message}" ;;
esac
echo "[${timestamp}] [${level}] ${message}" >> $LOG_FILE
}
# 检查SVN是否安装
check_svn() {
if ! command -v svn &> /dev/null; then
log_message "ERROR" "SVN is not installed"
exit 1
fi
}
# 检查是否是SVN工作副本
check_working_copy() {
if [ ! -d "$REPO_PATH/.svn" ]; then
log_message "ERROR" "Not a SVN working copy: $REPO_PATH"
exit 1
fi
}
# 更新SVN仓库
update_svn_repo() {
local svn_opts=""
if [ -n "$SVN_USER" ] && [ -n "$SVN_PASS" ]; then
svn_opts="--username $SVN_USER --password $SVN_PASS --non-interactive"
fi
log_message "INFO" "Updating SVN repository: $REPO_PATH"
# 先检查状态
svn status $svn_opts 2>&1 | while read -r line; do
if [[ $line == \?* ]]; then
log_message "WARN" "Untracked file: ${line:8}"
fi
done
# 执行更新
if svn update $svn_opts "$REPO_PATH" 2>&1; then
log_message "INFO" "SVN repository updated successfully"
# 显示当前版本
local revision=$(svn info --show-item revision $svn_opts "$REPO_PATH" 2>/dev/null)
log_message "INFO" "Current revision: $revision"
else
log_message "ERROR" "Failed to update SVN repository"
exit 1
fi
}
# 清理SVN工作副本
cleanup_svn() {
log_message "INFO" "Cleaning up SVN working copy..."
svn cleanup "$REPO_PATH" 2>&1 || log_message "WARN" "Cleanup failed"
}
# 主函数
main() {
log_message "INFO" "=== Starting SVN repository auto-update ==="
check_svn
check_working_copy
cleanup_svn
update_svn_repo
log_message "INFO" "=== SVN update completed ==="
}
# 执行主函数
main
使用说明
-
设置执行权限:
chmod +x auto_update_git.sh chmod +x auto_update_svn.sh
-
配置crontab定时任务:
# 编辑crontab crontab -e
添加以下配置(示例)
每天凌晨2点更新
0 2 * /path/to/auto_update_git.sh /path/to/your/repo
每隔30分钟更新
/30 * /path/to/auto_update_git.sh /path/to/your/repo
工作日每4小时更新
0 /4 * 1-5 /path/to/auto_update_git.sh /path/to/your/repo
3. **使用systemd服务**(Linux):
```ini
# /etc/systemd/system/repo-update.service
[Unit]
Description=Repository Auto Update Service
After=network.target
[Service]
Type=oneshot
ExecStart=/path/to/auto_update_git.sh /path/to/your/repo
User=your_user
[Install]
WantedBy=multi-user.target
- 配置告警通知:
- 可以集成Slack、钉钉、邮件等通知
- 修改
send_notification函数配置webhook
这个脚本提供了完整的自动更新功能,包括错误处理、日志记录和通知机制,可以根据实际需求进行定制。