Mercurial: Onward and upward
blog.bitbucket.org
blog.bitbucket.org
"In my time with Mercurial, I have seen it grow in fascinating ways. These include the concept of changeset evolution coming to life and the announcement of both Facebook and Google choosing Mercurial over Git. The future of Mercurial is that of scalability and because of that, I believe the best days of Mercurial are ahead."
Is it time to give Mercurial another shot? I first migrated from SVN to Mercurial way back when - but after the massive increase in Git's popularity I bit the bullet and switched.
What does Mercurial have over Git today?
There exists no easy tutorial, that takes a beginner up to speed with git. You need to read almost a book length of material and familiarize yourself with some of the git's internals, and to some extent build your own mental model of git by experimentation, before you can use git without regular wtf-moments.
Well, there is also no tutorial that would provide the same level of understanding of the internals of Mercurial, but by some magic it seems that beginners do not need to acquire the same depth of understanding of Mercurial that they need to acquire about git, before they can start to work with Mercurial without wtf's and frustration.
Once you have a solid understanding of how DVCS's work, you can use both Mercurial and git without problems. But if you need to bring a bunch of beginners up to speed, somehow it goes easier with Mercurial.
At least, this is my experience. If someone else has experience in training teams to start using a DVCS, and has compared both git and Mercurial, and has opposite experiences, I'd be interested to hear.
I used git for a couple of years and definitely had regular wtf moments. Switched to Mercurial and they just went away.
The complexity and counter-intuitive (to me, at least) nature of git's model was a major barrier to entry.
I still use git now and then because github is so popular, but for a small team on a moderate-sized project I really prefer Mercurial for its ease of use.
fetch/merge/pull/remotes can be pretty confusing without really wrapping your head around it.
> git pull origin master
(fix conflicts)
> git commit
That's it.
2) What's a fast forward?
3) What's a tracking branch?
This is my basic understanding in terms of how I use git. I like Mercurial too and don't have a horse in this race.
http://michaeldehaan.net/post/116465000577/understanding-whe...
Needing to know anything about git's internals to be able to use git is FUD.
Beyond that, though, the team itself is leveraging that extensibility to continue to evolve Mercurial in new directions. Years ago, I was able to ship a third-party largefiles extension that worked similar to the GitHub external files thing launched a few weeks ago, and was able to get it integrated into Mercurial easily, where it was heavily used for years by people in the games industry. The team took "bookmarks" (Git-style branches) under its wing when they proved valuable, and have now added a ton of behavior to improve bookmark workflows.
They can even add huge new features. the big one that Git lacks is changeset evolution. Evolution allows you to get all of the benefits of rebasing and squashing, and all the benefits of a traditional DVCS merge-based workflow. Specifically, you can see all the previous versions of a given changeset, but those versions don't need to clutter up the history unless you're specifically interested. This means you're dramatically less likely to lose critical forensics information over the course of developing a new feature, and much more likely to be able to sanely see where, over the course of several rebases, you mucked up how a chunk of code actually worked.
That's not entirely true. For instance, some of the scaling is going to require a new manifest format that is not going to be backwards compatible.
* revsets -- feature-rich DSL for querying your history, my presentation on them:
https://www.youtube.com/watch?feature=player_embedded&v=NSLv...
* templates -- the output of just about any hg command can be customised:
http://mercurial.selenic.com/wiki/GenericTemplatingPlan
http://jordi.inversethought.com/blog/customising-mercurial-l...
* Evolve -- safely rewrite commits as a team, a safe replacement for `git push --force`:
https://www.youtube.com/watch?v=4OlDm3akbqg
* Very easy to write extensions:
http://mercurial.selenic.com/wiki/UsingExtensions
* Mercurial scales well to gigantic monolithic repos:
https://code.facebook.com/posts/218678814984400/scaling-merc...
That's all I can think of for now.
http://doitlive.readthedocs.org/en/latest/
I hope you were able to pay attention to the talk instead of the gimmick.
http://mercurial.selenic.com/wiki/Phases
http://mercurial.selenic.com/wiki/ChangesetEvolution
The latter is embodied in the Evolve extension, which I use for day-to-day stuff and find incredibly useful.
http://mercurial.selenic.com/wiki/EvolveExtension
The reason Google and Facebook are interested in mercurial is based on the remotefilelog extension:
http://mercurial.selenic.com/wiki/ScaleMercurial
https://bitbucket.org/facebook/remotefilelog
https://code.facebook.com/posts/218678814984400/scaling-merc...
Performance on huge monolithic repositories like the ones Facebook, Google, and Mozilla work with is actively considered by the mercurial developers when integrating new features.
Aside from what others have mentioned, the biggest thing for me personally is hg share, i.e. the ability to have two or more independent checkouts of the same repository. Git does not really support this. Your options are (1) git-new-workdir, which is not safe and can lose data and (2) doing a complete clone, which is cumbersome, because you can't directly diff/merge against branches in the other repository, but have to push/fetch first.
Disclaimer: I'm one of the strange people who (by preference) still uses Bazaar over Git and Mercurial whenever possible, so that may skew my preferences.
> Quote from Google: "We're excited about the work Facebook is doing with Mercurial and glad to be collaborating with Facebook on Mercurial development." (Well, I guess the cat is finally out of the bag: Google is working on Mercurial. This was kind of an open secret for months. But I guess now it is official.)
As well, if you search the Mercurial-devel mailing list[1], you'll see that Google engineers has been committing to Mercurial for a bit now. (Looks like they started in Aug 2014, and really picked up in Nov 2014).
[0] http://gregoryszorc.com/blog/2015/03/28/notes-from-facebook%...
[1] http://mercurial.markmail.org/search/?q=list%3Acom.selenic.m...
On the other hand, the company I currently work for also uses Mercurial, but all the developers besides maybe the founder (I haven't asked) prefer Git. I don't know the specifics about why everyone feels that way but from what I gather it has to do with branching being easier.
The other big thing git has is startup speed. Python is slow. Something like chg helps, but it's a workaround.
Startup speed for hg is on my machine below 100ms, less than the time most people need to type a single letter.
Git's branches introduce too much fragility in the system for end user consumption (because branches are responsible for both naming and keeping commits alive) and do not allow you to describe sets of commits (nor is there an alternative feature for that), Mercurial's branches are too permanent in that they cannot even be renamed (well, there's an extension for that, but that's not without issues). Mercurial bookmarks still do not allow you to label sets of commits, but at least aren't responsible for the liveness of a commit.
In practice, I like both Fossil's and Bazaar's model better.
Branches isn't the only thing that keeps commits alive, you also got the reflog and tags. I have a hard time understanding why you would want to keep something alive that isn't reachable from the history.
That branches are not the only refs that keep commits alive is irrelevant, because the other refs by themselves are not sufficient; not every commit is reachable from a tag and reflog entries expire. Branches remain a necessary ingredient.
Git needs this because it requires a named head for each commit because (1) it has a garbage collector and (2) it doesn't allow for multiple checkouts. In version control systems with multiple checkouts, a new branch will typically end up in a checkout of its own. Because there's no GC, it will not spontaneously disappear, and because each checkout keeps track of its own head, there's no need to name it. Git branches are an artifact of Git's odd architectural choices.
But my bigger point is not about wanting to keep something alive that isn't part of the history, but that branches may not always accurately reflect what's part of the history (because Git allows you to alter them, and that's often even part of the normal workflow, e.g. deleting a temporary branch once you don't need it anymore). This usually does reflect human error, but, well, a major point of using a VCS is to protect against the results of human error. If you messed up your branches, then you can lose data either because (1) it eventually gets garbage-collected [1] or (2) it doesn't get pushed anymore and some day your computer or hard drive breaks. This is what I meant by Git introducing fragility.
[1] Yes, once the grace period expires and it disappears from the reflog, but that only makes it less likely, not impossible, especially for stuff that sees only intermittent work.
Then again, in my experience, if you manage to remove data or alter data which should not be removed or altered, and don't pick up on that before after the reflog expiration period, then you have bigger problems.
Much easier, you can turn off garbage collection (if you set the expiration time on the reflog, you have to make sure to set gc.reflogexpireunreachable, not just gc.reflogexpire). This is indeed what I do whenever I work with Git as the frontend (though not when I uses Git programmatically as basically a versioned DB backend). But that's not about me. I'm fully conversant in Git, up to and including having hacked Git repositories using dulwich. It's about users in general, all of whom have to deal with this.
Of course, this has its own problems, because lots of Git usage patterns have evolved around creating garbage and then throwing it away rather than having an explicit and safe delete operation that is rarely used (or at least to hide revisions rather than to delete them), and because it may not be possible on hosted repositories, such as on GitHub (Bitbucket allows you to prevent force pushes to master branches, GitHub doesn't [1]).
And even when you've made it safe, you still cannot have unnamed branches or multiple checkouts [2].
The more general problem is that Git's GC is not a user interface design decision. Git having a GC is ultimately a result of it being easier to hack together your own transactions without using an actual DB backend such as SQLite when you use (mostly) functional data structures with a GC. While this makes Git a fairly robust versioned database, these and other implementation decisions spilling over into user space is something that has plagued Git for a long time: for full proficiency with Git you need a fairly deep understanding of implementation details.
> Then again, in my experience, if you manage to remove data or alter data which should not be removed or altered, and don't pick up on that before after the reflog expiration period, then you have bigger problems.
This can easily happen on branches that see only intermittent changes or on personal repositories. Git was originally designed for being heavily distributed work, and it shows; it's relatively safe when commits are regularly mirrored to a network of contributors, not so much when they don't.
And, again, this is a problem that should not even exist. One of the primary tenets of source control management -- a major reason why we even have it -- is to protect developers against their mistakes. In particular, there are many cases where VCSs are being used by non-technical people (such as technical writers working on documentation) and they cannot be expected to have a deep technical understanding of the tools they are using. VCS tools must therefore be error-resistant.
[1] GitHub in many ways is still shockingly primitive, such as how it still doesn't support attaching files to issues. Referencing gists via URL is a sort-of workaround, but even that becomes painful with binary files. But that's another story.
[2] The reason for the latter is subtle, but basically boils down that the GC either needs to have global knowledge of all checkouts in order to trace checkout-local refs such as HEAD properly (which may be lost by a simple mv) or that multiple checkouts that use the same branch can get in a battle over who gets to point it to which commit (e.g., commit to master in two checkouts, and only one commit operation can "win", because master cannot point to two commits at once).
Any delete operation in Git is safe. At least compared to delete operations in other vcs's (hg strip comes to mind).
> may not be possible on hosted repositories
That isn't Git's fault though, but the hosted repository. You could say the same about Mercurial bookmarks.
> And even when you've made it safe, you still cannot have unnamed branches or multiple checkouts.
I don't understand why this would be nice to have. Mercurial had the former, which to me was completely useless. Should I ever want to go back to a previous unnamed branch, I would have to actively search for it, which on a large project would take forever. I always keep my branches named, after the issue number, for this particular reason.
I don't really understand what multiple checkouts are for (a quick google gave me nothing). I would assume it would be something like having multiple local repositories, but I assume that is not what you're getting at?
> a fairly deep understanding of implementation details
Which takes literally fifteen minutes to teach (at least the way I did it), and after that it becomes a lot easier to explain what the different commands actually do.
> it's relatively safe when commits are regularly mirrored to a network of contributors, not so much when they don't.
A network doesn't provide any more safety (except from a computer crash), as you don't push garbage.
> is to protect developers against their mistakes
To a point. To be completely safe we would have to auto-commit on fixed intervals, like a traditional backup system. Instead, the user is empowered with the decision to decide what gets stored. If the user wants to remove something entirely, or re-write history to make it more readable or whatever, he/she should have that power too. A default 30 days of full history is, IMHO, quite reasonable given what the user can do. If that doesn't meet your requirements, then there are other, better options out there.
> they cannot be expected to have a deep technical understanding of the tools they are using
They don't need one. Have someone teach them git add, commit, push, pull and merge. Then teach them to NEVER rebase. Done.
We could probably go back on forth on this a lot, as we're unlikely to change each other's position, I'll call it quits. Thanks for a fruitful discussion :)
While I'm not a big fan of Mercurial's strip implementation (because the management of strip backups is cumbersome), in order to permanently lose data there you'd have to do hg strip and then also expressly delete the backup in a separate step. Git does the deletion on its own.
More importantly, you seem to be mistaking this for a Git vs. Mercurial argument. I am not making a Git vs. Mercurial argument; if anything, my position is that "Mercurial is less bad than Git, except in some areas where Git is less bad." And even that's not what I'm getting at, because I'm not interesting in comparing them against one or the other, but to point out that both are lacking.
In general, SCM development has stalled since the late aughts and content with a relatively subpar state of affairs. That too many people seem to think that Git and Mercurial are the only DVCSs ever invented and that centralized version control means either CVS or SVN doesn't help, either. My interest is in getting less primitive version control than the existing systems, not defending the antiquated status quo (antiquated to the point that there are even older, now forgotten systems that did some things better than the current crop).
> That isn't Git's fault though, but the hosted repository. You could say the same about Mercurial bookmarks.
Mercurial bookmarks, if misplaced, do not result in revisions on a server becoming inaccessible.
About unnamed branches:
> I don't understand why this would be nice to have. Mercurial had the former, which to me was completely useless.
They go hand-in-hand with having multiple checkouts. Create a temporary branch in a second checkout, and you don't need any label for it (because it's the tip of that checkout).
> I don't really understand what multiple checkouts are for (a quick google gave me nothing). I would assume it would be something like having multiple local repositories, but I assume that is not what you're getting at?
For example what (as I noted) git-new-workdir attempts to do (again, that's unsafe, use at your own risk). If you aren't familiar with this concept, you can't know very many VCSs, though. It's supported by all DVCSes other than Git in some form of another (though arguably a bit indirectly in Darcs, and Mercurial's version doesn't have good commandline support). It is also obviously supported by all centralized VCSs.
It simply means that you can have two or more checkouts (working trees, in Git parlance) of the same or different revisions, but only one shared repository. Multiple clones can only crudely approximate the behavior, since you can't directly diff or merge between branches in different clones, say. A simple example of the usefulness is to be able to compare the behavior of different versions side-by-side (particularly when you're dealing with slow builds). Another is to be able to create a separate checkout for an urgent bugfix without interrupting your current work, then easily integrating that bugfix into your work.
> A network doesn't provide any more safety (except from a computer crash), as you don't push garbage.
My point is that the likelihood is higher that accidentally deleted material has already been shared with other developers, so it's more likely to be recoverable if you misplace a branch.
> To a point. To be completely safe we would have to auto-commit on fixed intervals, like a traditional backup system. Instead, the user is empowered with the decision to decide what gets stored.
Agreed. But my point is that Git unnecessarily trades away security, based on an implementation decision (to achieve transactional properties by using functional data structures plus garbage collection). Nothing is ever going to be perfectly safe, but that was entirely avoidable.
> We could probably go back on forth on this a lot, as we're unlikely to change each other's position, I'll call it quits.
I don't ever expect to change anybody's opinion; I am merely explaining.
> A simple example of the usefulness is to be able to compare the behavior of different versions side-by-side (particularly when you're dealing with slow builds).
That usecase I can understand. The other two you mention though could easily be solved by branches.
Not related to the core product but still very important for the experience: A decent Windows gui, tortiose hg. I have tried all the guis for git, both commercial and free, and they all suck rats ass. Either they are slow, they only support github, they look like shit, they only support the most basic commit operations, they can't show the diff between selected revisions, they destroy your merges and simply make everything related to source control a pita. There are many many of them available that can do some of the things I listed above but none that does all of it.
Mercurial made VCS fun. I recently moved on to Fossil, because I do like the integrated wiki and ticket system for smallish projects, but without Mercurial I never would have gotten there.
I also like Mercurial's hooks. I am not sure if other DCVS support that, but hooks are great. (Fossil doesn't appear to have them)
Git has various hooks (client and server), Darcs I do not know.
That sounded to me like Mercurial has started to carve their own niche after losing the popularity war to git (maybe just my wishful thinking?), and this may have very good outcomes since currently all scalable mainstream vcs choices are centralized.
Git developers showed they're hardly interested in this area, and Mercurial have had some head start with the contributions from Facebook. I don't think anybody would object it if we had a free dvcs that can respond to very high scalability needs without hacking around its deficiencies. This is the point where Mercurial project should reconsider its priorities and even put some of their current priorities into back seat if that's what it gets to achieve their new goals with no compromises.
My best wishes for Mercurial, go for it!
Perhaps this is true for Facebook. But I can say that Google most certainly does not use Hg over Git. The Go source code used to be under Hg, but they've recently migrated to git.
Today, right now, neither Facebook nor Google are fully centralized on Mercurial. Facebook uses a mixture of Subversion of Git, and Google uses a mixture of a system that is totally not Perforce why do you ask please do not look behind the curtain, and Git.
Moving forward, this statement will be true for both companies. In Facebook's case, they are narrowly focused on truly moving everything into Mercurial, and are heavily using Mercurial's extensibility to facilitate that. remotefilelog (https://bitbucket.org/facebook/remotefilelog) is a key part of this, but they've been doing lots of other stuff that's not public that I can't link to that lets them get further. This process is well underway, but (last I heard anything) is incomplete.
Google is going a different direction, because Google. They're aiming to extend out their not-Perforce system to speak scalable Mercurial protocols. Given that they have experience storing Mercurial and Git inside Subversion repositories on top of Bigtable, this actually strikes me as a relatively sane engineering decision, from their perspective. This project is not ready for use. Even when it is, public Google projects will continue living on GitHub, which means that Go will continue being Git for the foreseeable future (as will FOAM, Blaze, and anything else they want contributions on).
Presumably this is all about replacing the massive Perforce repository for Google's production codebase using similar Mercurial scaling tricks as Facebook. https://code.facebook.com/posts/218678814984400/scaling-merc...
Also, just because they're using git for public projects doesn't rule out that they may be using mercurial internally. Google pays a number of people to work on mercurial... I'm not sure if that's the same for git.
We do have some hg contributors like augie, but we have way more git contributors, includes git project Lead Junio.
I'm excited about Mercurial's future. There are so many great things coming out. New ways to handle branching, shallow and narrow clones, an experimental interface for running hg over a git store...
It would make me very happy to be able to interact with Git repos through an interface that didn't make me want to kill myself with a rusty railroad spike.
I gather the difference is that hg-git has a mercurial repo locally and maps hg bookmarks to git branches and commits at push/pull time, while it seems like this experimental interface is using the HG UI against a git repo locally, but why is this better?
Why is it better? Converting a git repo to hg takes a long time, you need a way to translate hashes back and forth between the two repos, bookmarks in hg are not exactly the same as branches in git. Or in the words of Cervantes, "translation from one language into another [...] is like gazing at a Flemish tapestry with the wrong side out."
We still use mercurial for most of our repositories just because they're dated and not likely to see more than a handful of commits a year, but most of our active development work has already converted to git.
If your workflow fits better with git-style branches, you should use Mercurial bookmarks, not Mercurial named branches.
Mercurial even tells you:
(branches are permanent and global, did you want a bookmark?)
every time you create a named branch.https://bitbucket.org/site/master/issue/5811/support-two-fac...
If you look through the changelogs, you'll find that it's mostly adding a lot of optional features, not frantically fixing bugs in the core.
I will take small, incremental improvements over massive upgrades always. If something goes wrong in a monthly release, the change log is short enough for me to read every item and probably figure it out in a few minutes.
I cannot think of any benefit to a slow release cycle with large changes bunched up into versions, and consider it a major negative when I am choosing software (I'm currently upgrading to Drupal 7 from 6 and its been almost funny how much of a disaster it's been).
There's a reason Chrome and Firefox and Manny others do rapid rolling releases. It simply delivers better software faster and with less likelihood of catastrophic problems. Small changesets are just easier to fit into a human mind.
I refuse to do that out of principle. I think Mercurial should have taken the place of git as the widely used DVCS. And I try to be THAT change I want to see.
That being said, It would be great if someone can get the hg-git plugin to work seamlessly with newer versions of Mercurial on Windows and Linux, so that I can keep using Mercurial even if a project I am involved in uses git.
This fake interview is pretty funny:
"Linus: Git has taken over where Linux left off separating the geeks into know-nothings and know-it-alls. I didn’t really expect anyone to use it because it’s so hard to use, but that turns out to be its big appeal. No technology can ever be too arcane or complicated for the black t-shirt crowd."
http://typicalprogrammer.com/linus-torvalds-goes-off-on-linu...
tl;dr: the interface of mercurial may be more straightforward, but git won because it allowed people to work better.
I have to disagree about the index, though. I use Git every day, and i'm still struck by how pointless the index and the idea of staging is.
Ditto rebase. The routine use of rebase still seems completely wrongheaded to me. Mercurial's convention of preferring merges is better, and the last few years' developments around safe evolution of history really show rebase up as the misconceived hack it is.
Mercurial got 'commit --amend' a long time ago, but even before that, it had 'rollback', which undoes the last commit, leaving the working tree untouched (that is, with the state it had in the commit), so you can make your fixes and commit again.
I'd entertain the argument that Git won because it was better if even a handful of the people who now use Git had learned both Git and Mercurial and made an informed choice between them. That simply does not appear to be the case. Git got ahead because Linus invented it, and won because of GitHub.
I find it amazingly useful. The staging area is for building your commit. I always ever use -p (ie., "add -p", "reset -p" and "checkout -p") and use it to construct the commit out of parts.
The way I work, I split my current work into multiple commits. I may have implemented a feature, fixed a bug I found along the way in the same file, and updated the readme with something unrelated; those are three separate commits. I do "add -p" to pick the fragments, and when I'm happy, I commit. Repeat until repo is clean.
Sometimes, my current work results in a whole bunch of such commits. Sometimes I have to split part of my current work into a separate branch. Again: Stage stuff, stash -k, checkout new branch, commit as a WIP commit, go back, unstash.
Darcs has "record", which is like "add -p" except it also commits at the same time, and back when I was using it, I remember hating the fact that it required that everything had to be recorded in one go. Git's incremental staging area is much more pleasant because you don't get stressed out by the impending commit that is looming over you.
One thing I really like about git is that it lets me be mindful of my actions in a way that hg didn't seem to encourage. In return, it gives me what feels like True Power to recover from _any_ mistake. Wrong branch? Accidentally merged (and pushed) my master branch? No problem, they're just bookmarks to commits anyways.
Mercurial, by contrast, felt Rather Convenient, with occasional chasms of despair if you strayed too far from the path. It's possible that my high opinion of Git is mainly from the fact that it forced me to learn more, but it really feels more flexible. I always have the right tool for whatever I need, and I know why and how to use them.
This is probably more a symptom of the fact that either your workflow doesn't require an index or you don't understand its value.
Either way, the index is by far git's more popular and used feature, besides branches.
I use Git on a daily basis, but I never understood it.
If I just want to commit a specific part of my changes, I just do it. It's nice to see which files are staged for a commit, but I also see them in the commit msg comments.
They're called "hunks" in git parlance: sections of the file that define a "diff". A diff on a file can be made of multiple hunks.
Very often, my changes to a file are a mix of "fixing a serious bug" and "minor refactoring" and "removing dead code". When the time to commit comes, git makes it trivial to separate all these changes in different commits so that each commit does one thing and one thing only.
I think you also underestimate the developer community (or may I overestimate them.) Regardless, my anecdotal evidence is that I did try HG and Git, and while I preferred HG when I first started evaluating them, as soon as I found out how to use Git branches, it was all over for HG. At work we currently inherited a project in HG and everyone that has to work on it complains about it. Some know Git, some are .Net or even old school CVS/SVN people (our VCS migration took a bit longer than it should have), but it doesn't matter. HG = hard to use for them, whereas Git make sense after getting over the initial hurdles. I see the same kind of path I took, where at first they are like, oh, Hg isn't bad, and then after using both, choosing Git as their preference.
Rebase is a hack? Rebase copies a series of commits on top of an immutable history at a certain point in time. This allows you to deal with merges a single conflict at a time, instead of dealing with all the conflicts at once with a merge. It also allows you to avoid cluttering your history with useless merge-commits when just syncing with another repo.
Merges have their place. I use them whenever I merge branches, using --no-ff so I can attach a "Fixes issue #77" in the merge commit message. Of course, before I do that, I sync the branch I'm merging into, then rebase on top of that (to have a clean merge). I might also rebase --interactive to clean up the commits of my branch, so that the history is as easy to read as possible.
Comparing rebase to rollback is wrong. Git has rollback (or revert) as well, and it's used for other usecases, like when reverting changes on a public branch (where rebase would fuck it up for everyone).
I'm sorry, but your comments make it sound like you don't really understand Git.
Not sure what you mean by 'deal with a single conflict at a time'. To rebase or merge, you will have to resolve all conflicts that merge/rebase produce, right?
It's easier to remember the intended behaviour when the code changes are as small as possible, and when you have a (hopefully) good commit message to look at.
If you are concerned about reading history, then a merge can give you more context regarding the commits. With re base, commits will jump between features. For example, You are looking at commit for feature 1, but the next series of commits are for a bug fix in feature 2. Next series of commits belong to minor tweaks in feature 3..
Regarding the "rebase, commits will jump between features" part: that really depends on how you do things. On my projects, we use git flow. In such a scheme, every branch you would rebase, belongs to the same feature or bugfix.
Not sure if I made that clear. But I was talking about the result of the rebase. Once you rebase, all the commits that were in different branch ends up being back to back, and hence become interleaved...
I can't tell you how many times I've shot myself in the foot accidentally committing stuff to svn when I just meant a single file.
This is quite subjective. A more probable reason is that git is popular because of github..
And once git gained some popularity, people started viewing other DVCS as inferior because they were doing things differently from Git. For eg, the branching in Mercurial. People are appalled when they see how named branches can be done in Mercurial. Without going into any thought or reflection on how Mercurial's named branching can be useful in certain situations, they call it braindead. But actually git's branching is quite simple and less powerful than the methods offered by Mercurial. Less powerful, because Mercurial offers multiple methods to make a branch so that you can use the right one for a particular situtation. Note that this actually asks for more experience from the user. He needs to have experience with using each of these methods and should know how each of them may be useful in the future. It also stores more metadata and tools like revset which lets you to build powerful queries. So in that sense, Mercurial is also more complex than Git. But that is in a good way and unlike git's, it is not the complexity that gets in your way.
So in short, I think git is actually quite simple than Mercurial, but hides that simplicity behind a complex interface with non-intuitive naming and weird combination of flags and stuff. This causes the 'Aha' moments when one can finally see the simplicity that hides behind that interface, which trigger a huge release of Dopamine and prompts the user to write his own set of Git revelations that (used to) flood the internet, which in turn increases the popularity of Git...
My team started using Mercurial a couple years before Git but eventually migrated over because in practice Git was less surprising and nobody had lost data using it.
Or rather (in many cases) how good it makes people feel to use and tell other people they use something incredibly complicated, whether they actually understand it or not.
I'd venture that a fairly large amount of the people who use git don't really understand it fully, they just understand some very small subset of what they picked up from whatever "best git flow" website or book they happened to read.
Lest anyone think I'm being elitist here, I'll come right out and admit there's a ton of stuff in git I've never bothered to really understand. I'm okay with standard push/pull commits, stashing and rebasing, but I still kinda think of these things as sort of interpretations of concepts I'm used to from older non-DVCS systems, I don't "grok" git, not really -- never really bothered since I find source control systems incredibly useful but not inherently interesting (to me personally).
All that said, I don't use git to show off, I use it because virtually everyone else does and there is a certain pragmatic benefit to going with the flow on something like that even if I think it is overkill for a lot of the projects I need a VCS for.
https://static.googleusercontent.com/media/research.google.c...
Your idea (my interpretation) that the industry mostly consists of people having productive discussions seems more off base. Yes, that's the way it should be, and usually is on HN and similar forums, but out in the larger real world, arrogance, superiority, etc are the order of the day.
If you want to make such claims, I'd love to see data backing it up.
[1] https://www.openhub.net/p/compare?project_0=Mozilla+Firefox&...
It is of course possible that performance follows a saddle like curve (or hump depending on how you look at it). For up to some size, git is faster. But at much larger ones a different algorithm wins out and hg could be end up being faster.
The main problem is that mercurial never got real branches, which is git's wheelhouse, forcing gross things like the "forest" extension (which I believe is now unmaintained). Maybe it's gotten better since then, but this was about 3-4 years ago.
The way I see it, git has all the powertools you'd need, and you don't have to use them most of the time, where as mercurial feels generally stripped down to be "easy", and when you want to do the hard things, it's not so good at it.
One of those examples might be something like grafting a repo into another repo at a arbitrary root, or some of the tricks you can do to edit previous commits (say if you mispelled your username all the way down).
My main point of switching originally was when I believe it mixed up a lot of commits in a merge and lost some changes. I also recall hearing about a patch for predictable ordering in diff output being rejected.
git's really gotten TONS better -- way back, I would say mercurial was easier to use, and git really excels at branch based workflows which at this point I can't live without.
Of course, a worse thing from having to work at a mercurial shop after loving git is having to work at a SVN shop :)
What we've learned is that these two things are actually liabilities.
git is a good example that the syntax of the command line is of no consequence. git's CLI is notoriously horrendous and bizarre, yet it didn't stop its adoption. And this is a problem that's easily worked around by creating tools (graphical ones and also porcelaines) around it.
The fact that Mercurial is written in Python has a big impact on its performance, and git is running rings around it as a result. When you run tens of commands every day, it adds up.
Strangely enough even git's initial hostility to running on Windows didn't stop its adoption.
git's features and modeling of source control system is so powerful and flexible that git became successful in spite of all these other aspects.
Frankly, I think it's silly to use any other source control these days: embrace git and get used to it because it's going to be around for a while.
This wasn't the case at all. In their early years, some operations were faster on git, and others, faster on Mercurial[1]. I don't remember any recent benchmarks, but early last year, there were reports of Facebook making Mercurial faster [2].
> Frankly, I think it's silly to use any other source control these days
You might get that impression if your work is centered around github, but I have friends who use enterprise-specific extensions on Mercurial that structure their workflow.
[1] http://draketo.de/proj/hg-vs-git-server/test-results.html
The bottom line is that a program written in C will always be orders of magnitude faster than a program written in Python. This is not news.
Yes, I am. And I gave a reference for it.
> Facebook forked it and managed to make it faster but they never released their fork so nobody can actually use it.
I invite you to look up the license that Mercurial is released under. And then I advise you read [3]. And why do you keep making these unsubstantiated claims?
> The bottom line is that a program written in C will always be orders of magnitude faster than a program written in Python. This is not news.
If we're comparing exactly the same algorithms implemented in both Python and C, C would usually be faster. But we are not discussing the implementation of simple algorithms. We are talking about complex software, with different architectures.
[3] https://code.facebook.com/posts/218678814984400/scaling-merc...
No, it doesn't.
You know why git won? HG was slow as molasses when they both showed up on the scene. That and git's branches are a dream come true. I think back then, an HG branch was a clone of the repo.
I can't figure out what sort of suffering people are talking about.
There are ways around it like hg-git, but they can't really hide the git underneath. We have to use git or be computer hermits.
Most of the git commands I use are about as straight forward and simple as they could be. If ever I manage to screw something up, the archeology commands I end up using are obtuse, but it's rare that I need them. And I'm glad they are there when I do.
If you are having to download 3rd party extensions, then that's a different problem.
I've somehow created a branch that couldn't be deleted. Instead of being really deleted it appeared in remote repository as some kind of a "tombstone".
I've tried to rebase, but to do that I had to fiddle with settings and enable plugins.
My impression was that Mercurial is a higher-level version of git, with the sugary layer doing things that I don't want.
The problem here is one of conflicting terminology. What Git calls a branch, no other version control system calls a branch. A branch in Git is really a moving pointer to the head of a branch as other VCSs would see it.
The confusion can go both ways, by the way. I.e. when a user who is used to another VCS expects a branch to be a persistent label for a set of commits and then discovers that it doesn't work like that for Git repositories and that your branches may "move" or "disappear" and don't even describe sets of commits but individual commits.
Except Git tracks history of the named branch in the reflog, and SVN (and others, I would guess) track it inside the repository. This is a huge difference for archeologists, but quite minor in practice from my experience.
Eventually, just less than a year ago, I bit the bullet and made the switch to git. What did the trick for me was a list of short aliases I copied from somewhere, tweaked and have been maintaining in my ~/.bash_aliases ever since. Some aliases are just shortcuts for super common commands (such as "alias gts='git status'") but others remove the burden of remembering what combination of commands and arguments make sense to me ("do i undo a change with revert, reset, checkout or something else? well it depends.."). I still can't claim I know git in depth but it's good enough for day to day usage.
Can you elaborate and/or point to an issue tracker that describes the problems?
The Windows malfunction may be more work than a reasonable person would want to bite off, but getting it to work on Linux should be feasible.
Mecurial is super easy to learn - there is no reason not to be comfortable with both.
Many times this. Git reflog is an extremely powerful feature to fix mistakes. Any git user should at least in base understand what the reflog is and how it can be used for roll-backs.
Git has git style branches which make it really easy to work on different things. Apparently hg added some of that later but it's not the main workflow
git also has a "staging area". You put things into the staging area and then commit. So for example the equivalent of "hg commit" in git is "git commit -a". The -a means "copy everything that's changed to the staging area".
The advantage of the staging area is it's easy to commit just a few files even if many have changed. It's even easy to commit just a few changed lines from a file and leave the other lines un-commmited.
There are other advantages I'm sure and I'm sure I didn't explain the branching one well. I can point out that I have repos with completely unrelated branches. One branch is the website, another branch is the docs, another branch is the source code, branches in hg, at least the default ones, are assumed to be something that will eventually be merged back. hg complains forever until you merge the branch back. git branches are effectively unrelated to each other, although by default git will track where it branched and if you happen to merge them where they merged. branches can be pushed and pulled to other repos or not, it's up to you.
Someone above said hg has bookmarks that are similar to git branches but I'd be curious if they're actually the same.
I've heard hg since then has added features that make it possible to have a more git like workflow but AFAICT it's still not the "recommended" at least not the default workflow which means I have no desire to switch back.