parent
411aca8f82
commit
72587c6aa3
@ -0,0 +1,286 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 快速 Git 提交脚本
|
||||||
|
# 自动执行 git add . git commit -m 'update' git push
|
||||||
|
# 自动输入密码: Git@2018
|
||||||
|
|
||||||
|
PASSWORD="Git@2018"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# 查找所有 Git 仓库
|
||||||
|
find_git_repos() {
|
||||||
|
local current_dir="$1"
|
||||||
|
local repos=()
|
||||||
|
|
||||||
|
# 查找所有 .git 目录(包括当前目录和子目录,最多搜索 3 层深度)
|
||||||
|
while IFS= read -r -d '' git_dir; do
|
||||||
|
# 获取仓库根目录(去掉 .git 部分)
|
||||||
|
repo_path=$(dirname "$git_dir")
|
||||||
|
# 标准化路径(去除相对路径符号)
|
||||||
|
repo_path=$(cd "$repo_path" && pwd)
|
||||||
|
repos+=("$repo_path")
|
||||||
|
done < <(find "$current_dir" -maxdepth 3 -type d -name ".git" -print0 2>/dev/null)
|
||||||
|
|
||||||
|
# 去重并排序
|
||||||
|
printf '%s\n' "${repos[@]}" | sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行 Git 操作的函数
|
||||||
|
execute_git_operations() {
|
||||||
|
local repo_path="$1"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo "正在处理仓库: $repo_path"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 切换到仓库目录
|
||||||
|
cd "$repo_path" || {
|
||||||
|
echo "错误: 无法切换到目录 $repo_path"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行 git add .
|
||||||
|
echo "执行: git add ."
|
||||||
|
git add .
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "错误: git add 失败"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行 git commit
|
||||||
|
echo "执行: git commit -m 'update'"
|
||||||
|
git commit -m 'update'
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "警告: git commit 可能没有新的更改需要提交"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查是否有 expect 命令
|
||||||
|
if ! command -v expect &> /dev/null; then
|
||||||
|
echo ""
|
||||||
|
echo "错误: 未找到 expect 命令"
|
||||||
|
echo "请先安装 expect: brew install expect"
|
||||||
|
echo ""
|
||||||
|
echo "或者手动执行: git push"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 获取所有远程仓库
|
||||||
|
local remotes=($(git remote))
|
||||||
|
|
||||||
|
if [ ${#remotes[@]} -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "警告: 当前仓库没有配置远程仓库,跳过 push"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 获取当前分支名
|
||||||
|
local current_branch=$(git branch --show-current)
|
||||||
|
if [ -z "$current_branch" ]; then
|
||||||
|
current_branch="master"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 选择远程仓库
|
||||||
|
local selected_remote=""
|
||||||
|
if [ ${#remotes[@]} -eq 1 ]; then
|
||||||
|
# 只有一个远程仓库,直接使用
|
||||||
|
selected_remote="${remotes[0]}"
|
||||||
|
echo ""
|
||||||
|
echo "检测到 1 个远程仓库: $selected_remote"
|
||||||
|
else
|
||||||
|
# 多个远程仓库,让用户选择
|
||||||
|
echo ""
|
||||||
|
echo "检测到 ${#remotes[@]} 个远程仓库:"
|
||||||
|
echo ""
|
||||||
|
for i in "${!remotes[@]}"; do
|
||||||
|
local_index=$((i + 1))
|
||||||
|
local remote_url=$(git remote get-url "${remotes[$i]}")
|
||||||
|
echo " [$local_index] ${remotes[$i]} ($remote_url)"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 读取用户选择
|
||||||
|
while true; do
|
||||||
|
read -p "请选择要推送的远程仓库编号 (1-${#remotes[@]}): " choice
|
||||||
|
|
||||||
|
# 检查输入是否为数字
|
||||||
|
if ! [[ "$choice" =~ ^[0-9]+$ ]]; then
|
||||||
|
echo "错误: 请输入有效的数字"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 处理选择
|
||||||
|
if [ "$choice" -ge 1 ] && [ "$choice" -le ${#remotes[@]} ]; then
|
||||||
|
selected_remote="${remotes[$((choice - 1))]}"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "错误: 请输入 1-${#remotes[@]} 之间的数字"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行 git push 的函数
|
||||||
|
do_git_push() {
|
||||||
|
local password="$1"
|
||||||
|
local remote="$2"
|
||||||
|
local branch="$3"
|
||||||
|
local temp_output=$(mktemp)
|
||||||
|
local push_failed=0
|
||||||
|
|
||||||
|
# 使用 tee 同时输出到终端和文件,以便后续检查错误
|
||||||
|
expect << EOF 2>&1 | tee "$temp_output"
|
||||||
|
set timeout 30
|
||||||
|
spawn git push $remote $branch
|
||||||
|
expect {
|
||||||
|
"Password:" {
|
||||||
|
send "$password\r"
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
"password:" {
|
||||||
|
send "$password\r"
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
"passphrase:" {
|
||||||
|
send "$password\r"
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
"Username:" {
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
"Authentication failed" {
|
||||||
|
set push_failed 1
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
"Permission denied" {
|
||||||
|
set push_failed 1
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
eof {
|
||||||
|
catch wait result
|
||||||
|
set exit_code [lindex \$result 3]
|
||||||
|
if {\$exit_code != 0} {
|
||||||
|
set push_failed 1
|
||||||
|
}
|
||||||
|
exit \$exit_code
|
||||||
|
}
|
||||||
|
timeout {
|
||||||
|
set push_failed 1
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
local exit_code=$?
|
||||||
|
local output=$(cat "$temp_output" 2>/dev/null)
|
||||||
|
rm -f "$temp_output"
|
||||||
|
|
||||||
|
# 检查退出码和输出中的错误信息
|
||||||
|
if [ $exit_code -ne 0 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查输出中是否包含认证失败相关的错误
|
||||||
|
if echo "$output" | grep -qiE "(Authentication failed|Permission denied|fatal:.*authentication|error:.*authentication)"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 首先尝试使用默认密码
|
||||||
|
echo ""
|
||||||
|
echo "执行: git push $selected_remote $current_branch (使用默认密码)"
|
||||||
|
if do_git_push "$PASSWORD" "$selected_remote" "$current_branch"; then
|
||||||
|
echo ""
|
||||||
|
echo "✅ 仓库 $repo_path 提交完成!"
|
||||||
|
else
|
||||||
|
# 默认密码失败,提示用户输入密码
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ 默认密码 push 失败,请手动输入密码"
|
||||||
|
echo ""
|
||||||
|
read -sp "请输入 Git 密码: " user_password
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "使用您输入的密码重新执行: git push $selected_remote $current_branch"
|
||||||
|
|
||||||
|
if do_git_push "$user_password" "$selected_remote" "$current_branch"; then
|
||||||
|
echo ""
|
||||||
|
echo "✅ 仓库 $repo_path 提交完成!"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "❌ 仓库 $repo_path push 失败,请检查密码和网络连接"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主程序
|
||||||
|
echo "开始执行 Git 快速提交..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 查找所有 Git 仓库
|
||||||
|
echo "正在查找 Git 仓库..."
|
||||||
|
repos=($(find_git_repos "$SCRIPT_DIR"))
|
||||||
|
|
||||||
|
if [ ${#repos[@]} -eq 0 ]; then
|
||||||
|
echo "错误: 未找到任何 Git 仓库"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 如果只有一个仓库,直接执行
|
||||||
|
if [ ${#repos[@]} -eq 1 ]; then
|
||||||
|
echo "找到 1 个 Git 仓库:"
|
||||||
|
echo " [1] ${repos[0]}"
|
||||||
|
echo ""
|
||||||
|
execute_git_operations "${repos[0]}"
|
||||||
|
else
|
||||||
|
# 多个仓库,让用户选择
|
||||||
|
echo "找到 ${#repos[@]} 个 Git 仓库:"
|
||||||
|
echo ""
|
||||||
|
for i in "${!repos[@]}"; do
|
||||||
|
local_index=$((i + 1))
|
||||||
|
echo " [$local_index] ${repos[$i]}"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo " [0] 全部执行"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 读取用户选择
|
||||||
|
while true; do
|
||||||
|
read -p "请选择要操作的仓库编号 (0-${#repos[@]}): " choice
|
||||||
|
|
||||||
|
# 检查输入是否为数字
|
||||||
|
if ! [[ "$choice" =~ ^[0-9]+$ ]]; then
|
||||||
|
echo "错误: 请输入有效的数字"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 处理选择
|
||||||
|
if [ "$choice" -eq 0 ]; then
|
||||||
|
# 全部执行
|
||||||
|
echo ""
|
||||||
|
echo "将执行所有仓库的操作..."
|
||||||
|
for repo in "${repos[@]}"; do
|
||||||
|
execute_git_operations "$repo"
|
||||||
|
done
|
||||||
|
break
|
||||||
|
elif [ "$choice" -ge 1 ] && [ "$choice" -le ${#repos[@]} ]; then
|
||||||
|
# 执行选中的仓库
|
||||||
|
selected_repo="${repos[$((choice - 1))]}"
|
||||||
|
execute_git_operations "$selected_repo"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "错误: 请输入 0-${#repos[@]} 之间的数字"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo "所有操作完成!"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
Loading…
Reference in new issue