git 推送大文件 repo

看一下我的效果

image-20250310233801870

我的需求:我想要阅读 Linux 源码,使用 git 管理我阅读的 Linux 源码,使用我自建的 gitlab 保存我阅读的源码。然后发现简单的 git push 一个 2GB 的 linux 源码文件会出现问题。

所以我就写了个脚本以期来解决这个问题。

脚本内容如下:

#!/bin/bash
# 配置参数(请根据需要修改)
REMOTE_NAME="origin" # 远程仓库名称
BRANCH_NAME="main" # 目标分支名
REMOTE_URL="git@gitlab.cheverjohn.me:CheverJohn/linux.git" # 远程仓库地址
BATCH_SIZE=500 # 每批文件数量
COMMIT_MESSAGE="批量上传文件" # 提交信息
# 颜色配置
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色
# 检查是否在git仓库中
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo -e "${YELLOW}当前目录不是git仓库,正在初始化...${NC}"
git init
echo -e "${GREEN}Git仓库已初始化${NC}"
else
echo -e "${GREEN}Git仓库已存在${NC}"
fi
# 检查远程仓库是否已配置
if ! git remote | grep -q "$REMOTE_NAME"; then
echo -e "${YELLOW}添加远程仓库 $REMOTE_NAME: $REMOTE_URL${NC}"
git remote add $REMOTE_NAME $REMOTE_URL
echo -e "${GREEN}远程仓库已添加${NC}"
else
CURRENT_URL=$(git remote get-url $REMOTE_NAME 2>/dev/null || echo "")
if [ "$CURRENT_URL" != "$REMOTE_URL" ]; then
echo -e "${YELLOW}更新远程仓库URL: $REMOTE_URL${NC}"
git remote set-url $REMOTE_NAME $REMOTE_URL
echo -e "${GREEN}远程仓库URL已更新${NC}"
else
echo -e "${GREEN}远程仓库已正确配置${NC}"
fi
fi
# 确保主分支存在
if ! git show-ref --quiet refs/heads/$BRANCH_NAME; then
echo -e "${YELLOW}创建分支 $BRANCH_NAME...${NC}"
git checkout -b $BRANCH_NAME
echo -e "${GREEN}分支 $BRANCH_NAME 已创建${NC}"
else
echo -e "${GREEN}分支 $BRANCH_NAME 已存在${NC}"
git checkout $BRANCH_NAME
fi
# 获取所有未跟踪和已修改的文件
echo -e "${BLUE}获取待上传的文件列表...${NC}"
FILES=($(git ls-files --others --exclude-standard) $(git diff --name-only))
TOTAL_FILES=${#FILES[@]}
if [ $TOTAL_FILES -eq 0 ]; then
echo -e "${YELLOW}没有找到需要添加的文件,尝试添加所有文件...${NC}"
git add -A
FILES=($(git diff --name-only --cached))
TOTAL_FILES=${#FILES[@]}
if [ $TOTAL_FILES -eq 0 ]; then
echo -e "${RED}错误: 没有找到要推送的文件${NC}"
exit 1
fi
else
# 添加所有文件到暂存区
echo -e "${BLUE}添加所有文件到暂存区...${NC}"
git add -A
fi
echo -e "${GREEN}找到 $TOTAL_FILES 个文件需要上传${NC}"
# 计算批次数
BATCH_COUNT=$(( ($TOTAL_FILES + $BATCH_SIZE - 1) / $BATCH_SIZE ))
echo -e "${GREEN}将分为 $BATCH_COUNT 批次上传${NC}"
# 首先提交所有文件
echo -e "${BLUE}提交所有文件...${NC}"
git commit -m "$COMMIT_MESSAGE"
# 分批推送
echo -e "${BLUE}开始分批推送...${NC}"
git push -u $REMOTE_NAME $BRANCH_NAME
if [ $? -eq 0 ]; then
echo -e "${GREEN}所有文件已成功推送到远程仓库${NC}"
else
echo -e "${YELLOW}常规推送失败,尝试使用批量方式推送...${NC}"
# 使用git batch push方式(参考了搜索结果中的示例)
# 基于 git_batch_push.sh 的思路,但简化了实现
# 使用git rev-list获取所有提交
COMMITS=($(git rev-list --reverse HEAD))
TOTAL_COMMITS=${#COMMITS[@]}
if [ $TOTAL_COMMITS -eq 0 ]; then
echo -e "${RED}错误: 没有找到提交记录${NC}"
exit 1
fi
echo -e "${GREEN}找到 $TOTAL_COMMITS 个提交,将分批推送${NC}"
# 计算批次数(每批500个提交)
COMMIT_BATCH_SIZE=500
COMMIT_BATCH_COUNT=$(( ($TOTAL_COMMITS + $COMMIT_BATCH_SIZE - 1) / $COMMIT_BATCH_SIZE ))
echo -e "${GREEN}将分为 $COMMIT_BATCH_COUNT 批次推送提交${NC}"
# 分批推送提交
for ((i=0; i<$COMMIT_BATCH_COUNT; i++)); do
START=$(($i * $COMMIT_BATCH_SIZE))
END=$((($i + 1) * $COMMIT_BATCH_SIZE))
if [ $END -gt $TOTAL_COMMITS ]; then
END=$TOTAL_COMMITS
fi
BATCH_END_INDEX=$((END - 1))
TARGET_COMMIT=${COMMITS[$BATCH_END_INDEX]}
echo -e "${BLUE}推送批次 $((i+1))/${COMMIT_BATCH_COUNT} (提交 $((START+1))-$END)...${NC}"
if git push $REMOTE_NAME $TARGET_COMMIT:refs/heads/$BRANCH_NAME; then
echo -e "${GREEN}批次 $((i+1)) 成功推送${NC}"
else
echo -e "${RED}批次 $((i+1)) 推送失败${NC}"
echo -e "${YELLOW}尝试另一种推送方法...${NC}"
# 如果上面的方法失败,尝试另一种批量推送方法
if [ $i -eq 0 ]; then
# 第一批次,创建新分支
git push $REMOTE_NAME $BRANCH_NAME
else
# 获取上一批次的末尾提交
PREV_END=$(($START - 1))
PREV_COMMIT=${COMMITS[$PREV_END]}
CURR_COMMIT=${COMMITS[$BATCH_END_INDEX]}
echo -e "${BLUE}使用范围推送 $PREV_COMMIT..$CURR_COMMIT${NC}"
git push $REMOTE_NAME $PREV_COMMIT:refs/heads/$BRANCH_NAME $CURR_COMMIT:refs/heads/$BRANCH_NAME
fi
fi
echo
done
fi
echo -e "${GREEN}分批上传过程完成!${NC}"

运行方法很简单。

chmod +x git_batch_push.sh

然后在当前文件夹运行脚本即可。

最终效果

image-20250310234253015