Splitting a project into branches afterwards

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Splitting a project into branches afterwards

Yohann Bénédic
Hello everyone!

First of all, I believe that what I am about to ask is impossible, but I
give it a shot because there may be ways to get a close enough result or
another approach that I have not thinked of.

What I have.
A git repository cloned from svn (entire repo : 30,000 commits in 60
branches) that contains the source code of several products built around a
common framework. Branches where made to track the delivered version of each
product, so that there is a product_A_v1 branch, a product_B_v2 branch, etc.
The key point is that there is only one trunk that is common to all of the
products and framework. The source code is organized in a low-level -> high
level hierarchy which results in not having a clean top level folders for
product_A, product_B, … and framework.

What I wish I had.
A git repository with a framework branch that only contains common code, a
product_A branch that derived from the framework branch at some point,
introducing all the product_A-specific source code. Same with the other
products.

My attempt.
I started from the master branch and created a framework branch out of it. I
removed all the product specific code from it (A, B etc.) and commited
(let's call that the initial_removal commit for further reference). I then
created a product_A branch from the master branch and removed all the
product-specific code other than product A's (keeping the framework) and
commited (that's another initial_removal commit). I then did the same for
product_B, C, etc.
At this point, I am happy with the situation, even though the history
reminds me that the products were not cleanly separated from each other in
the past. The problem is with the "initial_removal" commits I made on each
branch. If the framework branch moves forward, I want my product_A branch to
be able follow along : that's a merge of the framework from product_A. In
product_A, I might fix something from the framework and need to patch the
latter. That's a merge in the other direction. Both these merges will apply
the "initial_removal" commits, generating conflics at best, silently
succeeding at worst. And that's were I am stuck because and can't find a way
to tell git to ignore them once and for all so that I can have a normal
workflow afterwards.

Further ideas.
I feel like sub-trees might help me here, but I haven't learned enough about
them to knwo for sure: anyone telling me "nope they won't help" or "yes
that's what you are looking for" would help.
Any complete procedure is welcomde too :) as weel as pointers to other git
concepts.

Thank you all for your time.

Yohann

PS. I am not a native english speaker. Please, forgive any mistake or
misleading sentence I might have written. Corrections are welcomed too!N�����r��y���b�X��ǧv�^�)޺{.n�+����ا���ܨ}���Ơz�&j:+v�������zZ+��+zf���h���~����i���z��w���?����&�)ߢf�
Reply | Threaded
Open this post in threaded view
|

Re: Splitting a project into branches afterwards

Junio C Hamano
Yohann Bénédic <[hidden email]> writes:

> branch. If the framework branch moves forward, I want my product_A branch to
> be able follow along : that's a merge of the framework from product_A. In
> product_A, I might fix something from the framework and need to patch the
> latter. That's a merge in the other direction.

Instead of doing a mixed ball of wax on product specific branch,
can't you do the latter by (1) fix something that belongs to the
framework part of the system on the framework branch, (2) merge that
to product A branch, and then (3) use that fixed framework code to
update the product A?  That way you would never have to merge
product specific part to the framework, which is meant to be product
agnistic (which is the whole point of your "initial removal" done on
the framework branch, if I am reading you correctly).
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: Splitting a project into branches afterwards

Junio C Hamano
Junio C Hamano <[hidden email]> writes:

> Yohann Bénédic <[hidden email]> writes:
>
>> branch. If the framework branch moves forward, I want my product_A branch to
>> be able follow along : that's a merge of the framework from product_A. In
>> product_A, I might fix something from the framework and need to patch the
>> latter. That's a merge in the other direction.
>
> Instead of doing a mixed ball of wax on product specific branch,
> can't you do the latter by (1) fix something that belongs to the
> framework part of the system on the framework branch, (2) merge that
> to product A branch, and then (3) use that fixed framework code to
> update the product A?  That way you would never have to merge
> product specific part to the framework, which is meant to be product
> agnistic (which is the whole point of your "initial removal" done on
> the framework branch, if I am reading you correctly).

