Junio C Hamano <gitster@xxxxxxxxx> writes: > As I already said, I do not think "mostly common paths" case should be > encouraged to begin with. As far as I know (and you can guess by now that > I know reasonably well about git), you do not gain anything by not having > the ancestry link between '?' and 'B', except that it would make conflict > resolution at '*' extremely difficult. There is only downside without any > upside in "mostly common paths" disjoint merge. There is one case "mostly common paths" disjoint history can be useful. Imagine you have a hitherto proprietary software project and want to go open source. Perhaps your intention is to have an open source version and an enhanced commercial version. The project contains some third-party vendor software outside your control, and you have replaced them with open source equivalents or disabled features that depend on them. Your history may look like this: o---o---A oss-base / ---o---o---o---o master where master is the primary version you will continue shipping to your paying customers, with proprietary third-party components and features that depend on them. Commits on oss-base were your work to prepare the tree into a releasable shape, removing these proprietary stuff along with some features. But you cannot publish oss-base (commit A) to the public. "git log" will show all the history that leads to it, with all the third-party stuff you do not have license to distribute in the source form. The older parts of the history may even have site password at customer installation you have committed by mistake and eradicated long time ago. If you run this three command sequence (in this message, I am assuming that you keep the index and the working tree files intact in an updated implementation of --orphan, which is different from the suggestion to support "no common paths" case I mentioned in the previous message): $ git checkout --orphan oss oss-base $ git checkout oss-base $ git merge -s ours oss you will get a history of this shape: X oss \ o---o---A---B oss-base / ---o---o---o---o master with commits X, A and B all recording an identical tree. The oss branch (commit X) is now safe to publish. Once you have done this, further you can: $ git checkout master $ git merge oss-base which gives you a history of this shape: X oss \ o---o---A---B oss-base / \ ---o---o---o---o---Y master This merge Y has to be done carefully. It inherently has to be an evil merge because oss-base wants to replace some proprietary stuff with open source counterparts while you may want to keep using the proprietary ones you have support contract for in your paying customer release you will make from the master branch. So at Y, you will most likely be reverting some work you did on oss-base branch since it forked from master. After setting it up, this arrangement allows you to: - accept changes from public, and/or build changes for public, to advance "community version" on the oss branch on top of X; - from time to time, merge oss to oss-base; - from time to time, merge oss-base to master. and the histories will continue like this: X---C---C---C---C oss \ \ o---o---A---B-----------* oss-base / \ \ ---o---o---o---o---Y---P---P---*---P---P master with community commits C (either contributed from the public or you developed yourself and gave to the community) on oss branch, with proprietary commits P that record your own proprietary work on master branch. Note that oss-base branch is not used to produce nor record any commit on its own---it is merely to ease the merging from oss and master by providing X-B link to serve as a convenient common ancestor to make later merges easier. Note also that it would be the most convenient if you kept both the index and the working tree intact, if "checkout --orphan" is to be used as an ingredient for this workflow. It _might_ actually make sense not to make the "git checkout --orphan" an independent feature that can be randomly abused or misused, but package the three-command sequence to create the A-B-X open triangle above into a separate command, i.e. $ git branch --orphan oss would create a new branch "oss" with its own root commit X that records the same tree as the current HEAD A, and immediately merge X back into A to produce B, again recording the same tree, and advance the current HEAD to point at B, like so: X oss \ ---o---A HEAD --> ---o---A---B HEAD -- 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