I want to combine a cvs and a svn repository into a new git repo, without loosing history of course. The catch is the svn repo is a direct continuation of the cvs repo historywise. Someone just created the svn repo and clumsily added the last state from cvs without keeping any history. The most recent sources are in svn. I don't want to keep the old repos.
The history in graphics:
CVS: A - B - C
SVN: D - E - F - G
What I want:
GIT: A - B - C - D - E - F - G
I made a git repo from cvs with cvs2git, and another git repo from svn with git svn clone
as outlined in http://john.albin.net/git/convert-subversion-to-git but just can't figure out how to combine the two. I did this:
git clone cvs.git
cd cvs
git remote add svn ../../svn.git
git fetch svn
Now what? git merge -s ours svn/master
seems to do what I want but does not create a linear history:
A - B - C - - - H'
/
D - E - F - G /
Any experiments with git rebase
didn't get me anywhere.
In the Conceptual Overview section, we saw how a feature branch can incorporate upstream changes from main using either git merge or git rebase . Merging is a safe option that preserves the entire history of your repository, while rebasing creates a linear history by moving your feature branch onto the tip of main .
The alternative (and longer) way of fixing the fatal: refusing to merge unrelated histories issues is to unstage your current commits, stash them, clone your required remote repository, and then place your stashed branch contents into the new clone.
Use .git/info/grafts
to connect histories and then git filter-branch
to make it permanent.
There is a some description how somebody done it: http://bugsquash.blogspot.co.uk/2010/03/stitching-git-histories.html
Using what kan wrote I came up with this solution:
git clone cvs.git
cd cvs
git remote add svn ../../svn.git
git fetch svn
Use git log --all
to find the unconnected histories:
...
|
* ab42f52 2011-09-14 06:03:07 +0000 | [svnuser]
|
* 1985b93 2011-09-14 06:00:00 +0000 | Migration from CVS [svnuser]
* 12e0ed4 2011-09-14 05:58:10 +0000 | *** empty log message *** (HEAD, origin/master, origin/HEAD, master) [cvsuser]
|
* 5060a7f 2011-04-18 14:07:03 +0000 | *** empty log message *** [cvsuser]
|
...
Find the full SHA1:
git show 1985b93
git show 12e0ed4
Create the graft:
echo 1985b9305ebc819e760f7ecf8e2abe7963eac055 12e0ed4c3dd75cec396a2d228825702eab73ba19 > .git/info/grafts
Now the histories are connected but not yet permanent:
|
* ab42f52 2011-09-14 06:03:07 +0000 | [svnuser]
|
* 1985b93 2011-09-14 06:00:00 +0000 | Migration from CVS (grafted) [svnuser]
|
* 12e0ed4 2011-09-14 05:58:10 +0000 | *** empty log message *** (HEAD, origin/master, origin/HEAD, master) [cvsuser]
|
* 5060a7f 2011-04-18 14:07:03 +0000 | *** empty log message *** [cvsuser]
|
Make it permanent as shown in http://bugsquash.blogspot.co.uk/2010/03/stitching-git-histories.html:
git branch svnmaster svn/master
git filter-branch -- 12e0ed4c3dd75cec396a2d228825702eab73ba19..svnmaster
This creates new commits but also leaves the original svn commits. git log --all
will show it:
* 849278b 2013-04-15 16:31:44 +0000 | Java 6 in Eclipse. Deployed. (svnmaster) [svnuser]
|
...
|
* c33f7cc 2011-09-14 06:03:07 +0000 | [svnuser]
|
* 7acb3ed 2011-09-14 06:00:00 +0000 | Migration from CVS [svnuser]
|
| * b3d5413 2013-04-15 16:31:44 +0000 | Java 6 in Eclipse. Deployed. (svn/master, refs/original/refs/heads/svnmaster) [svnuser]
| |
...
| |
| * ab42f52 2011-09-14 06:03:07 +0000 | [svnuser]
| |
| * 1985b93 2011-09-14 06:00:00 +0000 | Migration from CVS (grafted) [svnuser]
|/
|
* 12e0ed4 2011-09-14 05:58:10 +0000 | *** empty log message *** (HEAD, origin/master, origin/HEAD, master) [cvsuser]
|
* 5060a7f 2011-04-18 14:07:03 +0000 | *** empty log message *** [cvsuser]
|
Remove the graft, the duplicate history will be gone:
rm -r .git/info/grafts .git/refs/original
Clean up:
git reset --hard svnmaster
git branch -D svnmaster
And push:
git push
All done!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With