8 ms·
> It’s the alien mental models Hm. I love Git because its core is so simple it fits on a napkin [1]. From such a simple mental model, everything else flows. I
by AceJohnny2 3y ago
> It’s the alien mental models
Hm.
I love Git because its core is so simple it fits on a napkin [1]. From such a simple mental model, everything else flows. It's an extremely simple mental model because it compresses so well: from only the first principles, I can derive the rest.
Any other computer system, I try to dig and find its first principles, but nothing is quite so clean, so I have to keep in mind a bunch of exceptions and add-on warts to understand them, a larger mental load.
That said, I seem to often be the one around my teams most comfortable around Git. I can't explain it. Perhaps I've erased my initial struggle to understand it. Perhaps others don't conceive of Git as a datastructure...
[1] files=blobs (named after the SHA1 hash of its content), dirs=trees=collections of blobs+trees (named after the SHA1 hash of its content), a commit=top-level tree + parent commit(s) + commit comment (named after the SHA1 hash of its content). A branch is a reference is a pointer to the latest commit in a series. Creating a new commit adds to the top and updates the pointer.
- aiunboxed 3y agoYes personally I also can't co relate with git being hard, I mean yes during the initial days of learning you get stuck, but it is the same with everything right ?
- rjblackman 3y agoI tend to agree, however it took learning about git internals to get to this point. Most developers don't read stuff like that. Also git creators made the mistake of using terms like add and checkout to mean completely different things to older version control systems. I think that's where a lot of the confusion stems from.
- saghm 3y agoI think the disconnect is that the "first principles" that you can derive from are implementation details; in other words, git makes the most sense if you embrace the inherent leakiness of the abstraction. > Perhaps others don't conceive of Git as a datastructure The problem is that git doesn't really look much like a datastructure at first glance; it's ostensibly a shell command that you invoke, which makes people look at it in terms of inputs and outputs rather than spending time learning the details of all of the parts that aren't obviously in plain sight. > A branch is a reference is a pointer to the latest commit in a series. Creating a new commit adds to the top and updates the pointer. I think this is a pretty good demonstration of the issue I'm talking about; I've talked to engineers who totally understand git's underlying model but still are incredibly resistant to this definition of a branch, even though it's the accurate one. The idea of a branch conceptually being the entire chain of commits from the most recent one to the initial one is so pervasive that even the term "branch" heavily implies it (when arguably the more accurate analogy would be to call them "leaves"). When the definition of one of the most fundamental concepts defies people's common intuition, the finer details of advanced operations on them like rebasing don't have a chance of being widely understood. Git's failing isn't that it's complex, it's that the only effective logical unit to think about the system is the entire thing, and that lack of abstraction is the alien model to the way we're encouraged to think of things as programmers.
- brabel 3y ago> arguably the more accurate analogy would be to call them "leaves" I don't think so. Branches are the more accurate analogy because two branches can have many commits on top of each of their common, parent commit - so branches grow as tree branches do, not leaves.
- Shish2k 3y ago> so branches grow as tree branches do, not leaves That’s exactly the mistake though - branches (the implementation detail) don’t grow. Branches - under the hood - are “one pointer to one commit”, and they are always the same size. The suggestion to call the implementation “leaves” is because you get a pointer to one commit at the end of the branch, and you can then follow that branch backwards (via the linked-list of parent-commits) until you reach the trunk. But the “branch” is never actually stored anywhere, it is only implied by its ends.
- brabel 3y agoThat makes no sense. Different branches always have a common parent commit which is the "branching point". When you update the branch to point to a new commit, your branch is growing apart from the other. The branch analogy makes much more sense.
- Izkata 3y agoI've shown coworkers "git log --graph --oneline --decorate --all -50" many times and always have them start with it (and even use it throughout stepping them through something) to try and show that structure as we go. I think it helps a bit, but their IDEs go to great lengths to keep them out of the command line, so they're never completely sure what happened when it does something odd to their repo.
- formerly_proven 3y agoidk I clicked something and then there was an error so I deleted the project and started over
- goalieca 3y agoGit is a tree and the nodes are commits. All of the git operations are operations on the tree except for the staging which is a special place to put things before you make a node out of it. Edit: it’s not a tree it’s a directed graph. But I find tree a very simple approximation that most people without a computer science degree can understand.
- nerdponx 3y agoA Git repo is a DAG of commits, and each commit is a snapshot of your files, along with some metadata. Commits are immutable and point to their own parents. Branches and tags are pointers or labels on commits. Everything follows from that.
- kibibu 3y agoFor me the parts that break my mental model are stuff like trying to check out an historical revision and ending up with a scary warning about a detached HEAD (wtf), or not being able to easily start a new branch from an older commit (like you could very easily in mercurial).
- nerdponx 3y ago> detached HEAD Believe it or not this actually fits into the model, albeit with a little more complexity. HEAD is a special label that can point to other labels, specifically to "heads" which are the labels that represent branch tips. Normally when you make a new commit, the current pointed-to branch head advances forward to point to the new commit, and the HEAD pointer follows that branch head pointer. "Detached HEAD" is whenever HEAD points directly to a commit rather than a branch head. When making new commits in this state, there's no branch head to advance, so HEAD itself will advance to the newly-created commit. However this is a little dangerous because once you switch HEAD to something else, commits in the DAG without a branch head at the tip/leaf would be considered "unreachable" and would be invisible in logs, and eventually will be deleted by the garbage collection process. It's still ultimately all about operations on the commit DAG and labels/pointers therein, which to me is really elegant. What is not necessarily clear from that mental model is what any given operation will actually do to the files in your repo (called the "work tree"). But Git is very consistent here and usually tries to keep the work tree in sync with whatever is ultimately pointed to by HEAD, unless you specifically ask it not to (as with `reset --soft`). > not being able to easily start a new branch from an older commit Unfortunately this is a case of CLI docs obfuscation: git branch new-branch old-commit