3

Say I have:

           X         Z
o-----o----o-----o---o A
 \        /       \ /
  o------o---------o B
         Y

Suppose that A and B intentionally diverge, because (say) A is a public branch and B is a company-internal branch (which needs to have some differences for technical reasons and potentially has secrets that should not be in the open-source release). Suppose X is a commit that intentionally does not pick up some of the changes in Y.

What is the best way to accomplish the following with Git?

  1. Changes from Y that were intentionally omitted from the merge at X are not re-applied at Z.
  2. I can publish a public version of A where the merge at X appears as a single squashed commit, so that none of the potentially secret information in Y (or other internal commits) shows up in the public revision history.
Josh Haberman
  • 4,170
  • 1
  • 22
  • 43

1 Answers1

3

I don't think the diagram you've drawn is possible in a single Git repository (given your secrecy/etc constraints). The only similar approach I can think of that would accomplish what you want is to keep three branches: public, private, and shared. Commits in shared are merged into both public and private when they're finished. This will allow divergence across the public/private branches, without the worry about re-applying diffs, because the commits will have been actually merged and thus will be genuine ancestors that git won't try to re-apply.

You can probably meld this with your desired approach, if you prefer, by developing for a while in private, and then rebasing to tease it apart into shared and private parts. Then you can merge the shared part back into private, and into public at the same time. Then you have the eventual behavior I describe in my first paragraph, but can develop more or less like you were hoping to in your question.

amalloy
  • 89,153
  • 8
  • 140
  • 205