I have tried to automate the gatekeeper setup described by Jon Loeliger and got it working. He starts out very detailed about what steps to perform, but the part 'Merging Back into Subversion' is rather short. I have tried different setups with git-svn, also followed the excellent presentations/examples given by Thomas Ferris Nicolaisen and have used his example projects (with modifications) for testing out the 'gatekeeper setup':
@echo 1. Clone Subversion repo
cd %WDIR%\devs\adm
call git svn clone -s --prefix=svn/ http://localhost/svn-repos/company-repo/websites -- username adm
cd %WDIR%\devs\adm\websites
call git reset --hard svn/trunk
@echo ----------------------------------
@echo 2. Create bare repo
cd %WDIR%\devs\adm
mkdir websites.git
cd websites.git
call git init --bare
@echo ----------------------------------
@echo 3. Populate bare with content from gatekeeper
cd %WDIR%\devs\adm\websites
call git push --all ../websites.git
call git push ../websites.git "refs/remotes/svn/*:refs/heads/svn/*"
@echo ----------------------------------
@echo 4. Setup bare as a remote in gatekeeper and fetch branches
call git remote add bare_repo ../websites.git
call git fetch bare_repo
Step 4 is not described by Jon Loeliger but I guess that's what he ment.
When it's time for merging back to subversion do:
C:\tmp\devs\adm\websites>git fetch bare_repo
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From ../websites
e53fba9..2ac281c svn/trunk -> bare_repo/svn/trunk
Now we can follow the steps from the book:
C:\tmp\devs\adm\websites>git checkout svn/trunk
Note: checking out 'svn/trunk'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at e53fba9... [maven-release-plugin] prepare release kaksi
C:\tmp\devs\adm\websites>git merge --no-ff remotes/bare_repo/svn/trunk
Merge made by the 'recursive' strategy.
0 files changed
create mode 100644 web/howto.txt
create mode 100644 web/readme.txt
C:\tmp\devs\adm\websites>git svn dcommit
Committing to http://localhost/svn-repos/company-repo/websites/trunk ...
A web/howto.txt
A web/readme.txt
Committed r8
A web/readme.txt
A web/howto.txt
r8 = 28da267255ae56022bd4ed3c0f4886da1ac04944 (refs/remotes/svn/trunk)
No changes between current HEAD and refs/remotes/svn/trunk
Resetting to the latest refs/remotes/svn/trunk
My problem with this setup (and we have been warned earlier in the book) is that the history is squashed:
C:\tmp\devs\adm\svn\websites>svn log
------------------------------------------------------------------------
r8 | adm | 2012-05-12 23:21:11 +0200 (lø, 12 mai 2012) | 1 line
Merge remote-tracking branch 'remotes/bare_repo/svn/trunk' into HEAD
------------------------------------------------------------------------
Now consider this alternative for merging back into subversion:
C:\tmp\devs\adm\websites>git checkout -t svn/trunk
Branch trunk set up to track local ref refs/remotes/svn/trunk.
Switched to a new branch 'trunk'
C:\tmp\devs\adm\websites>git fetch bare_repo
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From ../websites
c188a72..b1b4237 svn/trunk -> bare_repo/svn/trunk
C:\tmp\devs\adm\websites>git rebase remotes/bare_repo/svn/trunk
First, rewinding head to replay your work on top of it...
Fast-forwarded trunk to remotes/bare_repo/svn/trunk.
C:\tmp\devs\adm\websites>git svn reset 2147483647
r7 = c188a72da6df2966e563e9e575b626d5b449400f (refs/remotes/svn/trunk)
C:\tmp\devs\adm\websites>git svn rebase
Current branch trunk is up to date.
C:\tmp\devs\adm\websites>git svn dcommit
Committing to http://localhost/svn-repos/company-repo/websites/trunk ...
A web/howto.txt
A web/readme.txt
Committed r8
A web/readme.txt
A web/howto.txt
r8 = 18b7c7b4693cc8e55098bd716c9259ed5570acf0 (refs/remotes/svn/trunk)
No changes between current HEAD and refs/remotes/svn/trunk
Resetting to the latest refs/remotes/svn/trunk
Now the commit-history is intact:
C:\tmp\devs\adm\svn\websites>svn log
------------------------------------------------------------------------
r8 | adm | 2012-05-12 23:51:48 +0200 (lø, 12 mai 2012) | 1 line
'ola added [readme.txt, howto.txt] on svn/trunk'
In order for this setup to work we need to use the 'git svn reset' command, or else the dcommit will fail the second time, because git-svn is confused about the current revision, and is behind (to same revision as when we created the bare-repo). This is probably because we used rebase, which in turn is necessary to get a nice linear history in subversion.
The big question is: What does 'git svn reset ' really do?
Is "forward reseting" a legitimate use of 'git svn reset' in this case?