Git does something very well: it has great support for rewriting version histories. It nearly flawlessly supports almost every conceivable scenario of slicing, dicing, mixing and combining.
It also has great support for working at the sub-file granularity. For instance, this morning I moved a fix from an experimental branch to stable. The fix was part of a huge commit, and consisted of just a few "hunks" out of many in one file. It was obvious that the particular fix, though needed by the experimental changes, could be promoted to stable (it was a change of the kind where some code is altered in such a way that it no longer interacts with the experimental changes, and is improved at the same time.) With git I easily rewrote that big commit such that just those specific changes in the specific file were removed from that commit. This was done without touching anything in the working copy not so much as altering any modification timestamp! ("make" didn't even see that anything needed to be rebuilt after the commit rewrite.) In git we can do "keep my working copy as it is, but alter the history behind it, so those alterations then appear as staged, uncommitted changes". Then we can easily migrate the changes somewhere, like turning it into its own commit, perhaps on another branch. After I migrated those changes to master, I then went back to that branch and did a "git rebase". Lo and behold, that branch picked up the changes, and now it looks as if those changes were written on master all along, before the experimental changes were developed.
Programmers need this kind of thing because we are obsessed about making the perfect set of changes. Since the history of a code base is a digital artifact, we want to be able to hack that artifact to perfection too, not just the instantaneous/current view of the code itself.
Git is also like an adventure game in which you solve quests and acquire higher and higher status. This creates allure. The Novice Adventurer cannot understand all the reasons why the Grandmaster Wizards of GCC have switched to Git, but is mystified and fascinated.
A rewritten branch isn't hard to pick up. Git tells you that the history has diverged (N commits here, M over there). If none of the local history is yours, you can just throw it away with a "git reset --hard <origin>/<branch>". Or else you can rebase those changes which are yours.
It's only bad to rewrite "really public" branches that are distributed to the world. Even then, it can be okay to clean up some oops: like seconds after pushing a release, some last minute change needs to be made (typo in the release notes file or whatever).
Is there some extension that helps?
And that is a nonstarter, once Git has opened your eyes to light-weight rewriting, done casually and frequently.
Here's how you do it:
hg histedit -r .
# change "pick" to "edit" in the edit plan.
hg commit -i
hg commit
hg histedit --continue
Alternatively, and preferred, because you can then test intermediate commits: hg histedit -r .
hg shelve -i
# test that it works
hg commit
hg unshelve
hg commit
hg histedit --continue
If you don't want to affect the files in your current checkout, use hg share to create a separate checkout.That splits the commit in two; use hg graft or hg rebase to move the commits to different branches.
> Its always a huge pain point.
Not sure why; Mercurial's commands for history editing are conceptually pretty similar to Git's. I suspect that it's mostly a difference in familiarity with the tools.
It's not that it's impossible, but that it was not clearly described how to do it right, in contrast to the Git documentation. Now that I've been using Git for nearly three years, and have used it to save my bacon, I'm sure I could find some way to do similar with Mercurial ... but only after having learned it with git.
`hg record` might be somewhat more cumbersome than `git add -p`. But `hg rebase` should about as nice as `git rebase`?
Early on when Git was still new, I read about the different types of objects (files, trees, commit objects) and how they interact, and everything just clicked. It's the correct model for version control, and I like to believe that that's why it's winning.
In fact, all your praise for Git is something that, as far as I see it, flows directly from Git having the correct model for version control.
The fundamental concepts in all the DVCS's are almost indistinguishable; they're just packaged slightly differently.
It's tempting to seek a technological explanation for git's dominance; but all the obvious signs point to it simply being first-mover advantage. Where the other DVCS's do have technical advantages, they're rarely very significant for most people.
But Git was not a first mover. That simple model was pioneered by Monotone. Git won because Linus' use case required high performance. DVCS flows from that (no waiting on the network), as does the index, and it just made for a huge difference in user experience.
git+hg share the same model for history; that's a DAG of commits. Sure, there are differences, but they're rather superficial. One such difference is in how you, as a human, categorize commits in that dag - what git calls a branch isn't what hg calls a branch. But so what?
In day-to-day use I can't imagine that the vast majority of git users would really notice a ifference if they used hg instead; and I suspect the same thing holds for bzr too. There's no meaningful performance difference. But the point is also that reverse is mostly true too - why not choose git it it's good enough?
And then git's real advantage shines through - it's by far the most common, and that lets you cooperate with a large number of other developers simply because lots of people know git. Oh, and github is popular too and git-only. Then there's the fact that bzr seems dead, as does monotone. The advantage is largely social - though if the currect pace of development continues it way well become technical.
This doesn't matter: hg/Mercurial has to be 500% better than git to be able to replace it.
Look at the past changes: they've all been huge shifts in how we do version control, not minor improvements
The DVCSs were 500% better than Subversion (wow, distributed!)
Subversion was 500% better than CVS (wow, renames work! Branching is easy! http support!)
CVS was 500% better than RCS (wow, we can check out files concurrently)
when svn first came out (and up until a few years ago) branching was definitely not easy!
Before this, merging branches was a huge pain, because you had to manually keep track of the commits that needed to be merged.
http://www.minidisc.org/econ113-paper.htm
A technology needs to be 10x better than a previous one for widespread adoption. It has successfully explained many failed technologies and products.
A hypothesis about failure, on the other hand, has to account for the failures and successes. This one doesn't. While it can plausibly explain failed technologies and products, it doesn't explain the historic success of junk that is worse than its predecessors.
A technology can be hyped into widespread adoption. It can be dumped on the market for widespread adoption. It can ride on top of cheap hardware for widespread adoption. It can be bundled with something else, achieving widespread adoption. A technology can be falsely evaluated as 10X better by a large number of complete idiots, resulting in widespread adoption among idiots, resulting in pressure for non-idiots to adopt.
All these effects can overcome the barrier of having to be actually, objectively 10X better. The "10X better adoption barrier" is only faced by honestly promoted technologies whose campaign consists of "try this because it's better for these objective reasons".
With the ultimate irony that people largely use it in a centralized fashion.
DNS is distributed, yet it has a "root" servers.
Even if there a master repository in a given git scenario, it is still distributed because developers have their own repositories, which are independent, and contain a replica of the copies of the upstream objects.
The Linux kernel is a proper example of distributed workflow.
Even if you consider the SPOF-y nature of something like GitHub, more savvy git users will realize that if GitHub was down for an extended period of time, they could push their repo somewhere else that's public, like Bitbucket, or their own server, and keep working and allowing other people to collaborate. And for shorter downtime of the central server (where you might feel like setting up an alternate is too much effort), everyone can still get work done, they just can't collaborate as effectively until things are restored.
The amount of force required to move an object at rest is greater than the amount of force required to maintain it already moving (or something like that).
If you're going to attract new contributors to a system, having the toolset that everyone else uses is a huge win.
I've been at this long enough to have learned (somewhat) each of RCS, CVS, SVN hg, and git. In the beginning there were (mostly) just two: RCS and SCCS, and nobody used SCCS. With time, I've touched several others, had to wrap my head around them, as additional challenges to getting my primary job done, which generally involved solving problems in other domains (or learning other tool).
And ... some of that's knowledge which has stuck, some isn't. The time invested in learning is sunk cost, though there's the problem that it all leaves traces on your brain.
This is something that 20-somethings don't get: it's not learning things so much as unlearning. It's one thing to launch into a field with the hot new technology under your belt. I landed with some awarness of Unix when that was fairly unusual, and parlayed that and a set of tools for 25 years. During which I've not stood still...
... but the rate at which new tools are introduced, and having to sort out which actually will win is a considerable overhead. After a while it ... just gets kind of old. Especially since you realize that all of it is a constructed complexity, largely arbitrary.
How many operating systems (7, not counting Unix variants), shells (9), editors (10+), scripting languages (8), database implementations (7), firewall systems (4), webservers / application engines (6), mailservers (6), document markup languages (6+), etc., etc., etc., do you want to learn over your lifetime? Some are pretty cool. Others ... are just makework.
This spills over to larger highly integrated stuff which previous experience shows is almost always going to be a massive clusterfuck, of which I'll not mention systemd by name.
Which means you want to consider what projects you work on, where you work, etc. Google have a challenge in this regard with their NIH model -- work at Google long enough and you'll learn some really cool, advanced technology. Which nobody, anywhere else, uses. And, no, they're not the only ones. But they definitely come to mind.
Been in the industry since the late 80's. Eventually one gets tired of listening to every single fad.
On the rare cases syntax does change people raise holy hell. It can kill tools. Especially if done more than once.
GUIs have none of these features and change capriciously.This tends to keep user proficiency at a low general level over time.
Web apps only extend this.
One of the most important parts of my job as a sysadmin is the immediate sniff test on trendy technology of the week and being able to spot the obvious pain points early. Bitter experience, it's useful!
(TODO: pointy-clicky interface to systemd)
The last few weeks, after using git for a decade now I guess, I had to use CVS to checkout and contribute some changes to a project still using CVS. Wow, was that painful! One does get used to the simplicty and features of git, and going backward to older tools makes one really appreciate what they give you.
[1] ... in that it provides not just safe mutable history, but shared mutable history.
I use github as a backend, so I tend to do branch manipulation using the github UI, so this isn't an issue for me.
Everything else Just Works. Highly recommended.
I couldn't care less if Git stopped making releases; what I'm using isn't the latest anyway and does everything I want. (Though I'd like any newly discovered security holes to be fixed in any pieces of Git that face the Internet; e.g. via embedding in CGIT).
Unless your project is weighty enough to have its own gravitational pull, github is a ridiculously easy place to contribute and make life easy for contributors.