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