Re: Private/public branches/repos workflow

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jerome Martin <tramjoe.merin@xxxxxxxxx> writes:

> I have an application that lives in a git tree. That application is a
> commercial product, but we have decided to dual-licence it and release
> an open-source version of it, along with all further commits to it.
> Preparatory work for this has been done, and I now have two (let's
> ignore the other) branches in my git tree, 'public' and 'private'.
>
> The problem is, I cannot simply push the public branch on a public
> repository, because the history contains a lot of stuff that are not
> to be publicly released.

To do this properly without heavy cherry-picking, you would need a lot of
discipline.  Not just "you" as an integrator, but everybody in your
development organization who has an access to the 'private' branch.

What you have is something like this:

                   O   public

 ...---x---x---x---X   private

where X is the tip of private branch that contains unreleasable stuff,
while O is the tip of public branch, a redacted version fit for releasing
to the general public.  The former has a lot of history behind it, commits
marked with 'x' that you are ashamed of showing to the public ;-), while
the latter does not have any history behind it (the initial code dump).

Of course, if you build some feature that is not proprietary directly on
top of X and make a commit 'a', and try to merge that to the public
branch, the resulting history will become this, pulling all the history
behind X:
                    O----*   public
                        /
 ...---x---x---x---X---a   private

Unlike "merge tracking" tacked on to some other systems, a merge in git is
a statement you make: "I looked at all the histories behind all the
commits I am merging, and decided that this tree I am recording as the
merge suits the purpose of my branch better than any of the parents".
Merging 'a' is not "The change between a's parent and a was cherry picked
onto this branch" (i.e. what mergeinfo records for SVN).  In short, if you
want to keep your x's private, you have to promise yourself that you will
never ever merge private to public.

        Side note.  This is exactly a same discipline for managing the
        maintenance track for the released version and the development
        track for the next release in the open source world.  You queue
        fixes to the maintenance track, and you may merge the maintenance
        to the development, but you never merge the development track to
        the maintenance, because you do not want to pull new features from
        the development branch into the bugfix only branch.

First of all, you would do this once before making any changes:

    $ git checkout private
    $ git merge -s ours public

This will create a new commit at the tip of private, that records that all
the histories of public is now contained in private, but the recorded
state (i.e. the tree) is identical to that of X.  Let's call this commit S
(it is a merge that synchronizes two independent histories):

                     O   public
                      \
 ...---x---x---x---X---S   private

Then, from here on, your developers have a choice to make whenever
starting to work on a new thing, be it a bugfix or a feature.

If the change will _never_ be released to the public, you can continue
building on your private branch.

                     O   public
                      \
 ...---x---x---x---X---S---x---x   private

On the other hand, if it will _eventually_ be merged to the public, then
you fork a topic branch from public, build it on that branch:

                       a---a---a---a  feature-A
                      /
                     O---o---o---o  public
                      \
 ...---x---x---x---X---S---x---x   private

and merge it to public:

                       a---a---a---a  feature-A
                      /             \   
                     O---o---o---o---*  public
                      \
 ...---x---x---x---X---S---x---x   private

I depicted such a topic as "feature-A" that consists of four commits 'a'
in the pictures above.  Since you made the initial merge S, open source
world may have added three commits 'o' to improve your system and you also
have a few more commits 'x' that are secret.

The private branch can take the result of the work done on the topic
branch, either by merging public wholesale:

                       a---a---a---a  feature-A
                      /             \   
                     O---o---o---o---*  public
                      \               \ 
 ...---x---x---x---X---S---x---x-------*  private

in which case you will also get the open source improvements 'o', or by
merging that particular topic alone:

                       a---a---a---a...    feature-A
                      /             \  . 
                     O---o---o---o---*  .  public
                      \                  .
 ...---x---x---x---X---S---x---x----------*  private

in which case your private branch will not (yet) have the three 'o' open
source improvements.

Note that you may consider some of your features "differentiating edge"
that you may want to keep private for one year and then release it to the
public.  In such a case, you can even choose to merge feature-A to private
first:

                       a---a---a---a...    feature-A
                      /                . 
                     O---o---o---o      .  public
                      \                  .
 ...---x---x---x---X---S---x---x----------*  private

and after a year, you can merge it to public to arrive at the previous
picture.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]