1. 20

    Sad :-( I still think Mercurial far better meets the needs of most people, and that the chief reasons for git’s popularity are that Linus Torvalds wrote it, GitHub, and that Linus Torvalds wrote it.

    That said, I did end up switching from BitBucket/mercurial to GitHub/git a few years ago, simply because it’s the more pragmatical thing to do and I was tired of paying the “mercurial penalty” in missed patches and the like. I wrote a thing about it a few ago: https://arp242.net/git-hg.html

    1. 6

      Why do you think hg is better for most people? I honestly find it vastly more complex to use.

      1. 15

        The hg cli is light years ahead of git in terms of intuitiveness.

        1. 6

          I’d say it’s years behind ;)

          1. 10

            How long have you been using Mercurial? I find most people who dislike Mercurial’s UI, are mainly coming from years of experience with Git. I disliked Mercurial at first as well, but after a few years of forced usage it clicked. Now I appreciate how simple and well composed it is and get frustrated whenever I need to look up some arcane Git flag on StackOverflow.

            In general, I’d say you need several years experience with both Git and Mercurial before you can draw a fair comparison.

            1. 3

              I used mercurial for about 2 years before using git.

              1. 3

                Sorry if my post came across a bit accusatory (not my intent). In that case I guess to each their own :).

              2. 3

                but after a few years of forced usage it clicked.

                I’m pretty sure that git clicked for me in a much shorter timeframe.

                1. 1

                  Me too, but I know many (otherwise perfectly competent engineers) 5-10 years in who still don’t get it and aren’t likely to.

              3. 9

                I’m going to strongly disagree. I’ve used git intensively and I find Mercurial to be a well-designed delight. I’ve run across features that Mercurial supports flawlessly, with a nice UI, and Git requires a hacky filter-branch that takes hours to run and doesn’t even behave correctly.

                IMO, a lot of the badness in projects is down to Git badness. it doesn’t scale and people feel compelled to break things down into tiny sub-projects.

                The only reason Git is winning anything is GitHub’s support of it.

                1. 3

                  The only reason Git is winning anything is GitHub’s support of it.

                  Why then was github ever used in the first place? Kind of a strange proposition.

                  1. 1

                    Network effect of the social network is pretty important.

                    1. 1

                      Why would there ever be a network effect in the first place if git was so bad that github was the only reason to use it. I get that the argument technically holds but it seems very unlikely.

            2. 8

              You find mercurial more complex to use than git? That’s an… unusual view, to say the least. The usual recitation of benefits goes something like this

              • Orthogonal functionality in hg mostly has orthogonal commands (compare git commit, which does a half-dozen essentially unrelated different things).
              • hg has a somewhat more uniform CLI (compare git branch -a, git remote -v, git stash list).
              • hg either lacks or hides a bunch of purportedly-inessential and potentially confusing git functionality (off the top of my head, partial commits aren’t baked into the flow a la git’s index/staging area; and rebasing and history rewriting are hidden behind an extension).

              I personally prefer git, but not because I think it’s easier or simpler; I’m more familiar with it, and I find many of those purportedly-inessential functions to be merely purportedly, not actually, inessential.

              1. 5

                One more thing I like about mercurial that the default set of commands is enough for >90% of people, and that everything else is “hidden” in extensions. This is a very different approach than git’s “kitchen-sink” approach, which gives people 170 commands (vs. Mercurial’s 50, most of which also have much fewer options/switches than git).

                Git very much feels like “bloatware” compared to Mercurial.

                1. 3

                  I used git for many years, and then mercurial (at FB) ever since we switched over. The cli interface for mercurial is definitely more sensible, crecord is delightful, and overall it was fine. But I was never able to build a mental model of how mercurial actually worked. git has a terrible interface, but it’s actually really simple underneath.

                  1. 1

                    I didn’t think that underneath they were different enough to matter much. What differences do you mean? I guess there’s git’s remote tracking stuff. Generally, it seems like they differ in how to refer to and track commits and topological branches, locally and remotely. (IMHO, neither has great mechanisms for all the things I want to do.) Mercurial is slightly more complex with the manifest, git is more complex with the staging area that feels absolutely critical until you don’t have it (by using hg), at which time you wonder why anyone bothers with it. I’m a heavier hg user than git user, but that’s about all I can come up with.

                  2. 2

                    You find mercurial more complex to use than git?

                    I actually found – in a professional shop – mercurial far more complex to use. Now, the fact is that mercurials core – vanilla hg is IMHO absolutely without doubt vastly superior to git. Git keeps trying to make the porcelain less painful (including a release just a bit ago) – but I still think it is ages behind.

                    The problem is – I never used vanilla mercurial in a professional environment. Not once. It was always mercurial++ (we used $X extension and $Y extension and do it like $Z) which meant even if I knew hg, I felt painfully inexperienced because I didn’t know mq, share, attic, collapse, evolve, and more… not to mention both the bigger shops I worked with using mercurial has completely custom workflow extensions. I suspect part of this was just the ease of writing mercurial extensions, and part of it was wanting to fall into a flow they knew (mq, collapse). But, regardless of how we got there, at each place I effectively felt like I had to relearn how to use the version control system entirely.

                    As opposed to git, wherein I can just drop in and work from day one. It might be less clean, it might be more finicky and enable things like history rewriting by default. But at the end of the day, the day I start, I know how to generally function.

                    I am curious how Mercurial would have faired if instead of shipping default extensions you had to turn on – if they had just baked a little more functionality, to try to cover the 80% of what most shops wanted (not needed, I think most could have gotten by with what vanilla mercurial had) – if the shop to shop transition would have been easier.

                    1. 2

                      mq, I think, is responsible for many of the “mercurial is too complicated” complaints people have. Evolve, if it ever stabilized and ships with core hg would really enable some killer capabilities. Sadly for social and technical reasons it’s perpetually in beta.

                    2. 1

                      whoa, no index? Admittedly I didnt really use index as intended for several years, but now its an important part of my workflow.

                      1. 1

                        In Mercurial, commits are so much easier to make and manipulate (split, fold, move), that you don’t miss the index. The index in git is just a limited special cased “commit”.

                        1. 3

                          The index in git is just a limited special cased “commit”.

                          I disagree.

                          The index is a useful way to say “these lines of code are ready to go”. If you are making a big commit, it can be helpful to add changes in logical blocks to the index as you go. Then the diff is not polluted with stuff you know is already fine to commit.

                          You might say, “why not just make those changes their own commits, instead of trying to do one big commit?” That’s a valid question if you are talking about a 200 line commit or similar, but sometimes the “big” commit is only 50 lines. Instead of making a bunch of one line or few line commits, its helpful to “git add” small chunks, then commit at the end.

                          1. 0

                            You can as well amend to a commit instead of adding to the index.

                            1. 3

                              True, but all thats doing is bastardizing the commit process. If you are committing a one line change, just to rebase minutes or hours later, thats not a commit.

                              Rebase to me is for commits that were intended to be commits, but later I decided it would be better to squash or change the history. The index is for changes that are never meant to be a full commit on their own.

                              1. 1

                                Having a distinction between draft and published phases in mercurial I think makes it easier to rewrite WIP work. There’s also a number of UI affordances for it. I don’t miss the index using mercurial. There’s also academic user interface research that shows the index is a big conceptual barrier for new users.

                                1. 1

                                  There’s also academic user interface research that shows the index is a big conceptual barrier for new users.

                                  this isnt really a valid point in my opinion. some concepts are just difficult. if some goal can be achieved in a simpler way i am on board, but I am not a fan of removing useful features because they are hard to understand.

                                  1. 1

                                    But the point is the index is hard to understand and unnecessary.

                                    There’s no need to have a “commit process”. Just commit whatever you want and rewrite/amend it for as long as you want. As long as your commits are drafts, this is fine.

                                    Is the problem the word “commit”? Does it sound too much like commitment?

                                    There’s no need to have two separate ways to record changes, an index, and a commit, each with different degrees of commitments. This is multiplying entities beyond necessity.

                                    1. 1

                                      That’s your opinion. The index is quite useful to me. I’d rather make a proper commit once it’s ready, not hack together a bunch of one line commits after the fact.

                                      1. 2

                                        The index is a commit. Why have two separate ways of storing the same sort of thing?

                                        Also, it’s not my opinion that it’s hard to understand and unnecessary; it’s the result of usability studies:

                                        https://spderosso.github.io/oopsla16.pdf

                                        You’re also not “hacking together” anything after the fact. There’s no more hacking together after the fact whether you use git amend (hypothetically) or git add. Both of those mean, “record additional changes”.

                                        1. 0

                                          It seems you have a fundamental misunderstanding of the difference between add and commit. Commit requires a commit message.

                                          1. 1

                                            This isn’t a useful distinction. You can also create commits with empty commit messages in both git and Mercurial.

                                            With both git and Mercurial you can also amend commit messages after the fact. The index in git could well be implemented as a commit with an empty commit message that you keep amending and you wouldn’t notice the difference at all.

                                            1. 1

                                              you keep amending and you wouldn’t notice the difference at all.

                                              yeah, you would. again it seems that you either dont know git, or havent used it in some time. when you amend a commit, you are prompted to amend the message as well. another facet that doesnt exist with git add, because add doesnt involve a message.

                                              if you wish to contort git internals to suit your agenda thats fine, but git add has perfectly valid use cases.

                                              1. 0

                                                you are prompted to amend the message as well.

                                                This is UI clutter unrelated to the underlying concepts. You can get around that with wrappers and aliases. I spoke of a hypothetical git amend above that could be an alias that avoids prompting for a commit message.

                                                Don’t git users like to say how the UI is incidental? That once you understand the data structures, everything else is easy? The UI seems to have locked you into believing the index is a fundamentally necessary concept, but it’s not. It’s an artifact of the UI.

                                                1. 1

                                                  The UI seems to have locked you into believing the index is a fundamentally necessary concept, but it’s not.

                                                  Nothing has locked me into believing its a necessary concept. Its not necessary. In fact, for about 7 years I didnt use the index in any meaningful way.

                                                  I think what you are missing is that Im not compelled to use it because its the default workflow, I am compelled to use it because its useful. It helps me accomplish work more smoothly than I did previously, when I would just make a bunch of tiny commits because I didnt understand the point of the index, as you still dont.

                                                  The argument could be made to move the index into an option, like somehow make commit only the default workflow. Im not sure what that would look like with Git, but I dont think its a good idea. It would just encourage people to make a bunch of smaller commits with meaningless commit messages.

                                            2. 1

                                              You have a set of things you want to accomplish. With git, you have N+1 concepts/features/tools to work with. With hg, you have N (because you drop the index). That means you have to expand your usage of the remaining N.

                                              Specifically, since you no longer have this extra index concept, you now expand commits to cover the scenarios you need. Normally, you’d make an initial commit and then amend a piece at a time (probably with the interactive curses hunk selector, which is awesome.) If you’re unsure about some pieces, or you have multiple things going on that you’d like to end up in separate commits, you can always make a series of microcommits and then selectively collapse them later. (In practice, it’s even easier than this, because of the absorb extension. But never mind that.)

                                              Yes, those microcommits need commit messages. They don’t need to be good ones, because they’re temporary until you squash them out of existence. I usually use a one word tag to specify which of the separate final commits they belong to. (If you don’t have separate final commits, you may as well amend, in which case no messages are needed.)

                                              …or on the other hand, maybe mercurial ends up with N+1 concepts too, because phases really help in keeping things separate. As I understand it, one reason git users love the index is because it keeps rapidly changing, work in progress stuff separate from mostly set in stone commits. Phases perform the same purpose, but more flexibly, and the concepts are more orthogonal so they compose better. In my opinion.

                    3. 6

                      I never particularly liked git and find it unintuitive, too.

                      I wouldn’t consider myself a git poweruser. But whenever I had to work with alternatives I got the feeling that they’re just inferior versions of git. Yeah, maybe the usage was a bit more intuitive, but all of them seemed to lack things that I’d consider really basic (bisecting - hg has that, but e.g. svn has not - and shallow copying - not avaible in hg - are examples what I often miss).

                      1. 3

                        Mercurial was actually my first DVCS, and like you I ended up switching to git not out of a sense that it was technically better, just more pragmatic. For me, the change is more of a mixed bag, though. It is definitely the case that Mercurial’s UI is worlds better, and revsets in particular are an amazing feature that I sorely miss, but when I made the switch I found that the way git handles branches was much more intuitive to me than Mercurial’s branch/bookmark system, and that the affordances around selectively editing commit histories were very much worth the risk in terms of being able to manage the narrative of a project’s history in a way that makes it more legible to others. Ultimately, I found that git’s advantages outweighed its downsides for my use case, since learning its UI idiosyncrasies was a one-time cost and since managing branches is a much more common occurrence for me than using revsets. That said, I think this is a really unfortunate development.

                        1. 2

                          I occasionally convert people’s git repos to hg for my use. Stubborn like that.

                        1. 1

                          I think it’s important the separate “can we” and “should we” do this. It’s hard for me to imagine uses of this that aren’t harmful; maybe some kind of early intervention programs?

                          But it’s not implausible that this can be done. As one example, Fetal Alcohol Syndrome produces distinctive facial features and a disproportionate rate of criminality.

                          1. 52

                            Go has community contributions but it is not a community project. It is Google’s project. This is an unarguable thing, whether you consider it to be good or bad, and it has effects that we need to accept. For example, if you want some significant thing to be accepted into Go, working to build consensus in the community is far less important than persuading the Go core team.

                            This is, essentially, not that different from how most projects work. Even projects which have some sort of “community governance” seldom have voting rounds where everyone can vote. Only contributors/core members can vote.

                            Accepting all PRs is clearly not a good idea, so you need to do some gatekeeping. The biggest source of disagreement seems to be on exactly how much gatekeep is needed. The Go authors have pretty clear visions on what should and should not be in the language, and gatekeep a bit more than some other languages. Putting stuff in the language can also be problematic (see: Python’s := PEP drama).


                            On the specific point of generics (sigh, again), I think the premise of that tweet is wrong. It suggests that the overwhelming majority of the community is just screaming for generics, and the Go Overlords stubbornly keep say “no”. That’s not really how it is. In the most recent Go survey 7% gave “lack of generics” as a response to “what is the biggest challenge you face today?” which is hardly overwhelming (although it’s not a clear “would you prefer to see generics in Go”, so not a complete answer).

                            Anecdotally, I know many Go programmers who are skeptical or even outright hostile to the idea of adding generics to the language, although there are obviously also many Go programmers who would like to see generics. Anecdotally, I’ve also noticed that preference for generics seems negatively correlated to the amount of experience people have with Go. The more experience: the less preference for generics. I’ve seen people with a C# or Java background join our company and strongly opine that “Go needs generics, how could it not have them?!”, and then nuance or even outright change their opinion over the months/years as they become more familiar with the language and why the decisions were made.

                            The author of that tweet claimed in the Reddit thread:

                            I am suggesting that implementation of generics will be easy . All am suggesting is we (community) should implement prototype or so proof of concept and present it to committers .

                            Which seems to suggest that this person is not very informed on the topic. The Go authors have been writing and considering generics for at least 10 years, and thus far haven’t found an approach everyone likes. You can reasonably agree or disagree with that, but coming in with “oh it’s easy, you can just do it” is rather misinformed.

                            The Elm guy had a good presentation a while ago (“The Hard Parts of Open Source”) where he shared some of his experiences dealing with the Elm community, and one of the patterns is people jumping in on discussions with “why don’t you just do […]? It’s easy!” Most top-of-the-head suggestions to complex problems you can type up in 5 minutes have quite likely been considered by the project’s authors. They are not blubbering idiots, and chances are you are not genius-level smart either.

                            This is also the problem with a lot of the “conversation” surrounding generics in Go. People like this guy jump in, haven’t seem to informed themselves about anything, and shout “why don’t you just …?!”

                            Sidenote: I stopped commenting on anything Go-related on /r/programming as there are a few super-active toxic assholes who will grasp at anything to bitch about Go (even when the thread isn’t about Go: “at least it’s not as bad as Go, which [. rant about Go ..]”. It’s … tiresome.

                            1. 26

                              I think the premise of that tweet is wrong. It suggests that the overwhelming majority of the community is just screaming for generics, and the Go Overlords stubbornly keep say “no”. That’s not really how it is.

                              Be wary of selection bias here: if someone really thought generics was important they wouldn’t be in your community to be asked the question. If the goals of the language are to serve the people already using it, thats a fine thing, but if it’s to grow then that’s harder to poll for.

                              1. 10

                                Every community is biased in that sense. People who dislike significant whitespace aren’t in the Python community, people who dislike complex syntax aren’t in the Perl community, etc.

                                I don’t think the Go team should poll what random programmers who are not part of the Go community think. I don’t even know how that would work, and I don’t think it’s desirable as the chances of encountering informed opinions will be lower.

                                1. 6

                                  Anecdotally, I’ve also noticed that preference for generics seems negatively correlated to the amount of experience people have with Go. The more experience: the less preference for generics.

                                  This part was also concerning to me. If Go is “blub”, then of course people who are more used to not having generics wouldn’t necessarily think generics are preferential.

                                  1. 8

                                    I don’t think this fits the “blub” model. People who have only used “blub” don’t understand what they are missing. But here we are talking about people who have got experience with generics: the more experience with Go they gain, the more they understand why Go does not have them.

                                  2. 2

                                    There is the old adage of being unable to please everybody.

                                    It’s better to cater to the crowd you have than the whims of random people.

                                  3. 13

                                    In the most recent Go survey 7% gave “lack of generics” as a response to “what is the biggest challenge you face today?” which is hardly overwhelming (although it’s not a clear “would you prefer to see generics in Go”, so not a complete answer).

                                    I think it’s also worth mentioning that “lack of generics” is the third biggest challenge in that survey (after “package management” and “differences from familiar language”).

                                    1. 7

                                      “I am suggesting that implementation of generics will be easy”

                                      Do you have a link to this comment? The way it’s phrased makes me think that it’s a typo and they meant to say “I am not suggesting that implementation of generics will be easy”.

                                      1. 8

                                        For outrageously inflammatory post titles like this one, I skip straight to the Lobsters top comment. Cunningham’s Law hasn’t failed me yet.

                                        1. 5

                                          Reminder that Go has generics for a small set of built-in data types, just not user-defined generics. Let’s be explicit: the language already has generic types in its syntax, e.g.:

                                          [n]int
                                          []int
                                          map[string]int
                                          

                                          It’s not a great stretch from this to something like tree[int]. Given this, the fact that the language designers have put it off for so long, and so much of the community is antagonistic towards it (where does that antagonism come from–where did people pick up on it?)–it’s not a big stretch to infer that they simply don’t want Go to have user-defined generics.

                                          1. 5

                                            where does that antagonism come from–where did people pick up on it?

                                            I picked it up in the C++ community. From build times to breakage to complexity, I have repeatedly implemented external generics (code generation) solutions that were simpler to manage and gave far better results for my projects than using templates.

                                            1. 1

                                              Those are not really generic types but variable-length types. Not exactly the same.

                                              it’s not a big stretch to infer that they simply don’t want Go to have user-defined generics.

                                              The catch with your inferration (is that a word? Is now I guess) is that the Go authors have explicitly stated otherwise many times over the years, and have written a number of proposals over the years (the Go 2 Contracts proposal lists them). There have also been a number of posts on the Go issue tracker, Reddit, HN, etc. by Go authors stating “we’re not against generics, we’re just not sure how to add them”.

                                              1. 3

                                                Those are not really generic types

                                                If you take a look at your linked design document, e.g. maps are repeatedly used as generic types in the proposed Go polymorphic programming design.

                                                Go authors have explicitly stated otherwise many times over the years, and have written a number of proposals over the years

                                                Good point, before the generics design document was published I suppose my inference would be more credible. Now I guess they are serious about generics–which seems unfortunate for the people you mentioned who vehemently hate them :-)