Without changing the DAG, I can arbitrarily move "main" to point at any commit I like in git. This isn't some esoteric action - this is done constantly as part of normal git workflow.
While what people understand as a branch in traditional SCM discussions can only grow by the addition of new versions. Commits/versions belong to a specific and unique branch and once added to the version tree, cannot "move" branches.
While in git, a commit can belong to any number of (git) "branches" which makes presenting a true branch based history (if the DAG contains merges) impossible. Which is why we all end up using a workflow based on rebase instead of one based branch-and-merge.
I've observed how much confusion using the name "branch" for what is a version pointer in git causes to those starting with git. The easiest way I've found to help people is to tell them forget about the word "branch" and think in terms of the DAG and pointers to elements in the DAG.
Sure git is a bit different than P4 or Svn or whatever; they all have unique implementation details. I don’t disagree that git confusion sometimes exists nor that you’ve seen it, but it might make your point clearer to give a specific example, one that knowing a branch is a pointer fixes. I’m not sure if it’s useful to think of commits as immovable; they can be rebased and cherry picked, the “version” (SHA) is another implementation detail. Moving the content of commits around is common standard practice with git. That’s a different type of move than a branch move, not what I was referring to above, but I guess I’m arguing that branching is more about workflows, conventions, and conceptual understanding than how it works technically. You’re right that it’s sometimes useful to know that a git branch is a pointer and super lightweight, but that doesn’t help you differentiate branches and tags, for example. Git has a bunch of features that are ‘just’ a pointer. Knowing that is good for advanced workflows, but not really necessary for basic version control.
For a specific example of where choosing a name ("branch") which obfuscates the fact that you are actually manipulating a pointer, maybe consider what it means to delete a branch? Or create one for that matter.
Same in general programming, being clear on the difference between a reference and referee is vital to proper conceptualize what the operations actually do.
But I'm not sure even that's convincing as after using git for a while it becomes completely instinctual which is why it may not seem important to clearly identify a pointer to a commit and an actual sequence of commits related by the parent/child relationship.
I’m not following. Creating and deleting branches is easy in git without knowing it’s a pointer. What exactly is confusing about it, and how does knowing it’s a pointer help? Creating and deleting branches in Perforce is also easy, and they’re not pointers.
I never got deep enough into the legacy VCSs like Subversion to do things like branching. Or even the peer Mercurial. So I have no other VCS concept of so-called branching.
I don’t get what is the problem with Git’s concept of branching. It is mutable, yes, and commits aren’t somehow marked with the information about what branch it was made on. I can understand that some might expect it to. But why is Git’s “branch” so strange that it doesn’t deserve to call itself that? All technical names are in the end synthetic.
> Without changing the DAG, I can arbitrarily move "main" to point at any commit I like in git. This isn't some esoteric action - this is done constantly as part of normal git workflow.
You can reset to whatever in general. But this is typically not done for the main branch. People who pull it will get an error if you rewrite it completely. Only fast-forward updates are the normal ones (when you go from an ancestor commit to a descendant).
> While in git, a commit can belong to any number of (git) "branches" which makes presenting a true branch based history (if the DAG contains merges) impossible.
A true branch history? When does this matter? You can see that main has commits and things are merged into it. That’s typical. Of course people can make a mess of that (too easy really). But usually you have a few immortal histories (we can call them histories if you want) and things eventually end up in them.
> Which is why we all end up using a workflow based on rebase instead of one based branch-and-merge.
Plenty of people use only merges. Some hate rebase. Even though they shouldn’t.
> I've observed how much confusion using the name "branch" for what is a version pointer in git causes to those starting with git. The easiest way I've found to help people is to tell them forget about the word "branch" and think in terms of the DAG and pointers to elements in the DAG.
In other words you explain to them concretely what it is. Yes? “Branch” is just a name.
> I don’t get what is the problem with Git’s concept of branching. It is mutable, yes,
Exactly like a branch on a tree: It's a living thing, that keeps on growing. The word "branch" refers to the whole thing, regardless of where the tip of it has grown to. Utterly intuitive.
And just like branches on trees grow at their tips, the "branch" pointer in git, where you add stuff, is the latest commit. Of course; where else should it grow?
> and commits aren’t somehow marked with the information about what branch it was made on.
Again, exactly like a branch on a tree: Pluck a leaf from it, and there is no sign on it to say which branch it came from. But you can look at any twig or leaf and see what it's attached to, all the way to the trunk, and where it forks off from the trunk is where the branch begins.
(Somewhere along the length of it, you could score the branch name into the bark of the tree... Nah, analogy getting a bit too literal there. But still, totally intuitive.)
Opinionated branching is super obnoxious. It's much better to let you see the truth with a thin traditional branching veneer, and you can choose to enforce "fast-forwards"ness or not.
Without changing the DAG, I can arbitrarily move "main" to point at any commit I like in git. This isn't some esoteric action - this is done constantly as part of normal git workflow.
While what people understand as a branch in traditional SCM discussions can only grow by the addition of new versions. Commits/versions belong to a specific and unique branch and once added to the version tree, cannot "move" branches.
While in git, a commit can belong to any number of (git) "branches" which makes presenting a true branch based history (if the DAG contains merges) impossible. Which is why we all end up using a workflow based on rebase instead of one based branch-and-merge.
I've observed how much confusion using the name "branch" for what is a version pointer in git causes to those starting with git. The easiest way I've found to help people is to tell them forget about the word "branch" and think in terms of the DAG and pointers to elements in the DAG.