@echo off rem ========================================================================== rem git_push_dlp.bat rem Push from a DLP-protected (transparent-encrypted) directory where rem "git push" fails with: fatal: not a git repository rem rem How it works: rem 1. xcopy .git to a stage dir under %TEMP% (outside the protected zone, rem an authorized process reads plaintext, no re-encryption outside). rem 2. Run "git push" from the stage dir. rem 3. Run "git fetch" in the original repo to sync remote-tracking refs. rem rem Usage (run inside the repo root): rem git_push_dlp = git push origin HEAD rem git_push_dlp origin main = git push origin main rem git_push_dlp upstream main:main = any normal push args rem rem Env vars: rem GIT_PUSH_DLP_WITH_LFS=1 = also copy .git\lfs (needed only when rem the push contains new LFS objects) rem ========================================================================== setlocal EnableExtensions EnableDelayedExpansion chcp 65001 >nul if not exist ".git\" ( echo [ERROR] .git not found. Run this inside a git repository root. exit /b 1 ) for %%I in ("%CD%") do set "REPO_NAME=%%~nxI" set "STAGE=%TEMP%\git_push_dlp\%REPO_NAME%-%RANDOM%%RANDOM%" echo [DLP] Stage dir: %STAGE% rem .git\lfs is the LFS object cache (often several GB); normal commits do rem not need it for push. Excluding it avoids xcopy disk-space failures. rem If this push contains new/changed LFS files, set GIT_PUSH_DLP_WITH_LFS=1 first. set "EXCLUDE_OPT=" if not defined GIT_PUSH_DLP_WITH_LFS ( set "EXCLUDE_FILE=%TEMP%\git_push_dlp_exclude.txt" > "!EXCLUDE_FILE!" echo \lfs\ set "EXCLUDE_OPT=/EXCLUDE:!EXCLUDE_FILE!" echo [DLP] Excluding .git\lfs ^(set GIT_PUSH_DLP_WITH_LFS=1 to include^) ) xcopy /E /I /Q /H /Y %EXCLUDE_OPT% ".git" "%STAGE%\.git" >nul if errorlevel 1 ( echo [ERROR] xcopy .git failed. exit /b 1 ) set "REMOTE=%~1" if not defined REMOTE set "REMOTE=origin" if "%REMOTE:~0,1%"=="-" set "REMOTE=origin" set "PUSHARGS=%*" if not defined PUSHARGS set "PUSHARGS=origin HEAD" pushd "%STAGE%" echo [DLP] Run: git push %PUSHARGS% git push %PUSHARGS% set "EXIT_CODE=%ERRORLEVEL%" popd if not "%EXIT_CODE%"=="0" ( echo [ERROR] push failed with exit code %EXIT_CODE% rmdir /s /q "%STAGE%" 2>nul exit /b %EXIT_CODE% ) echo [DLP] Sync back: git fetch %REMOTE% git fetch %REMOTE% set "FETCH_CODE=%ERRORLEVEL%" rmdir /s /q "%STAGE%" 2>nul if not "%FETCH_CODE%"=="0" ( echo [WARN] push succeeded but fetch back failed with exit code %FETCH_CODE% exit /b %FETCH_CODE% ) echo [DLP] Done. exit /b 0