84 lines
2.8 KiB
Batchfile
84 lines
2.8 KiB
Batchfile
@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
|