git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Stitching together private svn repo and public git repo

From
Charles Bailey <charles@hashpling.org>
Date
Jan 2, 2008, 21:40 UTC
Message-ID
<20080102214005.GA10924@hashpling.org>
In-Reply-To
<C3A195B5.10839%jefferis@gmail.com>
On Wed, Jan 02, 2008 at 07:25:41PM +0000, Gregory Jefferis wrote:
Show 6 quoted lines
> 
> Right now I have been trying to pull B into A to splice:
> 
> A $ git checkout v1.91
> B $ git checkout v1.91-manualmerge
> B $ git pull --no-commit -s ours ../A
So you have something like this in B:
Av1* -- Av1_b -- Av1_c -- Av1_d -- Av2_d* -- Av2_e -- Av3_e*
Where the * are manual merges of the offical Avn releases...
And you want this:
Av1   --       --       -- Av2   --      -- Av3
  \                          \                \
  Av1_b -- Av1_c -- Av1_d -- Av2_d -- Av2_e -- Av3_e  ???

This is a "rewrite history" job as parent lists are part of each commit. (See Linus' big bold-face warning about history re-writes.)

First of all I would add a remote for the 'A' repository so that those commits are available in the 'B' repository.

Something like: git remote add repoA /path/to/A git fetch repoA

You could then do this with a 'git filter-branch --parent-filter' to rewrite the parents of the merge commits. As far as I can see, you would need to call filter-branch once per merge to rewrite everything from the merge commit forwards. At this point all later commits would have different ids, so attempting to rewrite subsequent parent-ids in the same filter-branch invocation is probably futile.

It might be possible to use an intelligent script in a single --commit-filter invocation of filter-branch, but the script of the actual filter would have to be a bit (a lot!) more sophisticated, remember the ids of the new commits as it created them with 'git commit-tree' and merging in the repoA parents at the right points.

Leaving that aside and concentrating on the multiple filter-branch invocation option... for example, the first parent-filter script could be: sed -e 's/^$/-p <commit id of Av1>/'

( This is if you want your exisiting tree to branch from Av1 in the original repo. If you wanted to replace your tree root with a root at Av1, because your current root is just a copy of Av1 then you want: sed -e 's/<commit id of repoB's Av1 copy>/<commit id of Av1 in A>/' )

Then, for whatever the Av2_d commit's new id is, you could do a parent-filter of: sed -e 's/\(<new commit id of Av1_d>\)/\1 -p <commit id of Av2>/'

This causes the Av2_d commit to be rewritten, maintaining its original parent and adding another parent which comes from repoA. It then rewrites all the descendent commits of Av2_d to take account of this new commit id and all the subsequent new commit ids.

Now you can do similar for the next merge commit: sed -e 's/\(<new commit id of Av2_e>\)/\1 -p <commit id of Av3>/'

As noted, you end up with completely new commit objects with a completely new history, so you will screw everyone who is pulling/cloning from you.

Charles.
Previous: Gregory JefferisNext: Dmitry Potapov
Message 2 of 6 in “Stitching together private svn repo and public git repo”
  1. Gregory JefferisJan 2, 2008
  2. Charles BaileyJan 2, 2008
  3. Dmitry PotapovJan 2, 2008
  4. Charles BaileyJan 2, 2008
  5. Gregory JefferisJan 3, 2008
  6. Junio C HamanoJan 3, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.