Technical details of the branch merging

Kai Blin kai at
Fri Sep 5 21:35:56 GMT 2008

As I threatened in my "[RFC] Suggested "combined tree" for easier development 
and Franky integration.", here's the technical details of the branch merging.

As a preparation, get a checkout of samba.git, and make sure you're on the 
current devel branch

$ git clone git:// samba3
$ cd samba3
$ git checkout -b s3-rename origin/v3-devel

Here begins the juicy part. Move the source directory to source3 in all 
changes and (on Metze's request) add the original sha1 of the commit to the 
commit message. The magic incantation for this is git filter-branch.

$ git filter-branch --tree-filter 'git mv source source3' --msg-filter 'cat; 
echo "(This used to be commit $GIT_COMMIT)"'

Now go and get yourself a coffee, meal, good night's sleep. Once you get back, 
the filter-branch should be done. Now lather, rinse, repeat for Samba4. (I'm 
getting a new clone as that'll make copying easier later.)

$ git clone git:// samba4
$ cd samba4
$ git checkout -b s4-rename origin/v4-0-test
$ git filter-branch --tree-filter 'git mv source source4' --msg-filter 'cat; 
echo "(This used to be commit $GIT_COMMIT)"'

This one will only take until after lunch provided you started it the first 
thing in the morning. ;)

Now, we're ready to start with the merge. To do that, we'll start from an 
empty repository an merge both Samba3 and Samba4 in.

$ mkdir franky
$ cd franky
$ git init

It's important to have an initial commit in the repository, so we'll create 

$ echo "Initial commit for the tree merge" > merge_info.txt
$ git add merge_info.txt
$ git commit -m "Initial commit on the merged tree"

Of course, at this point we can add all the files that we want to create from 
scratch for the merged tree, so I guess some sort of readme and things like 
that. After we created the inital commit, we'll move the beef over from the 
samba3 and samba4 dirs.

$ cp -a ~/samba3/source3 source3
$ cp -a ~/samba4/source4 source4

We also copy the other directories we want here, but the source dirs were the 
most interesting. Note that thanks to the filter-branch work we did before, 
we can actually copy source3 and source4 folders, not two source folders. 
This is the trick to keep git log working as expected.

After we did all that mundane footwork, let's work some git magic again. We 
need to add all the files and directories we copied over to the repository. 
But we also want them to retain the history they used to have, so we manually 
create the merge commit, specifying both the s3-rewrite HEAD and the 
s4-rewrite HEAD as parents, as well as the initial commit we did to the new 
repo. To make this work, we first need to add the repositories containing 
those branches as remotes.

$ git remote add s3 ~/samba3
$ git remote add s4 ~/samba4
$ git remote update
$ git add source3 source4

Of course the add would also add all the other files and dirs. Now, we need 
more control over what's happening next, so we leave the porcelain and start 
dealing with the plumbing. Thanks to Jelmer for coming up with the idea.

$ git write-tree

This created a tree object, which is halfway to a full commit. git write-tree 
returns a sha1 on stdout, which we will use now. Note that we add the 
s3-rewrite and s4-rewrite HEADs as additional parents, which is why we're 
doing this fuzzing with trees instead of a plain commit. This is plumbing, so 
the next command expects a commit message on stdin.

$ echo "Merge the branches" | git commit-tree <sha1 of the tree object> -p 
<sha1 of the initial commit> -p <sha1 of the s3-rewrite HEAD> -p <sha1 of the 
s4-rewrite HEAD>

git commit-tree creates a commit object and returns the sha1 for the commit 
object on stdout. Now, as this is plumbing we need to move our working copy 
to the new revision manually.

$ git reset --hard <sha1 returned by git commit-tree>

Last but not least, we want to fetch the old tags, so we need a final

$ git fetch --tags ~/samba3

And we're done. Feel free to use it in case you feel like trying the same 
thing yourself.


Kai Blin
WorldForge developer
Wine developer
Samba team member
Will code for cotton.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url :

More information about the samba-technical mailing list