Skip to content

Instantly share code, notes, and snippets.

@Foadsf
Created November 19, 2024 13:35
Show Gist options
  • Save Foadsf/40765ff28c72098bd3bebbca21bc963a to your computer and use it in GitHub Desktop.
Save Foadsf/40765ff28c72098bd3bebbca21bc963a to your computer and use it in GitHub Desktop.
A Windows batch script that recovers Git history for files moved without git mv by detecting deleted files and their new locations, then properly tracking the moves.
@echo off
setlocal enabledelayedexpansion
if "%1"=="" (
echo Usage: git_move_files.bat [RepositoryPath]
exit /b 1
)
set "repo_path=%1"
cd /d "%repo_path%" || (
echo Invalid repository path: %repo_path%
exit /b 1
)
if not exist .git (
echo The specified path is not a git repository.
exit /b 1
)
:: Print header
echo.
echo Filename From Path To Path
echo ======== ========= =======
echo.
for /f "usebackq delims=" %%i in (`git ls-files --deleted`) do (
set "missing_file=%%i"
for %%k in ("!missing_file!") do set "filename=%%~nxk"
for /f "delims=" %%j in ('dir /s /b "!filename!" 2^>nul ^| findstr /v "\.git"') do (
if /i "%%~nxj"=="!filename!" (
set "found_file=%%j"
set "rel_path=!found_file:%CD%\=!"
call :printRow "!filename!" "!missing_file!" "!rel_path!"
rem Create directory if it doesn't exist
if not exist "!missing_file!\.." mkdir "!missing_file!\.." 2>nul
rem First move file back to original location
move "!rel_path!" "!missing_file!" >nul
rem Then use git mv to track the move to new location
git mv "!missing_file!" "!rel_path!"
)
)
)
echo.
endlocal
goto :eof
:printRow
set "str1=%~1"
set "str2=%~2"
set "str3=%~3"
call :padString "!str1!" 24 pad1
call :padString "!str2!" 40 pad2
echo !pad1! !pad2! !str3!
goto :eof
:padString
set "str=%~1"
set "len=%~2"
set "result=!str!"
:padLoop
if "!result:~%~2!"=="" goto :endPadLoop
set "result=!result! "
goto :padLoop
:endPadLoop
set "%~3=!result!"
goto :eof
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment