Re: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
- From
Jakub Narebski <jnareb@gmail.com>
- Date
- Jan 11, 2011, 13:21 UTC
- Message-ID
- <m3lj2rbmq5.fsf@localhost.localdomain>
- In-Reply-To
- <746745466.20110111134101@mail.ru>
=?windows-1251?B?wOvl6vHl6SDY8+zq6O0=?= <zapped@mail.ru> writes:
Show 15 quoted lines
> 1.5 years ago I had sources of a project in a SVN repository (actually it does not > matter what SCM was used before). And I had two branches: v2.4 and v2.5. > They differed enough at that moment and (as usual for SVN branches) > laid in two different folders. > Then I had known of Git and I decided to try to use this powerful DVCS. > But as I was a newbie I created two git-repositories: one per each > branch. So v2.4 has its own git-repo. v2.5 (and above) has another one. > > Now I'd like to merge them as v2.5 was a continuos branch from v2.4, > but without a rebasing (i.e. without a global changing of v2.5 > repository, which already has another branches) > It must look like LAST commit of v2.4 should be a PARENT of FIRST commit of v2.5 > > Now there's a question: Is it possible to do so (no rebasing!), and If > "yes" then how to?
As Andreas Ericsson wrote, you can do this using grafts (and you can make history with grafts permanent using "git filter-branch").
Better solution might be to use more modern replace mechanism, see e.g. "git replace" manpage. Below there is untested step-by-step instruction.
First, you have put history of v2.4 and of v2.5 in a single repository (e.g. using "git remote add"). Then you need to find FIRST commit of v2.5 among
$ git rev-list master --parents | grep -v ' '
The above finds all parent-less commits in 'master' branch; replace it with branch holding v2.5 history. Then you need to find LAST commit of v2.4 and its SHA-1, e.g. via
$ git rev-parse v2.4
Save current state of FIRST commit of v2.5 to a file
$ git cat-file -p FIRST > tmp
Edit this file, adding 'parent' line between 'tree' and 'author' headers, so the header of this file looks like the following:
tree 13d050266e05f7c66000240814199fcf3b559d43 parent ada9983c4256f5a7bac1f7f0e29d52011741d6aa author Jakub Narebski <jnareb@gmail.com> 1294231771 +0100
(trailing space added for better readibility).
Then you need to add newly created object to repository:
$ git hash-object -t commit -w tmp
and then use it as replacement
$ git replace <SHA-1 of FIRST> <SHA-1 returned by hash-object>
Finally check that replacement works, e.g.:
$ git show FIRST $ git log --graph --oneline -3 FIRST
The anyone who would fetch refs/replace/ would get joined history, and who doesn't would see it not connected.
P.S. This probably should made it into Documentation/howto
-- Jakub Narebski Poland ShadeHawk on #git