You can get kinda far without really understanding what's going on, but if you stop and have to learn something really fundamental the "good" kids just seems to manage. Once things pick up they can excel because the have truly moved on. the previously "good" ones are still copy/pasting from past work or tutorials and get brackets wrong whereas the "slow" ones are now perfectly happy writing from scratch and thinking for themselves.
Today, most JS devs don't know how "this" works, most python devs never used pdb, most git users picture a branch like a diverging chain of commits and not a moving label, etc.
Again it's not the people's fault: they are required to be productive very quickly. There is competitive pressure. So they aim for what's good enough to make things that looks right. Can you blame them ?
Few jobs pay devs to update their skill on company time, and not everyone will spend an hour a day learning new things instead of playing with the kids, doing exercice or going out with friends.
Ok, I'll bite: can you explain that little more please?
A "branch" doesn't really have any special status in git. All it is is a pointer to a particular commit. Literally, that is all it is, even in the data structures. It has no additional ontological existence beyond that. When you make a commit to a "branch", all that happens is that git moves the branch marker along to the next commit. All of the "specialness" of a branch is what is in that behavior.
You can do anything you want with that branch marker, such as yanking it to a completely different part of the tree via "git reset --hard $NEW_COMMIT", and while you may confuse humans, you haven't confused git in the slightest. On the flip side, since branches don't actually "exist", it is perfectly sensible to "merge" with a direct commit hash, because that's all a branch is; a pointer to a hash. You can pick up that pointer and drop it down where ever you want.
(A tag is the same thing as a branch, except that when you're "on" a tag and make a commit to it, git does not advance the tag. But almost all it is is a pointer to a commit. Technically it can carry a bit more data, like a signature, but as far as the core structure is concerned it's just a commit.)
I am not the original poster, but I have a training I give at work for git, and it is heavily based on making sure this understanding is presented. (The other reason I wrote my own training rather than reusing any of the many other existing ones is mine makes sure to walk the trainees through the confusing states you can get into, then we explain what happened, why, and how to correctly get out of them. They follow along as we all manipulate a repository, and the training actually spends quite a bit of time in a "detached head" state, checking out, merging, and resetting to commits directly.)
In git, a branch is NOT like a wooden branch on the trunk of a tree, although it ends up being at the top of one, which makes the analogy ok.
A git branch is the same thing as a git tag, except it moves automatically when you commit from it.
You can see it as a lightweight label attached to a commit. If your HEAD is itself attached to a branch (HEAD is also a lightweight label, but this one is like a red sticker on a map saying "you are here"), when you do "git commit", the branch label is moved to the newly created commit.
Hence, you can have several branches on a single commit, and you can move branches around: they are just labels. You can also have branches with different names locally and in a remote, or have a branch with the same name, but on different commits locally and in a remote.
A branch is like a reference, it's useful to tell git what place in the history you are talking about, without referring to a commit in particular. It is a moving reference because the place in history you talk about is always changing: it's the top of a chain of commits, the ever changing last thing you worked on for this particular part of the history.
We want branches because they are a convenient way to say "I'm going to do something on the latest commit of this part of the history":
- "git checkout branch_name" => I'm now working on this part of the history, gimme all the latest stuff you got and consider everything I do is now related to it.
- "git checkout branch_name /file/path" => Get the latest version of the file from this part of the history and bring it on my hard drive
Of course, you can put a branch at a commit that is not yet the top of a chain of commits. But soon this commit will become the top of a new chain of commits because when you'll commit from this branch, a new commit will be attached to the previous one, diverging from the original chain, and the branch label will be moved to it. You now have a fork of two chains of commits, both of them having a different branch label at their top:
"git checkout commit_hash && git checkout -b new_branch_name" => I'm going to consider this commit as a new starting point and work from that.
In fact you can move a branch pretty much anywhere, create one or delete one at anytime, including "master", which is not a special case, just one created automatically on the very first commit.
This is also why if you "git checkout commit_hash" instead of "git checkout branch_name", git warns you you are in a "detached HEAD" (the "you are here" label is attached to a commit directly, not a branch label). Indeed, a chain of commits (the stuff that looks like a wooden branch on a trunk in graphics) can exist without a branch label. But it won't be convenient to reference: looking for the hash of the newest, latest commit, every time you want to mention it is tedious. Besides, git will run "git gc" automatically once in a while, deleting diverging parts of the history with no branch or tag, so you may lose this work.
This makes it clear that tags are labels like branches, only they don't move. They serve the purpose of having a static reference to a fixed point in time: both allowing you to easily talk about it, and let git know you want to keep this around.
All that stuff is way clearer with a visual explanation. For my Git training, I bought a fantastic toy for 10yo with magnets that let me build a 3D history tree and use post-its to represent branches and tags. It's instantly obvious. It's really fun, you can move stuff around and show what each command does to the tree. After that, git seems much more accessible, and you just grunt at the terrible UI ergonomics.
The problem is that they are easy to spot only for somebody with experience in the field. This is why companies sometime pay good freelancers to help with hiring: they can assess what the company can't.
And once they do, they realize quickly that:
- there are few experts
- most resumes are bs
- experts are expensive
- they probably don't need them for most tasks and the bs resume dev may be ok, given the price and skill constraints
- they had one expert internally all along, doing half the job of the rest of the entire team and they should make sure this expert stays
I have a friend that had some home remodeling work done, poorly. The friend said to me, "But, they were professionals!" I responded, "Well, that's the problem. A professional is someone who will do the least amount of work in the least amount of time for the most amount of money. If you want someone who actually cares about the work, hire a craftsman instead of a professional."