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 1
, 2
, 3
, 4
, 5
etc. If you make a branch from a commit, you call that commit 1a
, and then further commits from that are 1b
, 1c
, 1d
... If you branch from 1a
, you get a new commit 1a1
, from which follows 1a2
, 1a3
... If you go past the end of the alphabet, you loop around to aa
, 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
65
and commit1ab
merge, what do I name the merge commit? Do I make an arbitrary choice and flip a coin to make the new commit either66
, or1ac
? 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
1
I get1a
. The next commit after1a
is1b
. If I branch again from1
, I therefore can't use1b
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.