chore: git_push_dlp 改 robocopy 增量镜像(固定 stage 复用,只复制变动文件)
This commit is contained in:
@@ -20,11 +20,12 @@ fatal: not a git repository (or any of the parent directories): .git
|
|||||||
|
|
||||||
## 原理
|
## 原理
|
||||||
|
|
||||||
1. `xcopy .git` 到 `%TEMP%\git_push_dlp\<repo>-<random>\`(保护区外,授权进程
|
1. `robocopy /MIR .git` 到固定 stage 目录 `%TEMP%\git_push_dlp\<repo>\`(保护区外,
|
||||||
读出明文,写出不再加密)。默认通过 `/EXCLUDE` 排除 `.git\lfs`(LFS 对象
|
授权进程读出明文,写出不再加密)。stage 目录跨运行保留:首次全量镜像,
|
||||||
缓存,动辄数 GB,普通提交 push 不需要)。
|
之后每次 push 只复制变动的文件。默认通过 `/XD lfs` 排除 `.git\lfs`(LFS
|
||||||
|
对象缓存,动辄数 GB,普通提交 push 不需要)。
|
||||||
2. 在 stage 副本里执行 `git push`。
|
2. 在 stage 副本里执行 `git push`。
|
||||||
3. 回到原仓库 `git fetch` 同步远程跟踪引用,然后删除 stage。
|
3. 回到原仓库 `git fetch` 同步远程跟踪引用。stage 目录保留不删,供下次增量复用。
|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|
||||||
@@ -45,9 +46,9 @@ set GIT_PUSH_DLP_WITH_LFS=1
|
|||||||
|
|
||||||
## 排障
|
## 排障
|
||||||
|
|
||||||
- **`[ERROR] xcopy .git failed. Insufficient disk space`**:TEMP 所在盘空间不足。
|
- **`[ERROR] robocopy .git failed`**:常见于 TEMP 所在盘空间不足。stage 目录
|
||||||
先清理 `%TEMP%\git_push_dlp\` 下历史失败残留的 `TestHub-*` 目录(脚本在
|
跨运行复用(`%TEMP%\git_push_dlp\<repo>\`),旧版本脚本留下的 `<repo>-<数字>`
|
||||||
xcopy 失败时不会自动清理)。仍不足时确认是否误设了
|
残留目录可以整体删除。仍不足时确认是否误设了
|
||||||
`GIT_PUSH_DLP_WITH_LFS`(全量 lfs 可能超过盘符剩余空间)。
|
`GIT_PUSH_DLP_WITH_LFS`(全量 lfs 可能超过盘符剩余空间)。
|
||||||
- **stage 在 E: 盘也报 128**:整个 E: 盘都在 DLP 拦截范围内,stage 必须落在
|
- **stage 在 E: 盘也报 128**:整个 E: 盘都在 DLP 拦截范围内,stage 必须落在
|
||||||
C:(`%TEMP%` 默认位置),不要把 `TEMP` 指到 E:。
|
C:(`%TEMP%` 默认位置),不要把 `TEMP` 指到 E:。
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ rem Push from a DLP-protected (transparent-encrypted) directory where
|
|||||||
rem "git push" fails with: fatal: not a git repository
|
rem "git push" fails with: fatal: not a git repository
|
||||||
rem
|
rem
|
||||||
rem How it works:
|
rem How it works:
|
||||||
rem 1. xcopy .git to a stage dir under %TEMP% (outside the protected zone,
|
rem 1. Mirror .git to a fixed per-repo stage dir under %TEMP% with
|
||||||
rem an authorized process reads plaintext, no re-encryption outside).
|
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 2. Run "git push" from the stage dir.
|
||||||
rem 3. Run "git fetch" in the original repo to sync remote-tracking refs.
|
rem 3. Run "git fetch" in the original repo to sync remote-tracking refs.
|
||||||
rem
|
rem
|
||||||
@@ -16,8 +19,9 @@ rem git_push_dlp origin main = git push origin main
|
|||||||
rem git_push_dlp upstream main:main = any normal push args
|
rem git_push_dlp upstream main:main = any normal push args
|
||||||
rem
|
rem
|
||||||
rem Env vars:
|
rem Env vars:
|
||||||
rem GIT_PUSH_DLP_WITH_LFS=1 = also copy .git\lfs (needed only when
|
rem GIT_PUSH_DLP_WITH_LFS=1 = also mirror .git\lfs (needed only
|
||||||
rem the push contains new LFS objects)
|
rem when the push contains new LFS
|
||||||
|
rem objects)
|
||||||
rem ==========================================================================
|
rem ==========================================================================
|
||||||
setlocal EnableExtensions EnableDelayedExpansion
|
setlocal EnableExtensions EnableDelayedExpansion
|
||||||
chcp 65001 >nul
|
chcp 65001 >nul
|
||||||
@@ -28,24 +32,24 @@ if not exist ".git\" (
|
|||||||
)
|
)
|
||||||
|
|
||||||
for %%I in ("%CD%") do set "REPO_NAME=%%~nxI"
|
for %%I in ("%CD%") do set "REPO_NAME=%%~nxI"
|
||||||
set "STAGE=%TEMP%\git_push_dlp\%REPO_NAME%-%RANDOM%%RANDOM%"
|
set "STAGE=%TEMP%\git_push_dlp\%REPO_NAME%"
|
||||||
|
|
||||||
echo [DLP] Stage dir: %STAGE%
|
echo [DLP] Stage dir: %STAGE%
|
||||||
|
|
||||||
rem .git\lfs is the LFS object cache (often several GB); normal commits do
|
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 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.
|
rem If this push contains new/changed LFS files, set GIT_PUSH_DLP_WITH_LFS=1 first.
|
||||||
set "EXCLUDE_OPT="
|
set "EXCLUDE_OPT=/XD lfs"
|
||||||
if not defined GIT_PUSH_DLP_WITH_LFS (
|
if defined GIT_PUSH_DLP_WITH_LFS set "EXCLUDE_OPT="
|
||||||
set "EXCLUDE_FILE=%TEMP%\git_push_dlp_exclude.txt"
|
if defined GIT_PUSH_DLP_WITH_LFS (
|
||||||
> "!EXCLUDE_FILE!" echo \lfs\
|
echo [DLP] Including .git\lfs
|
||||||
set "EXCLUDE_OPT=/EXCLUDE:!EXCLUDE_FILE!"
|
) else (
|
||||||
echo [DLP] Excluding .git\lfs ^(set GIT_PUSH_DLP_WITH_LFS=1 to include^)
|
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
|
robocopy ".git" "%STAGE%\.git" /MIR %EXCLUDE_OPT% /NFL /NDL /NJH /NP >nul
|
||||||
if errorlevel 1 (
|
if errorlevel 8 (
|
||||||
echo [ERROR] xcopy .git failed.
|
echo [ERROR] robocopy .git failed ^(exit %ERRORLEVEL%^).
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,7 +68,6 @@ popd
|
|||||||
|
|
||||||
if not "%EXIT_CODE%"=="0" (
|
if not "%EXIT_CODE%"=="0" (
|
||||||
echo [ERROR] push failed with exit code %EXIT_CODE%
|
echo [ERROR] push failed with exit code %EXIT_CODE%
|
||||||
rmdir /s /q "%STAGE%" 2>nul
|
|
||||||
exit /b %EXIT_CODE%
|
exit /b %EXIT_CODE%
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -72,7 +75,6 @@ echo [DLP] Sync back: git fetch %REMOTE%
|
|||||||
git fetch %REMOTE%
|
git fetch %REMOTE%
|
||||||
set "FETCH_CODE=%ERRORLEVEL%"
|
set "FETCH_CODE=%ERRORLEVEL%"
|
||||||
|
|
||||||
rmdir /s /q "%STAGE%" 2>nul
|
|
||||||
if not "%FETCH_CODE%"=="0" (
|
if not "%FETCH_CODE%"=="0" (
|
||||||
echo [WARN] push succeeded but fetch back failed with exit code %FETCH_CODE%
|
echo [WARN] push succeeded but fetch back failed with exit code %FETCH_CODE%
|
||||||
exit /b %FETCH_CODE%
|
exit /b %FETCH_CODE%
|
||||||
|
|||||||
Reference in New Issue
Block a user