The Future of Version Control

https://bramcohen.com/p/manyana

Manyana

A Coherent Vision for the Future of Version Control

Bram’s Thoughts
The thing about how merges are presented seems orthogonal to how to represent history. I also hate the default in git, but that is why I just use p4merge as a merge tool and get a proper 4-pane merge tool (left, right, common base, merged result) which shows everything needed to figure out why there is a conflict and how to resolve it. I don't understand why you need to switch out the VCS to fix that issue.

Even if you don’t use p4merge, you can set Git’s merge.conflictStyle config to "diff3" or "zdiff3" (https://git-scm.com/docs/git-config#Documentation/git-config...). If you do that, Git’s conflict markers show the base version as well:

<<<<<<< left
||||||| base
def calculate(x):
a = x * 2
b = a + 1
return b
=======
def calculate(x):
a = x * 2
logger.debug(f"a={a}")
b = a + 1
return b
>>>>>>> right

With this configuration, a developer reading the raw conflict markers could infer the same information provided by Manyana’s conflict markers: that the right side added the logging line.

Git - git-config Documentation

That still have an issue with the vocabulary. Things like "theirs/our" is still out of touch but it's already better than a loose spatial analogy on some representation of the DAG.

Something like base, that is "common base", looks far more apt to my mind. In the same vein, endogenous/exogenous would be far more precise, or at least aligned with the concern at stake. Maybe "local/alien" might be a less pompous vocabulary to convey the same idea.

After 15 years i still cant remember which is which. I get annoyed every time. Maybe I should invest 15 minutes finally to remember properly

Let’s see if I get this wrong after 25 years of git:

ours means what is in my local codebase.

theirs means what is being merged into my local codebase.

I find it best to avoid merge conflicts than to try to resolve them. Strategies that keep branches short lived and frequently merging main into them helps a lot.

That's kind of the simplest case, though, where "theirs" and "ours" makes obvious sense.

What if I'm rebasing a branch onto another? Is "ours" the branch being rebased, or the other one? Or if I'm applying a stash?

> What if I'm rebasing a branch onto another?

Just checkout the branch you are merging/rebasing into before doing it.

> Or if I'm applying a stash?

The stash is in that case effectively a remote branch you are merging into your local codebase. ours is your local, theirs is the stash.

The thing is, you'll typically switch to master to merge your own branch. This makes your own branch 'theirs', which is where the confusion comes from.

Not me. I typically merge main onto a feature branch where all the conflicts are resolved in a sane way. Then I checkout main and merge the feature branch into it with no conflicts.

As a bonus I can then also merge the feature branch into main as a squash commit, ditching the history of a feature branch for one large commit that implements the feature. There is no point in having half implemented and/or buggy commits from the feature branch clogging up my main history. Nobody should ever need to revert main to that state and if I really really need to look at that particular code commit I can still find it in the feature branch history.