Subject: Re: Where is information of "git read-tree" stored?

From: David Aguilar <[email-masked]>
Date: Sun, 25 Sep 2011 03:30:45 +0200

On Mon, Sep 19, 2011 at 03:09:22PM -0700, Junio C Hamano wrote:
> 
> To a certain degree, the point of a tool is that the user does not need to
> know about the details, but if you are interested...

git-subtree allows you to not have to know about the details:

https://github.com/apenwarr/git-subtree

https://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt

git-subtree, combined with Junio's wonderful write-up below,
should get you on the right track.

> Suppose you have this tree structure in your "original" project:
> 
>         Documentation/README.txt
>         hello.c
> 	Makefile
> 
> and then somebody else has this structure in his project (in your case, it
> may happen to be stored in SVN but once it is slurped in a git repository,
> it does not matter):
> 
>         goodbye.c
> 	Makefile
> 
> Further suppose that you would want to end up with this tree structure:
> 
>         Documentation/README.txt
> 	Makefile
>         hello.c
>         imported/Makefile
>         imported/goodbye.c
> 
> i.e. you would want to move stuff that came from the other project in imported/
> hierarchy.  There may be many other files, and even subdirectories, in the
> other project, but they all are shifted one level down and placed in imported/
> hierarchy.
> 
> The first four steps of the howto is to create such a final tree structure
> and make a merge commit out of that tree.
> 
> After you update your project (which now has both the original files such
> as hello.c etc., may have added new files, and may even have updated stuff
> inside imported/ hierarchy) and the other side updated their project (e.g.
> it may have updated goodbye.c whose change you would want to carry over to
> your imported/goodbye.c, or it may have added a new file welcome.c, which
> you would want to import as imported/welcome.c), you would invoke "pull -s
> subtree", which in turn runs "merge -s subtree".
> 
> The subtree strategy first compares the shapes of two trees being merged,
> and tries to find how much they have to be shifted to match.  Your tree
> may now have:
> 
>         Documentation/README.txt
> 	Makefile
> 	hello.h (added)
>         hello.c
>         imported/Makefile
>         imported/goodbye.c
> 
> while the other side may now have:
> 
>         goodbye.c
> 	Makefile
> 	welcome.c
> 
> The subtree strategy notices that by prefixing "imported/" in front of the
> paths, the tree from the other side will match the shape of the subtree
> you have under "imported/". Thus it can pair:
> 
> 	their "goodbye.c" with your "imported/goodbye.c"
>         their "Makefile" with your "imported/Makefile"
>         their "welcome.c" with your "imported/welcome.c"
> 
> and merge the changes. The common ancestor commit of this merge will be
> the initial merge you made with the first 4-step, so the three-way merge
> logic would notice that there wasn't "welcome.c" in the beginning, they
> added that path, while you did not do anything to the path that
> corresponds to it (namely, "imported/welcome.c"), so the new "welcome.c"
> file from the other project would simply be copied as "imported/welcome.c"
> to your tree, and the change they made to "goodbye.c" and your changes you
> made to your "imported/goodbye.c" will be merged and result is recorded in
> your "imported/goodbye.c".
> 
> If "compares the shape and figures out how much to shift" makes you feel
> uneasy (and it probably should), you can give an explicit directory prefix 
> as the backend option "subtree" (see "git merge help" for details).

-- 
					David