How to migrate SVN patches
Everything in this wiki page is provided "as is", i.e. I do not take any responsibility, if it destroys your patches, your repository, your car, your house, your life, or your mom's friend's garden! And if you think it's ugly and lacking sufficient explanation, it is YOUR responsibility to fix that!
What is this?
If you have a lot of SVN patches (like I used to have) you might wonder how to get them into the new git repository. I wrote a small batch file to exactly this and it really helps, although it is not 100% fail-safe. In fact it is really messy and doesn't work as it was supposed to be, yet it can help.
Isn't that overcomplicated?
Well, if you have 5 patches, then yes! Don't bother! Apply them manually. But if you have more than 350 patch files like I had, then this might be useful for you.
How to use it
- Put this batch file in a folder, adjust the pathes accordingly (some are not even used, I don't give...)
- Put ONE (it might look like the script could handle multiple files, but it can't!) patch file in the same folder and run the batch script
- The patch file must have a very specific file name: "r<svn-revision-number>-<repopath>-<patchname>.patch" (no spaces anywhere!)
- Use the highest revision number that you can see in your patch files. This won't guarantee that it can be applied (since SVN allows to check out arbitrary revisions of each file at the same time), but is the best guess.
- repopath is the subfolder inside the repo, where "\" is replaced by ".", e.g. "reactos.base.applications")
- patchname is whatever you want, just without any spaces
- If you get an error, check if the scrtipt told you a commit hash. If not, it might not be in your git repo, so find the next one after it and rename your patch file accordingly
- If you get the commit hash (thus the correct revision should have been checked out) and an error occurs, try moving the patch file into the git repo to apply manually (with TGIT). If often works. Then Commit manually.
Can I improve this?
I don't know. If you think you can, try it. If you succeed, great. If you are a nice person, please update this wiki-page with whatever you think is useful.
The batch file
@echo off setlocal EnableDelayedExpansion set PATCH_FILE_PATH="D:\Dev\ReactOS\Patches\Diffs\test" set DONE_PATH="D:\Dev\ReactOS\Patches\Diffs\done" set FAILED_PATH="D:\Dev\ReactOS\Patches\Diffs\failed" set GIT_REPO_PATH="D:\Dev\ReactOS\git.reactos.org" cd %GIT_REPO_PATH% :. Clean the repo git checkout . git clean -d -f :: Process all patches for /f %%F in ('dir /b /a-d /one %PATCH_FILE_PATH%\r?????*.patch 2^>nul') do ( :: Set the patch file name set PATCH_FILE=%%F set PATCH_FILE1=!PATCH_FILE:~1! set PATCH_FILE2=!PATCH_FILE1:.patch=! :: Extract some fields from the name for /F "tokens=1,2,3 delims=-" %%a in ("!PATCH_FILE2!") do ( set REVISION=%%a set PATCH_DIR0=%%b set BRANCH_NAME=%%c ) set PATCH_DIR=!PATCH_DIR0:.=/! echo Processing file !PATCH_FILE! echo - Revision: !REVISION!, Directory: !PATCH_DIR!, Branch name: !BRANCH_NAME!) :: Find the commit with the desired SVN revision for /f %%h in ('git --no-pager log --all "--pretty=%%H" "--grep=file:///srv/svn/reactos/trunk@!REVISION! "') do set COMMIT_HASH=%%h echo Using commit hash: !COMMIT_HASH! :: Checkout the revision git checkout --detach !COMMIT_HASH! :: Apply the patch git apply -p0 --directory=!PATCH_DIR! -v !PATCH_FILE_PATH!\!PATCH_FILE! && goto Success echo Failed to apply patch! :: move !PATCH_FILE_PATH!\!PATCH_FILE! !FAILED_PATH!\ goto Next :Success :: Create the new branch git branch patchfiles/!BRANCH_NAME! git checkout patchfiles/!BRANCH_NAME! :: Commit to new branch git add . git commit --all --message="Patch from file !PATCH_FILE! on r!REVISION!" :: Move file away move !PATCH_FILE_PATH!\!PATCH_FILE! !DONE_PATH!\ :Next echo ------------------------------------- pause ) echo Done!