@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. Mirror .git to a fixed per-repo stage dir under %TEMP% with rem robocopy /MIR (outside the protected zone, an authorized process rem reads plaintext, no re-encryption outside). The stage dir is kept rem between runs, so after the first full mirror only changed files rem are copied on subsequent pushes. 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 mirror .git\lfs (needed only rem when the push contains new LFS rem 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%" 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 filling up the TEMP drive. rem If this push contains new/changed LFS files, set GIT_PUSH_DLP_WITH_LFS=1 first. set "EXCLUDE_OPT=/XD lfs" if defined GIT_PUSH_DLP_WITH_LFS set "EXCLUDE_OPT=" if defined GIT_PUSH_DLP_WITH_LFS ( echo [DLP] Including .git\lfs ) else ( echo [DLP] Excluding .git\lfs ^(set GIT_PUSH_DLP_WITH_LFS=1 to include^) ) robocopy ".git" "%STAGE%\.git" /MIR %EXCLUDE_OPT% /NFL /NDL /NJH /NP >nul if errorlevel 8 ( echo [ERROR] robocopy .git failed ^(exit %ERRORLEVEL%^). 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% exit /b %EXIT_CODE% ) echo [DLP] Sync back: git fetch %REMOTE% git fetch %REMOTE% set "FETCH_CODE=%ERRORLEVEL%" 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