In addition, I would imagine that you have this:

      F+B
     /
 ---X---F
     \
      F+A

where F stands for "framework part", A stands for "product A" and X
is F+A+B (i.e. everything).  The first thing I would do if that is
what you have is to abandon the product specific branches directly
forked from the "everything" and instead form a history of this
shape:

          F+B
         /
 ---X---F
         \
          F+A

That is, make the commit marked F in the updated history, whose tree
has only the framework part, the new "birth" of your company's
source code, where other product specific branches all fork off of.

Then touch the common framework only on its own branch, occasionally
merging that down to (all) product specific branches, change product
specific parts only on their own product specific branch, and merge
only in one direction (i.e. framework to product), never in reverse.

          F+B
         /
 ---X---F-----F'-----F''   ... framework evolves this way
         \            \    
          F+A---F+A'---F''+A'  ... product A evolves this way


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

RE: Splitting a project into branches afterwards

Yohann Bénédic
>In addition, I would imagine that you have this:
>
>      F+B
>     /
> ---X---F
>     \
>      F+A
>
>(...)
>          F+B
>         /
> ---X---F
>         \
>          F+A
>

Hi,

Thank you for your answer :)
I don't understand the difference between the two diagrams. I can see the branch points are different but why is it relevant?

I probably should have included diagrams in my original post. Here is what I have, with your notations, and with Ai, Bi, Fi denoting commits that introduce changes in product A, product B and the framework respectively:

--F1----B1----A1----A2----F2----B2=X

What I wish I had

        A1 ---- A2----+=A
      /                     /
--F1----------------F2=F
      \                      \
        B1---------------+-----B2=B

Thanks to your post, I now realize that merges should only bring new framework stuff into product specific branches and not the other way around (ie. If I happened to have fixed a framework issue in a branch derived from product A, I should rebase it onto the framework, merge it in the framework and then merge the framework into the product A branch, it makes perfect sense).

I don't really care if I can rewrite the history this way (unless it turns out to be super easy) as long as I can set up the repository so that I can work this way from now on. So here is my attempt from the current history, introducing the framework branch and the new product branches with their respective "initial_removal" commits: Ax means remove product A specific code, same for Bx.

                                                     Bx---------+=A (now contains Ax, which is not suitable)
                                                    /   \        /
--F1----B1----A1----A2----F2----B2---+---F3=F
                                                    \   /       \
                                                     Ax--------+=B (now contains Bx, which is not suitable)

Notice that I applied Ax and Bx to F in order to clear it from the product specific code. Yet, doing so will eventually bring Ax to branch A and Bx to branch B, killing them. I can't find a way to avoid this while clearing the F branch other than cherry-picking F3 or any rebase solutions.

Now I believe you're suggesting not to apply Ax and Bx to F, and hence have the product specific code remain in a dead state in F. That will do and it probably is what I will end up doing, unless another idea comes out.

Thank you

Yohann

_________________________________________________________________________________________________________________________

Ce message et ses pieces jointes peuvent contenir des informations confidentielles ou privilegiees et ne doivent donc
pas etre diffuses, exploites ou copies sans autorisation. Si vous avez recu ce message par erreur, veuillez le signaler
a l'expediteur et le detruire ainsi que les pieces jointes. Les messages electroniques etant susceptibles d'alteration,
Orange decline toute responsabilite si ce message a ete altere, deforme ou falsifie. Merci.

This message and its attachments may contain confidential or privileged information that may be protected by law;
they should not be distributed, used or copied without authorisation.
If you have received this email in error, please notify the sender and delete this message and its attachments.
As emails may be altered, Orange is not liable for messages that have been modified, changed or falsified.
Thank you.

N�����r��y���b�X��ǧv�^�)޺{.n�+����ا���ܨ}���Ơz�&j:+v�������zZ+��+zf���h���~����i���z��w���?����&�)ߢf