238 行
5.8 KiB
Bash
可执行文件
238 行
5.8 KiB
Bash
可执行文件
#!/bin/bash
|
|
# sync-gitea.sh - 自动同步到 Gitea 仓库
|
|
#
|
|
# 用法:
|
|
# ./sync-gitea.sh # 正常提交和推送
|
|
# ./sync-gitea.sh --init # 初始化仓库
|
|
# ./sync-gitea.sh --commit # 仅提交
|
|
# ./sync-gitea.sh --push # 仅推送
|
|
|
|
set -euo pipefail
|
|
|
|
# 配置
|
|
REPO_DIR="/Users/x/websafe"
|
|
GITEA_URL="https://git.hk.hao.work"
|
|
GITEA_API="${GITEA_URL}/api/v1"
|
|
REPO_NAME="${REPO_NAME:-websafe-kb}"
|
|
REPO_DESC="${REPO_DESC:-授权攻防实验与研究知识库}"
|
|
GITEA_TOKEN="${GITEA_TOKEN:-}"
|
|
GIT_USER="${GIT_USER:-hao}"
|
|
GIT_EMAIL="${GIT_EMAIL:-hao@users.noreply.git.hk.hao.work}"
|
|
|
|
cd "$REPO_DIR"
|
|
|
|
# 颜色定义
|
|
RED='\033[91m'
|
|
GREEN='\033[92m'
|
|
YELLOW='\033[93m'
|
|
BLUE='\033[94m'
|
|
END='\033[0m'
|
|
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${END} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${END} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${END} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${END} $1"
|
|
}
|
|
|
|
repo_api_url() {
|
|
echo "${GITEA_API}/repos/${GIT_USER}/${REPO_NAME}"
|
|
}
|
|
|
|
repo_git_url() {
|
|
echo "${GITEA_URL}/${GIT_USER}/${REPO_NAME}.git"
|
|
}
|
|
|
|
ensure_remote_repo() {
|
|
if curl -fsS ${GITEA_TOKEN:+-H} ${GITEA_TOKEN:+"Authorization: token ${GITEA_TOKEN}"} "$(repo_api_url)" >/dev/null 2>&1; then
|
|
log_info "远程仓库已存在: ${GIT_USER}/${REPO_NAME}"
|
|
return 0
|
|
fi
|
|
|
|
if [ -z "$GITEA_TOKEN" ]; then
|
|
log_error "远程仓库不存在,且未提供 GITEA_TOKEN,无法自动创建"
|
|
return 1
|
|
fi
|
|
|
|
log_info "创建远程仓库: ${GIT_USER}/${REPO_NAME}"
|
|
local payload
|
|
payload=$(cat <<EOF
|
|
{"name":"${REPO_NAME}","description":"${REPO_DESC}","private":false,"auto_init":false}
|
|
EOF
|
|
)
|
|
curl -fsS -X POST \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$payload" \
|
|
"${GITEA_API}/user/repos" >/dev/null
|
|
log_success "远程仓库创建完成"
|
|
}
|
|
|
|
# 初始化仓库
|
|
init_repo() {
|
|
log_info "初始化 Git 仓库..."
|
|
|
|
if [ -d ".git" ]; then
|
|
log_warning "Git 仓库已存在"
|
|
else
|
|
git init
|
|
git config user.name "$GIT_USER"
|
|
git config user.email "$GIT_EMAIL"
|
|
log_success "Git 仓库初始化完成"
|
|
fi
|
|
|
|
# 添加远程仓库
|
|
if git remote | grep -q "origin"; then
|
|
git remote set-url origin "$(repo_git_url)"
|
|
log_info "远程仓库 URL 已更新"
|
|
else
|
|
git remote add origin "$(repo_git_url)"
|
|
log_success "远程仓库已添加"
|
|
fi
|
|
|
|
ensure_remote_repo
|
|
|
|
# 凭证处理:
|
|
# 默认不在仓库脚本中写入真实凭证。
|
|
# 如需使用 token,请在运行时通过环境变量 GITEA_TOKEN 注入,
|
|
# 推送时通过临时 HTTP Header 使用,不写入仓库或全局凭证文件。
|
|
if [ -n "$GITEA_TOKEN" ]; then
|
|
log_info "检测到 GITEA_TOKEN 环境变量,将在推送时临时注入 HTTP Header"
|
|
else
|
|
log_warning "未提供 GITEA_TOKEN;推送时将使用本机已有认证方式"
|
|
fi
|
|
|
|
log_success "初始化完成"
|
|
}
|
|
|
|
# 提交更改
|
|
commit_changes() {
|
|
log_info "检查更改..."
|
|
|
|
# 添加所有文件
|
|
git add -A
|
|
|
|
# 检查是否有更改
|
|
if git diff --staged --quiet; then
|
|
log_info "没有需要提交的更改"
|
|
return 0
|
|
fi
|
|
|
|
# 生成提交信息
|
|
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
local changed_files=$(git diff --staged --name-only | wc -l | tr -d ' ')
|
|
local commit_msg="更新: ${changed_files} 个文件 - ${timestamp}"
|
|
|
|
# 如果提供了自定义提交信息
|
|
if [ -n "$1" ]; then
|
|
commit_msg="$1"
|
|
fi
|
|
|
|
git commit -m "$commit_msg"
|
|
log_success "提交完成: $commit_msg"
|
|
}
|
|
|
|
# 推送到远程
|
|
push_changes() {
|
|
log_info "推送到远程仓库..."
|
|
|
|
# 获取当前分支
|
|
local branch=$(git branch --show-current 2>/dev/null || echo "main")
|
|
|
|
# 如果分支为空,使用 main
|
|
if [ -z "$branch" ]; then
|
|
branch="main"
|
|
fi
|
|
|
|
ensure_remote_repo
|
|
|
|
# 推送
|
|
if [ -n "$GITEA_TOKEN" ]; then
|
|
git -c http.extraHeader="Authorization: token ${GITEA_TOKEN}" push -u origin "$branch"
|
|
else
|
|
git push -u origin "$branch"
|
|
fi
|
|
if [ $? -eq 0 ]; then
|
|
log_success "推送完成: $branch"
|
|
else
|
|
log_error "推送失败"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# 完整同步
|
|
full_sync() {
|
|
init_repo
|
|
commit_changes
|
|
push_changes
|
|
}
|
|
|
|
# 显示帮助
|
|
show_help() {
|
|
echo "用法: $0 [选项]"
|
|
echo ""
|
|
echo "选项:"
|
|
echo " --init 初始化 Git 仓库"
|
|
echo " --commit 仅提交更改"
|
|
echo " --push 仅推送到远程"
|
|
echo " --ensure 检查远程仓库;不存在则创建"
|
|
echo " --status 显示仓库状态"
|
|
echo " --help 显示此帮助"
|
|
echo ""
|
|
echo "环境变量:"
|
|
echo " GITEA_TOKEN 可选;脚本不会自动写入 ~/.git-credentials"
|
|
echo " GIT_USER 可选;默认 hao"
|
|
echo " GIT_EMAIL 可选;默认 hao@users.noreply.git.hk.hao.work"
|
|
echo " REPO_NAME 可选;默认 websafe-kb"
|
|
echo " REPO_DESC 可选;默认 授权攻防实验与研究知识库"
|
|
echo ""
|
|
echo "无参数运行时执行完整同步 (提交 + 推送)"
|
|
}
|
|
|
|
# 显示状态
|
|
show_status() {
|
|
log_info "仓库状态:"
|
|
echo ""
|
|
git status -s
|
|
echo ""
|
|
|
|
local ahead=$(git rev-list --count @{upstream}..HEAD 2>/dev/null || echo "0")
|
|
local behind=$(git rev-list --count HEAD..@{upstream} 2>/dev/null || echo "0")
|
|
|
|
log_info "领先远程 $ahead 个提交, 落后 $behind 个提交"
|
|
}
|
|
|
|
# 主程序
|
|
case "${1:-}" in
|
|
--init)
|
|
init_repo
|
|
;;
|
|
--commit)
|
|
commit_changes "$2"
|
|
;;
|
|
--push)
|
|
push_changes
|
|
;;
|
|
--ensure)
|
|
init_repo
|
|
;;
|
|
--status)
|
|
show_status
|
|
;;
|
|
--help|-h)
|
|
show_help
|
|
;;
|
|
*)
|
|
full_sync
|
|
;;
|
|
esac
|