11 ms·
For those of us who don't know Mercurial -- how is the UX better than git's? Are there examples you can use to illustrate? (I've heard this frequently but never
by mehrdadn 7y ago
For those of us who don't know Mercurial -- how is the UX better than git's? Are there examples you can use to illustrate? (I've heard this frequently but never had a chance to really learn it.)
- umvi 7y agoWell, the biggest UX fail for me on git was the ambiguous and counter intuitive use of the command `checkout`. I've heard the latest versions of Git mitigate this with `git switch` and `git restore` but seriously `git checkout` is the most confusing command ever. Just attempt to describe to an SVNer what `git checkout` does in one sentence or less. I haven't used Hg, but I'm guessing it doesn't have anything as bad as checkout.
- grumpydba 7y agoIn 5 years from now, will there still be svners?
- umvi 7y agoMaybe not, but "checkout" still conjures up imagery of libraries, where you get permission to use materials. You "checkout" a book in order to read it. So in that sense, it sort of makes sense to "checkout" a branch. But imagine bringing a book to a librarian and saying "hello, I'd like to checkout this book" and the librarian says "ok" and snatches the book from your hands and throws it into a furnace and tells you not to worry because she will order a new copy to be put on the shelf.
- rumanator 7y ago> because she will order a new copy to be put on the shelf. Calling git checkout is a request to check out a specific version of the repository (or individual files) from a specific point in the repository's history. If you ask the librarian "hello, I'd like to checkout this May 23rd issue of this magazine" then you can't act surprised that the librarian returns from the library's repository with the issue of the magazine released in May 23.
- onei 7y agoSure there will. I doubt many people would use SVN for a new project, but plenty of old projects still use them. It's not always simple to migrate SVN to Git especially if you want to maintain the history.
- jackewiehose 7y agoYou could ask the same question about today and the answer would be yes. Why should that change in the next 5 years? (speaking out of experience - I try to sweet talk my coworkers about git for more than 5 years)
- beagle3 7y agoIn 2010, I joined a project that was still using svn; so I used git-svn and hardly even noticed svn; and my colleagues would often ask me about project history because many things that were easy to check in gut weren’t easy in svn. Also, I had offline history and everything and they didn’t but thanks to git’s compressed storage, it didn’t take more disk space.
- umanwizard 7y agoFreeBSD uses SVN, and it is unlikely that they would ever move to git or mercurial, since they try to minimize the amount of copyleft code in the base system (e.g., they moved to Clang instead of GCC a few years ago)
- throw0101a 7y agoSome OpenBSD devs may have the answer: * http://gameoftrees.org/ http://gameoftrees.org/
- umanwizard 7y agoCool, I vaguely remember having seen this on HN but I either never looked at it or forgot. Thanks!
- _-david-_ 7y agoFreeBSD is looking into moving to Git. https://wiki.freebsd.org/Git https://wiki.freebsd.org/Git
- umanwizard 7y agoInteresting... why?
- pjc50 7y agoI still have some files in a CVS repository. Never shared with anyone, and I never felt the need to upgrade it. Doesn't make me a "CVSer".
- inetknght 7y ago`git checkout` does more than one thing and to trivialize it to a single sentence won't give it the value it deserves.
- umvi 7y ago> `git checkout` does more than one thing And therein lies the problem. Ambiguous commands are not good for UX.
- jfim 7y agoThey're mapped to different verbs in mercurial, which helps the user. git checkout somefile (revert a file) -> hg revert git checkout somebranch (switch to a branch) -> hg update somebranch git checkout -b somebranch (create a new branch) -> hg branch somebranch
- tux1968 7y agoTo be fair, there is "git branch <somebranch>" to create a new branch. Then you'll have to checkout that branch if you want to use it. Your third git example above just combines those two operations into a single command as a convenience.
- jfim 7y agoThat's true, but from my perspective it makes more sense to attach combined operations to the first operation, not the following one. For example, the equivalent of git fetch (fetch remote code without updating the working copy) is hg pull, while the equivalent of git pull (fetch remote code and update the working copy) is hg pull -u (pull, then update). In my opinion, and this can be debated, is that it makes more sense to attach it to the first operation, since one would look at the documentation of the first command (how do I fetch the remote code?) then see that the working copy can be updated as part of that. The git documentation does mention git checkout -b as part of the git branch documentation, though. Maybe this is just a rant against git though, at the end of the day, as long as work gets done, use whatever tools work for you. :-)
- 7y ago
- mehrdadn 7y agoHm, I was hoping there would be higher-level differences than that. Like maybe the notion of having an index and staging area would be fundamentally different (or absent), or the notion of committing locally and pushing remotely would be fundamentally different, or something like that. Which is not to say command names aren't also confusing in git ('git add' to remove a file is my favorite), but they're not really where I imagined the substantial differences would lie?
- deleted 7y ago[deleted]
- jcranmer 7y ago> the notion of having an index and staging area would be fundamentally different (or absent) Mercurial indeed lacks a staging area > the notion of committing locally and pushing remotely would be fundamentally different If you enable phases, it does. By default, all local commits are "draft" commits, which can have history edited. But when you push to (or pull from) a public repository, it becomes a "public" commit, and Mercurial will refuse to edit those commits. There's also a "secret" phase, which Mercurial will refuse to push to a public repository. You can also configure whether or not remote repositories are public or not. The other fun feature is changeset evolution: when you rebase a changeset, Mercurial will keep the original changeset around with a link between the old and new versions of it. If you push the rebase remotely to a repository that previously had the original, Mercurial will tell people that changesets based on the original also need to be rebased when they pull it, and the history information will let them use the regular rebase flow to do it. Too bad BitBucket is dropping hg repos...
- doubleunplussed 7y ago> Mercurial indeed lacks a staging area I'm sure someone will dispute that it is the same as the staging area, but mercurial does have the ability to only include some things in commits, and I use it daily. I admit I have no idea how it works on the command line, but in tortoisehg I can select individual files and hunks thereof to add to a commit (screenshot: https://imgur.com/ErPEjSN https://imgur.com/ErPEjSN). It's my impression that loads of people use this feature and somehow don't notice it exists, and will openly agree that mercurial lacks a staging area. My opinion is that defaulting to including changes from all files previously committed is such a sensible default that it makes the feature so seamless that people forget it exists even whilst using it. Kinda like how people from the US think you can't turn left on red in Australia (equivalent of right on red in the US). You can, but the existence of slip lanes everywhere its allowed mean you don't actually face the red light when doing so. This hides it so effectively that I've seen several people complaining that they can't turn on red, not noticing that they do it every day.
- koolba 7y agoAnytime the lay description of a command involves “when operating on a ...” you know you have a problem.
- linsomniac 7y agoIt seems like "one sentence or less" is an unreasonable demand in this case. But, if you're up for it, can you describe for an SVNer what the benefit of hg over svn is, you know, in one sentence or less? :-)
- pseudalopex 7y agoIt works offline.
- alwillis 7y agoSVN’s main commands mean the same thing in Mercurial with the added bonus of being a DVCS.
- rumanator 7y ago> Just attempt to describe to an SVNer what `git checkout` does in one sentence or less. It checks ou a version of the repository from a specific point in its history?
- Lazare 7y agoThat is not a good description of what checkout does. :) That is one of the things checkout can do, if you pass it a commit hash as the only argument. If you pass it a branch name, it does something quite different (a branch does not represent a specific point). If you pass it the path of a file, it does something quite different again. And depending on what extra flags you pass it, it'll do different things again, including creating a new branch, which is entirely different again.
- rumanator 7y ago> That is one of the things checkout can do, if you pass it a commit hash as the only argument. No, that's all that git checkout does: check out prior commits. Passing a branch name actually points to the branch HEAD, which marks a specific commit made in a specific point in time. Passing a tag also does the same thing: check out a specific commit. Passing a file path does the exact same thing: check out the contents of a specific file as saved in a specific commit represented by the branch HEAD. It's the exact same thing as git checkout <branch> or git checkout <tag>, except it does not update the whole working copy. > And depending on what extra flags you pass it, it'll do different things again, including creating a new branch, which is entirely different again. That's false as well. Running git checkout -b may be syntactic sugar for git branch && git checkout but what you are asking git to do, again, is to checkout a specific commit that represents the state of the repository at a specific point in time. That's it. All git does is enable users to navigate and edit a graph of commits. It takes a poor mental model of git and a poor understanding of what git does to fail to understand that all git checkout does is checkout a commit done somewhere in the past.
- chousuke 7y agogit checkout puts files from the repository into your working directory. For convenience, it will also update the HEAD ref if you check out the full contents of a branch. I'm not sure what's so confusing about it. Are people thinking of their entire git workdir as the repository? I suppose the fact that .git is often in the same directory as the checkout might lead to people not thinking of them as separate entities.
- lilyball 7y ago> For convenience, it will also update the HEAD ref if you check out the full contents of a branch. Not quite accurate. From the root of the repo, `git checkout foo -- .` will checkout the entire contents of the branch without updating HEAD.
- comex 7y ago> For convenience, it will also update the HEAD ref if you check out the full contents of a branch. And updates the index. And sometimes it gets files from the index instead of a commit. From a workflow perspective, "switch to working on a different branch", "copy some files into the working tree from a different commit", and "resolve all merge conflicts in this file in favor of 'ours' or 'theirs'" are three very different operations. From a low-level perspective they're somewhat similar, but not the same.
- randomsearch 7y agoMercurial uses a single command for a single purpose, generally speaking. Git overloads many different functions with clearly distinct uses in a single command. A bit like having a word processor with a “format” command that changes text font, but is also used to produce a word count or print the document. I think it attracts so much attention because git is forced on people by network effects, but many think the inconsistency of its interface defies belief, and that this lack of empathy for the user is symptomatic of a broader problem in designing software that seems to be prevalent across our industry.
- miohtama 7y agoGit is what a version control UX would look like if it were written by kernel developers who only knew Perl and C
- deleted 7y ago[deleted]
- oconnor663 7y agoAnd Bash! So much Bash...
- type0 7y agoOh, enough bashing Git! It is for developers by developers. However you can teach cli newbies Hg management, but there's no chance to do the same with git.
- oconnor663 7y ago> for developers by developers The OXO brand of kitchen utensils was designed for people with arthritis. It became a giant worldwide brand because people realized that utensils that felt good for people with arthritis also felt good for everyone else. Not everything is a tradeoff. Sometimes we can just do better.
- zyx321 7y ago
- vostok4 7y agoRecently I wanted to understand in a git repository what was different on the remote vs what I had locally. The best I could stackoverflow for git was "git fetch; git whatchanged ..origin" In Mercurial its even better (since it doesn't modify anything locally like git fetch does): hg incoming Want to see what will be pushed? hg outgoing When I use Mercurial I just don't think about it as much, it does what I expect it to do, which is something that is easy to take for granted.
- magicalhippo 7y agoOne random example, to update the current working directory with changes and then (later) to revert a file is both done using `git checkout`, while it's `hg update` and `hg revert` respectively when using Mercurial. https://git-scm.com/docs/git-checkout https://git-scm.com/docs/git-checkout https://www.mercurial-scm.org/repo/hg/help/update https://www.mercurial-scm.org/repo/hg/help/update https://www.mercurial-scm.org/repo/hg/help/revert https://www.mercurial-scm.org/repo/hg/help/revert
- jcranmer 7y agoThe biggest UX improvement is that Mercurial's help is actually usable and useful to figure out how to do stuff. For git, your best bet is to search for your question and hope it's worded sufficiently well for someone to have already answered it correctly. As a concrete example of where this helps: I needed to do a complex merge in a script, rather than manually, which means I need to know how to do a) automatic merge strategies (conflicts will happen were it naive!) and b) how to choose different strategies on a per-file basis. By running `hg help merge`, it tells me that `hg help merge-tools` will help me for problem a) and `hg help resolve` will help me for problem b). Read those documents, and you find the list of internal automatic merge strategies, as well as the fact that `hg resolve` allows you to change the current resolution status of a single file, or re-run a merge tool on that file. It's not clear to me how to do this in git just from following its help pages, despite `git merge` being far more voluminous than Mercurial's equivalents. Another example of a power feature is that anywhere you can specify a revision (or set thereof), Mercurial has a full expression syntax for computing revisions. The cases most people are used to are the hash (or any unique prefix thereof), the commit's integer id [1], tip (for the most recent), . (for the currently-checked-out revision), or the tag, branch, or bookmark (Mercurial's equivalent to a git branch) name. But you can specify quite complex revision sets as well: `hg glog -r "ancestors(draft()) and (draft() or branchpoint())"` will show you a log with ASCII graph (the `glog` command) of all the changesets that are not yet public, as well as specifically where they all branched off. The syntax is naturally inscrutable, but once again, `hg help revisions` (as pointed out by the documentation in `hg log`) will give you the full details. Another surprisingly useful UX feature is that Mercurial is not afraid to alias the hell out of everything. `hg rename`, `hg move`, and `hg mv` all do exactly the same thing: record a file move. `hg glog` is short for `hg log --graph`. And any unambiguous prefix of a command is happily expanded to that command--useful if you don't remember if the document name is 'hg help revision' or 'hg help revisions', as they both work! For repository features itself, there's a few things that really make things simpler for people: * Mercurial lacks the staging area. This is a good thing. * The UI generally aligns to the naming conventions of SVN, which makes it much easier for people transitioning from SVN. * Mercurial treats commits as a much more permanent thing. There's no such thing as garbage collection in Mercurial, and you don't run the risk of losing commits just because you're not currently on a "branch" [2] like in git. Also, no scary message like "DETACHED HEAD STATE" if you decide to go poking at an older commit in Mercurial. * Phases and changeset evolution make history rewriting much safer: you can't rewrite public history (determined by the phase), and changeset evolution means that pushing a rebase allows other people to safely develop on top of draft changes. It's made quite evident when you pull that your changesets are based on ones that have changed history, so you need to continue the rebase to stabilize your branch. [1] All commits are assigned a unique, incrementing integer ID from 1 to N. These IDs are not stable: if you delete an integer, everything afterwards is shifted down. And if you clone a repository, it won't necessarily assign the same IDs. But they're still useful for referring to commits locally. [2] Mercurial's branches are a completely different beast from git's branches: they are immutable properties of a changeset, and they are designed to be used for things such as release branches or version branches rather than feature branches. The Mercurial equivalent to a git branch is a bookmark. Hence why "branch" is quoted here--I'm referring to it in the git sense, not the Mercurial sense.
- ufo 7y agoOne of the more noticeable differences is that there is no staging area. So to commit your changes you only need yo go through a single step,hg commit. For the situations where you actually only want to partially commit things you can use "hg shelve", which is sort of like "git stash"
- hamandcheese 7y agoThe lack of a staging area is the deal breaker for me.
- doubleunplussed 7y agoMercurial does have a staging area. It just defaults to including all previously-committed files, which IMHO is very sensible. Link to my previous comment on it: https://news.ycombinator.com/item?id=21393972 https://news.ycombinator.com/item?id=21393972
- jcranmer 7y agoWhat you describe is not a staging area, it is an interactive commit. And, personally, I see no positive value in a staging area, given that you can achieve the same functionality via interactive commits or amending commits.
- doubleunplussed 7y agoAh, fair enough. So I suppose git's staging area has the additional benefit that you can stage some things and then shut your computer down and the staging will be there when you come back. I have no idea whether tortoisehg remembers the state of what you've selected in its 'interactive commit' GUI, because I've only ever made those decisions when committing. Given I've been using it almost daily for about six years on a community project (i.e. not just linear commits by a single dev who doesn't need to care about anyone else), I think this is also evidence that a persistent staging area isn't super important.
- 7y ago
- all_blue_chucks 7y ago> how is the UX better than git For one, 'hg' is one of the easiest possible things to type at a command line... up there with 'ls'.
- _-david-_ 7y agoYou can alias git to whatever you want.
- pseudalopex 7y ago"git checkout" overwrites uncommitted changes. "hg revert" creates backup files in case you made a mistake.
- greggman2 7y agoIt's not. hg users generally don't understand that git is doing something fundamentally different from hg. git adds a 3rd dimension to your file system. dimension 1 = files, dimension 2 = directories, dimension 3 = branch. That git adds this 3rd dimension makes it useful for version control but that's effectively a side effect. hg on the other hand is specifically about version control so it does not handle adding this 3rd dimension well. This is why for example things like gh-pages on github where there's a branch that has absolutely nothing to do with any other branch and no shared history is a normal thing to do in git (because a branch is another dimension to the file system, not a version control construct). That difference, adding branches as a 3rd dimension, is why git is more powerful. It's also a reason why a staging area is important to be able to precisely decide what goes in each branch since they may be unrelated. That is not to say that hg's ux isn't easier to understand than git's. It is easier. In part because it's trying to do something else. That is also not to excuse git's unintuitiveness.
- yjftsjthsd-h 7y ago> It's not. hg users generally don't understand that git is doing something fundamentally different from hg. > That is not to say that hg's ux isn't easier to understand than git's. It is easier. In part because it's trying to do something else. That is also not to excuse git's unintuitiveness. 1. So... it is, albeit perhaps by sacrificing certain features. 2. I'm not convinced that git's admissibly more powerful branching model justifies the claim that hg's UX is no nicer and people who prefer it just don't understand git. If nothing else, what practical difference is there between creating a branch with no history vs creating a branch with history and then clearing it out? (That is: `hg branch newbranch && rm -r * && hg commit . -m 'new start'`) Both hg and git boil down to DAGs and have generally similar tools available to manage the grand set of commits.
- bogdanoff_2 7y agoJust to clarify, in mercurial you can "branch off" and then merge back just like in git. The difference is that git has an explicit concept of "branch" and each commit must be part of a branch, whereas in hg each commit stands on its own and your history is just a graph of commits. Instead of using branches to indicate that you are working on different features, in hg you use bookmarks, which are just pointers to commits. In hg land, gh-pages would be a bookmark.
- cryptonector 7y agoIt isn't. The thing people supposedly like is Mercurial's heavy-duty branching model, but mostly I find that Mercurial so wants to hide the details of the underlying store that it just gets in the way. Same thing with Fossil -- great internals, opinionated UI, useless to me. Mercurial resisted rebase forever, and then they insisted that rebasing and editing history must be separate operations (why? opinions). And Mercurial doesn't have anything like an index, so no git add -e/-p, but instead you can do a combined equivalent of git add -p and git commit with hg record -- talk about "one command does one thing" nonsense. Just let Mercurial die already.
- sfink 7y agoFrom what I've seen, few people use Mercurial's heavy branches, except for things like release and maintenance branches, where it makes a certain amount of sense. Some do, but most people seem to use bookmarks, topics, or multiple heads. Everything else you're talking about sounds like ancient history to me. `hg record` is now `hg commit -i`, so it's back to one command. `hg histedit` intersects with rebase, in that you can do some types of rebasing with it, but you tend to use them in different scenarios.
- cryptonector 7y ago> `hg histedit` intersects with rebase, in that you can do some types of rebasing with it, but you tend to use them in different scenarios. I don't tend to use them in different scenarios. I routinely `git rebase -i origin/master`. Sometimes from detached-HEAD mode. > `hg record` is now `hg commit -i`, so it's back to one command. So Mercurial has an index? Or is that something else? Looks like roughly the same thing as `hg record -p`. An index is much easier to use. `git add -e` is simply amazing. I've tried to use "bookmarks" in hg or whatever they were calling light-weight branches, but I've had trouble with it. Git won. I'm not saying Git is perfect. It's missing a few things, but it's better than all open source VCSes so far. And the work MSFT is doing is really helping too.
- sfink 7y ago> So Mercurial has an index? Or is that something else? Something else. i for interactive. > Looks like roughly the same thing as `hg record -p` Do you mean git commit -p? (Or is it git add -p? I can't check right now, and I can't even predict which one git would pick.) Anyway, yes, it's exactly that. > An index is much easier to use. Why? I don't miss it in hg. I use it in git, but it mostly feels like it's an extra thing to remember. Yet most git users agree with you, so I'd like to understand why. > `git add -e` is simply amazing. I wonder what you'd think of `hg absorb`.
- alwillis 7y agoCommands aren’t overloaded. hg checkout only does one thing. Because git checkout does a whole lot of things, it takes lots and lots of text to describe what those things are. hg help co | wc -l $ 42 git help checkout | wc -l $ 520