前言
- 最近天天在仓库提交东西,于是整了一个一键推送脚本,这里也分享一下。
- 本脚本仅适用于单人仓库,且已经安装git的情况下。

1 完整代码实现
1-1 完整代码
- 先上完整代码我再分析
bat
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
echo ===============================
echo Git 一键Push脚本
echo ===============================
echo.
echo [1/4] 检查 Git 状态...
git status -sb
echo.
echo [2/4] 检查远程更新
git fetch --quiet
for /f %%i in ('git rev-list --left-right --count HEAD...@{u} 2^>nul') do set status=%%i
if defined status (
for /f "tokens=1,2" %%a in ("!status!") do (
set behind=%%a
set ahead=%%b
)
) else (
set behind=0
set ahead=0
)
echo 本地领先: !ahead!
echo 本地落后: !behind!
if !behind! GTR 0 (
echo WARNING!警告:远程有更新,建议先 pull!
)
echo.
echo [3/4] 检查本次变更是否存在 >100MB 文件(已剔除.gitgnore)
rem 获取变更文件(已暂存 + 未暂存)
git diff --name-only
git diff --cached --name-only
git ls-files --others --exclude-standard > .git_new_files.tmp
(
git diff --name-only
git diff --cached --name-only
type .git_new_files.tmp
) > .git_changed_files.tmp
rem 去重处理(简单方式)
for /f "delims=" %%f in (.git_changed_files.tmp) do (
if exist "%%f" (
for %%A in ("%%f") do (
set size=%%~zA
if !size! GTR 104857600 (
echo ERROR!! 超大文件: %%f
echo size: !size! bytes
del .git_changed_files.tmp >nul 2>&1
del .git_new_files.tmp >nul 2>&1
pause
exit /b 1
)
)
)
)
del .git_changed_files.tmp >nul 2>&1
del .git_new_files.tmp >nul 2>&1
echo 未发现本次变更中的超大文件
echo.
echo [4/4] git add .
git add .
echo.
set /p msg=请输入本次的 commit message:
if "%msg%"=="" (
echo ERROR!! commit message 不能为空
pause
exit /b 1
)
git commit -m "%msg%"
if errorlevel 1 (
echo ERROR!! commit 失败
pause
exit /b 1
)
echo.
echo 正在 push...
git push
if errorlevel 1 (
echo ERROR!! push 失败(可能冲突或权限问题)
pause
exit /b 1
)
echo.
echo ===============================
echo Push 成功!
echo ===============================
pause
1-2 完整流程
- 整个脚本就完成以下几个流程:
- 检查仓库状态
- 检查远程更新风险
- 检查本次变更是否有 >100MB 文件 (需要考虑
.gitgnore,且每次只检测本轮新增的内容) git add .- 根据用户输入信息进行
git commit git push
1-3 测试

2 代码解析
- 整体没啥难的就快速过一遍
2-1 初始化
bat
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
- 关闭bat脚本的执行命令前缀
C:\xxx>命令 - 切换控制台编码为
UTF-8防止中文乱码 - 延迟变量展开,确保普通变量
%var%会在for循环中实时更新
2-2 检查 Git 状态
bat
git status -sb
-s简洁输出,-b当前分支
2-3 远程更新
2-3-1 同步信息
bat
git fetch --quiet
- 同步远程信息但不执行修改,
--quiet静默模式
2-3-2 对比分支
bat
git rev-list --left-right --count HEAD...@{u}
HEAD当前本地分支.@{u}远程分支,一般是origin/main...进行比较,比较远程和本地的commit--left-right区分左右--count只输出数量。
bat
for /f %%i in ('git rev-list --left-right --count HEAD...@{u} 2^>nul') do set status=%%i
if defined status (
for /f "tokens=1,2" %%a in ("!status!") do (
set behind=%%a
set ahead=%%b
)
) else (
set behind=0
set ahead=0
)
echo 本地领先: !ahead!
echo 本地落后: !behind!
- 读取命令输出,然后拆分赋值变量
bat
if !behind! GTR 0 (
echo WARNING!警告:远程有更新,建议先 pull!
)
- 如果远程更新比本地多,就警告
2-4 大文件检测
2-4-1 获取本次所有变更文件
bat
git ls-files --others --exclude-standard
- 获取未
tracked文件但自动遵守.gitignore(这很重要否则这一步会贼慢)--others只看未track文件。--exclude-standard考虑.gitignore、.git等文件
bat
(
git diff --name-only
git diff --cached --name-only
type .git_new_files.tmp
) > .git_changed_files.tmp
git diff --name-only获取未暂存文件git diff --cached --name-only获取已暂存文件- 并合并到文件列表
.git_changed_files.tmp - 上述指令将获得本次所有变更文件,考虑到
.gitignore、.git等文件
2-4-2 遍历检查大小
bat
for /f "delims=" %%f in (.git_changed_files.tmp) do (
if exist "%%f" (
for %%A in ("%%f") do (
set size=%%~zA
if !size! GTR 104857600 (
echo ERROR!! 超大文件: %%f
echo size: !size! bytes
del .git_changed_files.tmp >nul 2>&1
del .git_new_files.tmp >nul 2>&1
pause
exit /b 1
)
)
)
)
- 逐行读取文件名。
delims=防止空格被截断。 if exist "%%f"防止文件被删除for %%A in ("%%f") do (bat 获取文件属性%%~zA获取文件大小(bytes)104857600是100 * 1024 * 1024,也就是100MB- 如果有大文件删除临时文件
2-5 三部曲
bat
git add .
set /p msg=请输入本次的 commit message:
if "%msg%"=="" (
echo ERROR!! commit message 不能为空
pause
exit /b 1
)
git commit -m "%msg%"
git push
set /p msg=等待用户输入。
小结
- 目前本脚本可以勉勉强强支持正常个人仓库的使用
- 如有错误,欢迎指出
- 感谢观看!