90 lines
3.4 KiB
Bash
Executable File
90 lines
3.4 KiB
Bash
Executable File
#!/bin/bash
|
||
# ============================================================
|
||
# 脚本名称: git-force-push.sh
|
||
# 功能描述: 将本地分支强制推送到远程,让远程与本地完全一致
|
||
# 使用场景: 本地代码正确,远程有错误或需强制更新
|
||
# 安全机制: 默认使用 --force-with-lease,并检查远程新提交
|
||
# ============================================================
|
||
|
||
set -e
|
||
|
||
# ---------- 颜色 ----------
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# ---------- 1. 检查是否在 Git 仓库 ----------
|
||
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
|
||
echo -e "${RED}错误:当前目录不是 Git 仓库${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
# ---------- 2. 获取当前分支 ----------
|
||
CURRENT_BRANCH=$(git branch --show-current)
|
||
if [ -z "$CURRENT_BRANCH" ]; then
|
||
echo -e "${RED}错误:当前处于 HEAD 分离状态,请先切换到具体分支。${NC}"
|
||
exit 1
|
||
fi
|
||
echo -e "${BLUE}当前分支:${CURRENT_BRANCH}${NC}"
|
||
|
||
# ---------- 3. 先拉取远程最新信息(但不会合并) ----------
|
||
echo -e "${BLUE}正在获取远程最新引用...${NC}"
|
||
git fetch origin
|
||
|
||
# ---------- 4. 检查本地是否有未提交的更改 ----------
|
||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||
echo -e "${YELLOW}⚠️ 检测到本地有未提交的更改(已暂存或未暂存)。${NC}"
|
||
echo -e "${YELLOW}这些更改不会被推送,但会保留在工作区。${NC}"
|
||
read -p "是否继续强制推送?(y/N) " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
echo -e "${GREEN}操作已取消。${NC}"
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
# ---------- 5. 检查本地是否落后于远程(存在远程新提交) ----------
|
||
LOCAL_COMMIT=$(git rev-parse @)
|
||
REMOTE_COMMIT=$(git rev-parse @{u} 2>/dev/null || echo "")
|
||
if [ -z "$REMOTE_COMMIT" ]; then
|
||
echo -e "${YELLOW}⚠️ 当前分支未设置上游,将使用 --set-upstream 建立跟踪。${NC}"
|
||
fi
|
||
BEHIND=$(git rev-list --count @{u}..@ 2>/dev/null || echo "0")
|
||
AHEAD=$(git rev-list --count @..@{u} 2>/dev/null || echo "0")
|
||
|
||
if [ "$AHEAD" -gt 0 ]; then
|
||
echo -e "${YELLOW}⚠️ 远程有 $AHEAD 个新提交,本地落后于远程。${NC}"
|
||
echo -e "${YELLOW}强制推送会覆盖这些提交,请确认这不是他人刚提交的代码!${NC}"
|
||
fi
|
||
|
||
# ---------- 6. 选择强制推送模式 ----------
|
||
echo -e "${BLUE}请选择推送模式:${NC}"
|
||
echo " 1) --force-with-lease (推荐,安全覆盖,会检查远程是否有未知新提交)"
|
||
echo " 2) --force (强制覆盖,忽略远程所有内容,极度危险)"
|
||
read -p "请输入数字 (1 或 2,默认 1): " MODE
|
||
MODE=${MODE:-1}
|
||
|
||
if [ "$MODE" = "2" ]; then
|
||
FORCE_FLAG="--force"
|
||
echo -e "${RED}您选择了 --force,这将无条件覆盖远程分支!${NC}"
|
||
else
|
||
FORCE_FLAG="--force-with-lease"
|
||
echo -e "${GREEN}您选择了 --force-with-lease,安全模式。${NC}"
|
||
fi
|
||
|
||
# ---------- 7. 最终确认 ----------
|
||
read -p "确认将本地分支 '$CURRENT_BRANCH' 强制推送到远程?请输入 'yes' 继续: " CONFIRM
|
||
if [ "$CONFIRM" != "yes" ]; then
|
||
echo -e "${GREEN}操作已取消。${NC}"
|
||
exit 0
|
||
fi
|
||
|
||
# ---------- 8. 执行推送 ----------
|
||
echo -e "${BLUE}正在执行: git push $FORCE_FLAG origin $CURRENT_BRANCH${NC}"
|
||
git push $FORCE_FLAG origin $CURRENT_BRANCH
|
||
|
||
# ---------- 9. 结果反馈 ----------
|
||
echo -e "${GREEN}✅ 推送完成!远程 'origin/$CURRENT_BRANCH' 已与本地保持一致。${NC}"
|