How to migrate SVN patches

From ReactOS Wiki
Revision as of 20:07, 3 October 2017 by ThePhysicist (talk | contribs)
Jump to: navigation, search

Disclaimer

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 explanantion, it is YOUR responsibilty to fix that!

What?

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.

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 sjould 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.
@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%

:. Chlean 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 Processig 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
)

:: for /f %F in ('dir /b /a-d /one D:\Dev\ReactOS\Patches\Diffs\r?????*.patch 2^>nul') do @set FILE=%F && @set REVISION=%FILE:~1,5%

echo Done!