Imagine you're creating a completely new version control system, like Git, Mercurial, SVN etc. from scratch. Rather than identifying commits by SHA hashes, you identify them using an ordered sequence of numbers and letters, from
5 etc. If you make a branch from a commit, you call that commit
1a, and then further commits from that are
1d... If you branch from
1a, you get a new commit
1a1, from which follows
1a3... If you go past the end of the alphabet, you loop around to
ab etc. like in Excel.
It looks like this:
1---2---3---4---5 ... 64---65 \ 1a---1b---1c ... 1z---1aa---1ab \ 1a1---1a2---1a3 \ 1a2a
So a summation of the sequence rule would be:
- The name of every commit is incremented from the name of the parent commit, either by incrementing the number, or incrementing the letter.
- Only the last number/letter is "incremented" using the rule above
- A commit name can consist of an alternating string of numbers and letters, where "numbers" can be 1 or more digits, and "letters" can be one or more letters. But you cannot have two strings of numbers, or two strings of letters, in a row.
Now there are two problems I've identified with this, and I'm not sure if there's a solution.
Merge commits. E.g. if commit
1abmerge, what do I name the merge commit? Do I make an arbitrary choice and flip a coin to make the new commit either
1ac? I need to designate one of the parent commits as the "true" parent and increment that name to arrive at the merge commit name. But what logic do I use to conclude which commit is the "true" parent?
If you have multiple branches from the same commit, there's currently no logical way to name the next branch from that commit. If I branch from
1a. The next commit after
1b. If I branch again from
1, I therefore can't use
Problem 1 visualised:
1---2---3---4---5... 64---65------??? \ / 1a---1b---1c ... 1z---1aa---1ab/
And problem 2:
1---2---3 |\ | 1a---1b \ ???
For problem 1, I originally thought of identifying the "ancestor" commit - i.e. the commit that connects all of the commits you're trying to merge, and then following the branch of that "ancestor" until you get to the parent of the merge commit. But I realised that that's fundamentally flawed, because finding the one commit that connects all of your merge commit parents, doesn't tell you which branch to follow to get back to the merge commit - they're all equally valid branches.
The main solution I've thought for branching (problem 2) would be to introduce a separate signifier for branches and commit numbers, maybe separated by a punctuation character. E.g.
1---2---3 |\ | 1a.1---1a.2---1a.3 |\ | 1b.1---1b.2---1b.3 \ 1c.1---1c.2---1c.3 |\ | 1c.2a.1---1c.2a.2 \ 1c.2b.1---1c.2b.2
But that already seems to be ludicrously complex at only a few levels of branching.
So my question is: is there any reasonable and logical approach one could take to name commits using a system like this, or would this system fail from the outset? In particular:
Could you name merge commits in a systematic way, without simply choosing which parent commit to "increment" the name of at random?
Could you name branch commits in this system without names quickly becoming long and complicated to read?
I'm prepared to accept the answer "No to both, this system is fundamentally flawed", but would like to see if there are possible solutions to this problem that I hadn't envisaged.