I had a bad dream I would like to describe, and I need your help to assure me that it has no basis in reality.

In my dream, we have developed a new feature of git called meta-versioning.

This means you can create meta-trees which are snapshots of the current value of all tags and branches, and a little other miscellaneous state of the repository that didn't use to be versioned yet. This allows you to start a meta-branch where you can, for example, rename branches or tags, save all the meta-history for these renamings, all without affecting other meta-branches. Commands that modify the repository in an ordinary way, such as commits to a branch or creating tags, are normally configured to meta-commit to the current meta-branch, so all meta-history is preserved by default. Once you're satisfied with changes in a meta-branch, you can meta-merge it and resolve meta-conflicts such as tags with the same name created independently.

Meta2 history, which stores a snapshot of all meta-tags, is also supported. In fact, for any rational number q, metaq-history exists. A metaq-tree stores a snapshot of the whole metap history for all p < q, except that meta0 history is the history traditional git used to support. These meta levels spring into existence lazily as you reference them, so if you reference metap-history for the first time, then the metaq-history for all p < q is considered to always have contained a single default metap-branch.

The meta-history feature was very difficult to merge to mainline git. This is because the various developers who have worked on it have made branches in conflicting ugly styles, so we had to consolidate these by changing the version control history. Thus, our repository code could eventually be cloned only with versions of git supporting meta-history, which is a bootstrapping problem we had to deal with. We didn't want to just throw away our meta-history, because the code is complicated so hard to fix bugs may yet turn up for which we need the meta-history to debug. We thus added a compatibility mode where, if you clone from a new repository with an old version of git, you see only the current meta-history. This does not require changes in the old version of git. Thus now git developers can clone the current meta-tree of git with an old version of git, compile git from that, hopefully successfully, then pull the full meta-history of git.

Thus, the meta-history project has a happy end.

Meanwhile, another group of developers have developed a new feature to git called infinite versioning.

This means that a repository can contain infinitely many commit objects, even in the same branch. Commits can now have parents that are not necessarily commits, but possibly upwards infinite chains of commits.

When you would like to merge such a chain, you may encounter divergences. These are similar to merge conflicts, but are not the same: they result when a particular tree or blob fails to converge to a stable state, even though there are no two conflicting parents because there is only a single parent. Git helps resolve divergences by inserting conflict markers with all infinite previous versions of that conflict shown, letting you choose to any of them or any combination of them. There's a new git-convergetool to interactively resolve divergences, and a new git-rerererere* that helps reuse recorded resolutions. (git-rerererere* is not the real name of the command, but the real name is too long so people customarily say just git-rerererere*, as git wildcard-expands this uniquely to the right command.)

History need not even be well-ordered, so if you blame or bisect, you may find no first commit that contains a change, but only a descending chain of commits each of which contains it.

The infinite history feature was difficult to merge to mainline git. This is because due to the large number of developers working concurrently to get it right, the feature itself has a complicated and infinite history. Thus, their repository could eventually be cloned only by versions of git supporting infinite history, which is a bootstrapping problem they had to deal with. They didn't want to just throw away their infinite history, because the code is complicated so hard to fix bugs may yet turn up for which they need all the history to debug.

Thus, the developers have decided to change the history of these changes by flattening commits until only a finite history remains. The git server would need a compatibility mode where if you clone from a new repository with an old version of git, you see only this finite section of history. Developers would then be able to clone this finite history at first, build git, then pull the full history. While it is suspected that it may turn out to be impossible to get an understandable finite history, but even in that case they would like to have a bootstrap sequence where you have to pull and rebuild git as few times as possible.

Creating a finite slice of history, however, is complicated, and with many developers working together, it would be nice to have the meta-history feature available for this so they can branch and merge their changes. The problem, however, is that nobody has a version of git that supports both infinite history and meta-history. This causes a severe bootstrapping problem because to create such a version, we need to merge the repositories of the two extensions, which would need such a version of git.

Merging the two features would be far from trivial. For example, the merged version of git needs to allow infinite meta levels of history. More precisely, we would like to allow metap histories for any surreal number p, thus allowing you to insert a level of meta-history at any place without having to renumber meta levels. Renumbering meta levels and merging such renumberings would be supported of course, but as renumbering meta levels is itself a metaq change where q must be greater than all meta levels renumbered, we need to support at least meta levels greater than any increasing chain of meta levels.

As I have mentioned, the implementation of both extension alone is quite complicated, so we really need to use the meta-histories of both extensions to merge them.

Thus, we are now stuck with two extensions we cannot merge and we don't know what to do.

Perhaps a time machine would help so we could change history to delay the start of work of one of the extension after the other, and have it use the git with the other extension as a starting point. We'd prefer an open source time machine whose source history is acyclic. If you have such a time machine, please drop us a line.