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

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

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

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:52:04

Manuel Reimer [off-list ref] writes:
quoted
That "how to" may be badly written and this may have been unclear to you
but the first four steps are to be done _only once_ to set things up, and
after that you need to run only the fifth step whenever you want to update
from the Bproject. Could you suggest a better wording to update the doc?
As long as I don't understand what's going on here, I can't suggest
how to improve the documentation.
quoted
The very first "subtree merge" (the one that is recorded with the commit
after the read-tree) records all paths from Bproject renamed to elsewhere
in the merge result (you can view it with "git show -M
$that_merge_commit")
Tried that, but the stuff, I saw on screen, doesn't make clear how GIT
knew about what to do here.
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...

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).

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

From: David Aguilar <hidden>
Date: 2016-06-15 22:52:06

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help