2 ms·
The fundamental issue with git is that it doesn’t have branches. What git calls a “branch” is a misnomer - it should be called a version/commit pointer. In a
by derriz 3y ago
The fundamental issue with git is that it doesn’t have branches. What git calls a “branch” is a misnomer - it should be called a version/commit pointer. In a tree of versions/commits a single pointer does not identify a "path" through the tree of versions.
When talking about VCSs in general, the word “branch” is used to mean a linear sequence or chain of versions connected by a parent/child relationship. Unsurprisingly many git users also have this mental picture of "branches" in git which causes confusion - but it's is not really the fault of users.
For example, if the current main/master commit in git has two parents (which it will have after a merge) then it is not possible to know with certainty which of the two parents was previously pointed to by main/master and which came from the feature "branch". Thus git is unable to present a picture/log of the main/master branch as a linear sequence of commits - all it knows about main/master is what it currently points to. So when you log, it has to present the entire tree which means mingling up commits which were master/main commits and which represent work on feature "branches".
With other "true" branching VCSs, a branch identifies an actual sequence of commits and is not just a pointer to a single version. Thus you can navigate the history even after merging. You can ask it to only show main/master commits or only show commits created on a specified branch. While once a git "branch" is advanced or points to a new commit/version, the fact that it previously pointed to a specific parent is lost.
So git "branches" can only identify a linear sequence of versions if every commit only has a single parent. And this is what the rebasing workflow gives you. And this is why the rebasing workflow, dissatisfying as it is, provides the least friction when using git.
If you use merges, then you have commits with multiple parents and now your main/master _pointer_ can no longer be used to identify a single path/sequence of commits. If main/master points to a commit with two parents, git does not record which of the parents came from main/master and which represents work which was, at one time, pointed to by the feature branch.
So while I prefer VCSs with true branches so that merge workflows can be supported but I've given up trying to use such workflows with git - it's just not supported in a useful way.