(copied over from lobsters, with links to more material there: <a href="https://lobste.rs/s/odj5y1/why_i_don_t_hate_git_hidden_consistency/comments/dtlwwf#c_dtlwwf" rel="nofollow">https://lobste.rs/s/odj5y1/why_i_don_t_hate_git_hidden_consi...</a> )<p>Haha, I spurred this debate with mitsuhiko over IRC yesterday. I was arguing with him over git vs hg yesterday, and this blog post is obviously his retort. Here is my defence of Mercurial:<p>Mercurial’s design aims to welcome people who come from other VCSes. It started being welcoming to CVS and SVN users, and its CLI mimicked those, as well, as a few ideas of Bitkeeper. Git’s initial design was very bitkeeper-like too, such as branching-by-cloning being the only way to branch. Nowadays, Mercurial also makes some concessions to git users.<p>Despite its various sources of inspiration, Mercurial works hard to keep all of these ideas consistent. Commands rarely grow new options. Many deviations from core functionality are first tested in optional extensions for a long time before going into the core. Lots of time is spent bikeshedding what a command’s name should be, and what language the documentation should use. Consistency is very important. Backwards compatibility is tantamount. The CLI is the UI and the API.<p>A thing git is often lauded for is the simplicity of its internals, which are frequently deemed to be as simple as to not be internal at all. Despite being a binary format, Mercurial’s revlogs are also approximately simple, which is why people sometimes write parsers in other languages.<p>But Mercurial is a lot more than just git-with-a-nicer-UI. There are many exciting features in Mercurial, features that I don’t think will ever make it into git because they are just too different from the way git works. Mercurial Evolve really changes the way we collaboratively edit commits. Templates and revsets can be combined to program interesting extensions. New extensions can scale Mercurial into gigantic repos.<p>And because I think these ideas are so great and must be explored and improved, I will keep using Mercurial, teaching Mercurial, and improving Mercurial
Basically this says, "git's UI was so bad that it forced me to learn the internals, and once I groked the internals git made a whole lot of sense." That summary might sound like I'm trolling but I don't think that's a bad thing (else, why is git so popular?). I've been the mercurial "expert" on my team at work for the past 5 years and I can't count the number of little DAG diagrams I've drawn trying to get people to understand what was <i>really</i> going on with their repository. I'm pretty sure there are a few people who still don't really understand how mercurial works under the hood. Maybe that's a positive aspect of mercurial...but maybe it's not :-)<p>Now, I will say that the internals of mercurial that you need to understand to gain enlightenment seem simpler to me than what you have to know for git. Mercurial has commits and commits have parent reference(s) that link commits together into a DAG. Commits might have a branch label. You move commits from one repo to another with push and pull. You create a commit with two parents by doing a merge. And that's it!<p>Git has those same basic concepts, but you also have to know about the index, and branches (which are really pointers to commits that may or may not be a branch in the DAG), and remote branches, and merges that aren't really merges because they just move the branch (which is a pointer, remember, that's why a "branch" can move) to the head, and all kinds of other interesting (and useful, no doubt) concepts.
Three words against git: Detached Head State<p>I view git as a sort of shibboleth.<p>You can't really understand how git works unless you understand trees as a data structure. That excludes all but the hardcore types.<p>Some designers and CSS experts need to use source control, but Git is too complicated for them.<p>Once you get a detached head state or corrupted repo, then you need a git expert to clean things up. I once committed while in a detached head state, and so git ate my changes and I had to reflog to recover them. That is just insulting.<p>At my job, I work with some designers now, and they always leave the test server in a detached head state.<p>But when I switched from the GitHub client (yuck) to the SourceTree client, most of my concerns went away.
Good article. That old tutorial is scary :)<p>> I screwed up really badly before, merging wrong things together, accidentally deleting data and much more, yet I never lost any data or felt left abandoned by my tool.<p>I can relate for the most part. I can only think of one instance (in over half a decade) where I felt git's shortcomings: there is no way to get a deleted non-gc'd object from a remote to your local repository, even if you try to reference it by its sha1.<p>This happened to me when some bad changes were force-pushed to a repository on Github and did not have access to a machine which had the latest changes. My repository on Github still knew about the old commits, but they were unreachable by git itself.
Do others have examples of software "where the way it works is a crucial part of the user experience"? The one that comes to my mind is lisp macros; if you mess with them for a month or two you can't help but have a pretty good understanding of how they work. Clean internals can colonize your brain in a way that merely clean interfaces can never compete with.
The conceptual model matches the implementation - this is what Don Norman's "Design of Everyday Things" says is good design. When this is the case, a user can interact with the object's interface using logic and intuition and get predictable results.<p>I agree, git really embodies this.
Having grown up w/ git (svn was on the way out when I started programming) and then having had to use svn at a previous employer (I migrated it to git, eventually), I can't fathom a reason to prefer svn or to "hate" git other than ignorance.<p>You can spot an ex-svn user from a mile away by their commit history. We need rehabilitation clinics.
I am getting a message when I push stuff to Github (or any remote) because there is a git config value that I need to set. I just did a search to try to understand the effect of each option for this value, so I could pick the one that best fits how I want git to act. I am approximately 90% sure I understand what each one does, however all of the explanations of them have some element of confusion or lack of clarity. This is the problem of using git.
tangentially, that's a really lovely header font ("jim nightshade"). one of the very few times i've seen a "fancy" font work well in a post like this.