Subject: Re: Stitching together private svn repo and public git repo

From: Gregory Jefferis <[email-masked]>
Date: Thu, 03 Jan 2008 14:43:09 +0000

Many thanks to both for your replies.  Starting from your comments and
consulting:

http://www.kernel.org/pub/software/scm/git/docs/repository-layout.html

for (fairly scant) details of .git/info/grafts and
 
http://www.kernel.org/pub/software/scm/git/docs/git-filter-branch.html

I think I have now been able to do the necessary.  Since I found this a
trivial operation (in the true mathematical sense of quasi-impossible until
someone helps you to figure it out and simple once you have) and I tripped
over a couple of times, I thought I would share my final shell script below.

One point that I missed initially.  The graft file format is unforgiving.
You are allowed comments but each regular line is:

Commit-SHA-1 Parent1-SHA-1 Parent2-SHA-1\n
      
If you put e.g. more than a single space between your SHA-1s you will get
"bad graft data:" - I missed one in the fake merge line and ran round in
circles for a bit thinking it was something to do with the state of my
trees.

Anyway, boy did it feel great when I was able to git-pull the latest public
release into my private repository:

    34 files changed, 11563 insertions, 8399 deletions

and only 2 simple conflicts to fix with git-mergetool.  That was not a merge
I wanted to do by hand!

Best wishes and thanks again,

Greg.
-- 

#!/usr/bin/env bash
# makemygitbygraft.sh
# merge my private repo (converted from svn) with a public git repo
# retains history of both and will allow 3 way merges etc in future

# work on a copy of my svn imported repo just in case
cd ~/dev/Physiology
rm -rf ~/dev/Physiology/nm-graft
cp -R nm-git-svn2 nm-graft
cd nm-graft

# Now get to work, bring in public repo as a remote
git remote add nm-ucl ../nm-ucl
git fetch nm-ucl

# set up the grafts
cat > .git/info/grafts <<EOF
# connect r2 of git-svn to v1.86 of nm-ucl
# r1 (which was an identical initial import) will now be detached (and
forgotten)
52b1933421ef524811407fa4c240da58ceec5749
eca3db14fcf25744fdf585456f03599a9db2af96
#
# Make fake merge with Neuromatic v1.91b
# svn-manualmerge1 svn-manualmerge1~1 public-v1.91b
120282ee5275027312dde386c8995218f361cf35
0962cb27f7ad92f44def04630e8e6a22b86e0699
6735057f53dd57248c7ec23f6ae9f22085d98fba
EOF

# running git-status seems to stop git thinking that the working dir is
dirty
git-status
# run git-filter-branch to instantiate the new parents
# just use cat so that parent names are untouched by the process
# but will be fed by .git/grafts/info as appropriate
git-filter-branch --parent-filter cat HEAD

Nicely formatted snippet also at
http://pastie.textmate.org/private/pv1n1nbmcmtxnxbq4zd7w

On 2/1/08 22:46, "Charles Bailey" <[email-masked]> wrote:

> On Thu, Jan 03, 2008 at 01:13:54AM +0300, Dmitry Potapov wrote:
>> I believe there is a much easier way to do that using .git/info/grafts
>> The first step is to create .git/info/grafts, which specifies commit-id
>> and its parents for each commit that you want to change. Then you
>> can check the result using gitk, and if you are satisfied with what
>> you see then you run git filter-branch on it to convert 'fake' parents
>> into real ones.
>> 
>> Dmitry
>> 
> 
> Oh yes, this is much easier.  Unless I'm missing something, the
> documentation on grafts is fairly sparse, though.  They are mentioned
> (almost in passing) in git help filter-branch but the file format is
> only documented in repository-layout.txt which seems more developer
> than user oriented.
> 
> Charles.

-- 
Gregory Jefferis, PhD
Division of Neurobiology
MRC Laboratory of Molecular Biology,
Hills Road,
Cambridge, CB2 0QH, UK.

http://www2.mrc-lmb.cam.ac.uk/NB/jefferis_g
http://www.neuroscience.cam.ac.uk/directory/profile.php?gsxej2
http://flybrain.stanford.edu