简体   繁体   中英

Merge two git repository histories

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.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM