Hacker News new | past | comments | ask | show | jobs | submit login

I don't understand why so many people seem to dislike git. But maybe in actuality it is not many people, as usually people who are discontent are the loudest.

I used Mercurial in the past for a bit, and it was fine. But for me it doesn't seem to have any huge advantages over git, if any. And after so many years of experience using git, I know what workflows work well, how to resolve merge conflicts, how to revert to an old commit if something really gets messed up, etcetera.

I don't see any other DVCS really being able to replace git in the short run and I wouldn't be surprised if git will stay number 1 for the following decennia, as in my opinion it's really great software. A DVCS really has to provide substantial benefits over git in order to replace git as the number 1 DVCS.




Git functionality is great. But the CLI just kind of grew in a nonsensical way. No serious effort seems to have been made on UX consistency and verb/noun names.

People who've been using it for years don't notice, they don't even think about it. But when coming from scratch, it's anything but intuitive. The CLI is not discoverable in a reasonable way.

That and there's so many ways to use it.

Mercurial had the advantage of having a much more consistent UX. Though these days I'm sure I'd struggle with it, because I'm so used to git.

Mercurial was never trying to "replace" git. All of these guys came out at the same time. Git got headspace because Linux used it and GitHub was a "cool" Ruby on Rails site, run by cool web 2.0 kids, same era as the rise of Twitter, etc. (And also down all the time, just like Twitter).


Exactly this. To be perfectly honest, the git CLI is so bad that I would take pretty much anything over git. I would prefer SVN over git, despite that product being older and with less functionality, just because it's at least easy to use.

I learned and use git because that's just how the industry has moved, and I'm pragmatic enough to just roll with it. But good Lord, the UI is a case study in "programmers shouldn't be allowed to design UIs".


> I would prefer SVN over git

Yes SVN has so much better CLI especially for things like

  * merging

  * history navigation

  * searching commit messages, filenames and file content

  * bisecting
I'm filled with joy remembering good old SVN days and how my life was a way easier.


Yeah, SVN was terrible. Its chief advantage was it was just less terrible than CVS and carried roughly the same workflow, so wasn't unfamiliar to people. It was basically CVS with atomic commits and a better interface and transport layer. You could drop SVN into a CVS shop without ruffling many feathers -- and back then I found most people were quite resistant to "novelty" in revision control systems, so SVN fit into that.

I don't think there's anything intrinsically wrong with a centralized revision control system. I used Piper/CitC at Google for years and it could be ... tolerable. Many people just end up using git this way anyways.

But SVN shipped with garbage merge-on-merge support, and that was the deal-breaker for me.


> Mercurial was never trying to "replace" git. All of these guys came out at the same time.

Mercurial even had a couple weeks' head start on git, and git partly happened trying to replace Mercurial in early experimentation. The name "git" was always an interesting self-deprecating choice because it was (intentionally) "stupider" than its competition that it knew about, which included Mercurial (and also darcs/Monotone/Bazaar).


It's a bummer that Graydon didn't stick with monotone.


Please have a look at newer commands like restore, switch etc. Much clearer in my regard.


Essentially, the problem with git is - it is a tool that is simple in its internals, but with a complex/confusing UI. The only way for someone to feel somewhat in comfortable with git is to have a good conceptual model for how it works internally. Once you have that mental model, you feel like a magician with git, but for beginners, it is a source of endless confusion and fear.


GIT is a tool. Like a swiss army knife, it looks tricky and you need some experience to master all what it provides. But you never actually need everything and, surely, you should also shy away from features if you do not really need them. In this respect GIT is a bit like Perl or C++. You have to apply some discipline to avoid unnecessary complexity. Personally, I have never used GIT's "octopus" merge support but I am sure in some situation it may well be a useful feature to have. So I respect that while scratching my head. ;)

Those are basically all commands I am really ever using:

git status

git add

git rm

git commit

git branch

git checkout -t -b ...

git merge

Learn those and you'll mostly good to go.

Sure, I could to rebase my branches all day and make sure my version history looks "pretty" but I find obsessing with the commit history is a major source of complexity people face when using git. Another usual source of confusion is the branching model. However, that totally depends on your organization. GIT is flexible enough to support all kinds of weird development processes but if it comes over as complicated then don't put the blame on the tool but on its users.


I like the in-progress `git checkout` split to `git switch` and `git restore`. (switch and restore are still marked "experimental" in the official documentation in case their arguments change again, but in my experience they are already pretty dependable.) It's much less likely to accidentally do the wrong thing with either of the two replacements. That's one of the things that I think if that split had been done years ago there would be a lot fewer complaints about git being confusing in the base commands; `git checkout` was always an odd duck sadly (it makes sense why it was a single command from a technical sense but it probably shouldn't have ever been from a UX/DX sense).


I like it too, unfortunately it will take decades before books, tutorials and google search results can catch up.

It is the same fate as any cli application that needs to maintain backwards compatibility because it is used both by humans and programmatically as part of scripts. My favorite example of this dd. Most tutorials still show using dd against /dev/sda1 etc instead of using device names as humans should, and meanwhile people keep shooting themselves in the foot.


Although I understand all these commands and can use them, it's a typical Linux tool. Sure, if you understand the internals you can use the tools and the horrendous GUIs that are nothing more than a thin layer of paint.

But a truly user-centric tool would actually help you with something like

"I want to work on a new Feature A" "I want to continue working on Feature B" "I want my changes in the software/product" "I want to review a pull request (haha!) locally, in order to have IDE support." "I did an oopsie and need to go back."

Imagine navigating to a website by specifing its hash, or seeing changes to a PowerPoint file using "git status" and seeing "++slide1.pp". It would be terrible.


It's a low-level tool. Imagine writing code with Microsoft Word. There are layers on top of Git that give you more of what you're looking for.

- https://github.com/extrawurst/gitui

- https://github.com/jesseduffield/lazygit

- https://magit.vc/


> you should also shy away from features if you do not really need them

>Learn those and you'll mostly good to go.

I wasn't really talking about "fancy" features of git, like rebasing history to try to make your history pretty or using things like git bisect. You need to develop basic understanding of git internals, even in the most basic workflow.

I would argue that your list of commands is not in any way complete for being "mostly good to go". At the minimum, you also need to know `git clone`, `git push`, `git pull`, `git fetch`, `git diff`, `git log`, `git blame`, and `git reset` as well. You need to save progress on your current feature branch to context switch to review some PR or analyze some production bug, well add `git stash` to the list. Your boss asked you to hotfix your recent commits onto the release branch? Better not forget `git cherry-pick`.

That brings us to 17 commands (up from the 7 you listed). Fine, it is still a finite number. Can you at least use them as a black box without bothering about the internals? NOPE. You also have to learn a lot of concepts to even understand the help and error messages for these commands - the worktree, the index, the stash, HEAD, ours vs theirs, conflicts, remotes, tracking branches.

Besides, so many commands come with their own gotchas (git checkout will happily overwrite your local changes - without any warning). Some have bad defaults, so you need to figure out which of the hundreds of options that command supports to make it do what you actually want (e.g. git log --oneline and git diff -w -b). Still others have overloaded semantics and do two completely different things (git checkout switches branches but also restores files).


I find it interesting how many tutorials praise the simplicity of git while simultaneously assume nothing goes ever wrong. It's when you have to pull the main branch into the feature branch you're working on (because you sure don't want to do the big merge in a few weeks when you're done, not the least, because you don't even know whether you're still there to do it), but aren't ready to commit all changes made yet, when Murphy assures that there are conflicts. Then you have to do the stash/pop dance and since you manage to not fix all conflicts, the stash wasn't dropped, which you do manually and you just lost some changes. Then you wished you'd done a back-up before the pull ...

Sure, if you always commit your changes before pulling, then you won't need the stash and (even old CVS documentation reminded us that a VCS tool cannot replace communication) if there are no unrelated changes in the files you're working on, there won't be conflicts, but that just aren't realistic assumptions.


Sounds like you should commit more often inside you topic branches.

In case you are talking about merge conflicts: That's the nature of distributed development other people might trump on places you are currently working on.

I guess there are more intelligent merge strategies. But GIT gives you a list of files that need a manual merge and you have to look into them one by one. GIT even tells you what to do in this case.


I think the idiosyncratic command names are rooted in the fact that git is designed as a peer to peer distributed system as opposed to how it is generally used right now, the server/client workflow. Github even follows and adds to this tradition with the always weird sounding "pull request", since the pull request is normally a mail to a mailgroup with the description of the changes and an actual request to pull that person's changes to the maintainers local repositories.

I'm not sure what is currently being done at developing git, but adapting/creating some porcelain commands accommodating a more centralized workflow even mainly on a semantic level could help with the UX friction.

Also, the obligatory joke "git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space"


> Also, the obligatory joke "git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space"

The scary thing about that one is that I still don't know whether it's just a joke, or if it's the "it's funny because it's true" kind of joke.


The sheer functionality of git is amazing. The number of times I have encountered a new situation and used a previously unknown (to me) feature, or (equally as impressive) been able to harness the flexibility of the software to wrangle some strange edge case are innumerable. All that while also being lightning fast.


Despite having 14 years of experience with Git, I still can't use it without Stackoverflow for any non-daily task. And I've read the internals back in 2008 and understand this, but it doesn't make it any clear how merges, conflict resolution, or amendments to commits work. Absolutely confusing. In Mecrurial a lot more stuff is clear and easy to remember.

Example: I tried rebasing or merging, and got merge conflicts. Started resolving them, git-added some of files, but got stuck, and want to get back to the last commit. git-reset doesn't work. How do I get there? No idea. How does the knowledge of commit hashes, branches and staging area help me? It doesn't.


When conflicts occur when performing rebase, git prints out the following: ``` hint: Resolve all conflicts manually, mark them as resolved with hint: "git add/rm <conflicted_files>", then run "git rebase --continue". hint: You can instead skip this commit: run "git rebase --skip". hint: To abort and get back to the state before "git rebase", run "git rebase --abort". ```

The options on how to proceed seem pretty clear to me.


This is just one of a dozen unclear cases, that arise sometimes in git workflow. I do recall the first sentence in the hint, and I could have read the end too, but it's not clear, why it's "rebase --abort", not "reset --hard", that's why it's easy to forget this and other commands.

Also, "git add/rm" is confusing, because they're not opposite of each other -- 'add' puts the file to the stage area, but rm removes it and makes forget.


> after so many years

This is why so many people dislike git. It's a base tool that should have an obvious workflow and very few pitfalls. Instead it allows one to do just about anything at anytime without giving much of a fuck about any resulting mess. All blade, no handle. It's a tool for Linus, by Linus. The average corporate coder is not Linus and doesn't have Linus problems. People don't want a Merkle tree manager, they want a workflow.


Exactly….

(I strongly dislike git and much prefer KISS tools)


Aside from the terrible UI that several other people have mentioned, there are some other things that Git does badly (though I don't know if Mercurial does better):

* Large projects. It has poor monorepo support (especially on Linux), and also poor multirepos support (submodules are really buggy).

* Large files. LFS is a PoC-level hack; not a proper solution.

* Conflict resolution. The default diff algorithm is very dumb, and even with `zdiff3` it doesn't quite give you enough information to easily resolve all conflicts.


Git is very good with large repos, but the monorepo concept doesn't fit the git model. Monorepo is a bad idea with the current DVCS-es unless you use custom tooling. My guess is that people adopt monorepos because they aspire to be Google-scale, but it usually doesn't make sense for their workflow.

If you want monorepo, use Perforce or SVN, but good luck with the speed ;)


> Git is very good with large repos

Not really. It only very recently got support for partial clones, sparse checkouts (still experimental!) `git status` daemon (only on Windows and Mac!), etc. And that's only because Microsoft is pushing it.

> My guess is that people adopt monorepos because they aspire to be Google-scale, but it usually doesn't make sense for their workflow.

Rubbish, it's nothing to do with wanting to be Google-scale. In fact being Google-scale makes a monorepo more difficult and require custom tooling.

The reason people like monorepos is because they don't have the downsides of multirepos:

* Cross-repo changes are very difficult to do and even harder to test.

* Testing code becomes very difficult. For example if you update a library that's in one repo, how do you test all the things that depend on it? Very difficult with multirepos, trivial with monorepos.

* Git's support for submodules is really bad.

The downside of monorepos is that they are big and slow, but they work fine as long as you aren't Google scale.


> Not really. It only very recently got support for partial clones, sparse checkouts (still experimental!) `git status` daemon (only on Windows and Mac!), etc. And that's only because Microsoft is pushing it.

Which only proves my comment that git is not designed for bigcorp view of monorepos. Kernel is monorepo and works fine.

> The reason people like monorepos is because they don't have the downsides of multirepos:

The reason people like monorepos is that they are lazy to properly organize development process. If you update library in one repo but test it in another, I'd say you need to reconsider your pipeline. But, to each their own.


> Which only proves my comment that git is not designed for bigcorp view of monorepos. Kernel is monorepo and works fine.

Not really; it just means you misunderstood what I meant by "large projects". The Linux kernel is not nearly as large as most company codebases.

> The reason people like monorepos is that they are lazy to properly organize development process. If you update library in one repo but test it in another, I'd say you need to reconsider your pipeline.

Sounds like you just don't have any experience of this sort of thing so don't appreciate the problems. You update the library in one repo and test it in another because that other repo is using the library. You want to make sure your library update doesn't break it.

If you don't test all of the dependants of your library then you're massively increasing the risk of breakage (plus all the other downsides) just so you can use separate repos. That isn't worth it.


I definitely feel the large file support in Mercurial is less bolted-on. My personal favourite mercurial gui features that I hope make it into git or a mercurial using a git data store are:

  phases
  revsets (query language for revisions, they also have filesets for the files)
  hg grep --diff
  hg fa --deleted
  hg absorb


I could go into some detail here why Git is the harder to use system of the two, but I think that would miss the bigger point.

IMO, the larger and longer-term problem is that (open source) version control systems seem to be mostly stuck in the early aughts. This may sound provocative, but in principle, Git and Mercurial don't offer much that wasn't already part of Monotone. Meta/Facebook has really been the only actor I am aware of who has been really pushing the envelope in terms of making open source version control more convenient.

If you think I'm being needlessly provocative, just consider this simple example: why don't version control systems (especially ones that can change history) have undo/redo functionality out of the box? I've only seen this as a Facebook extension for Mercurial that never made it into the Mercurial proper (and survived only as part of Sapling).

This is an essential feature of every basic editor nowadays and it is not easy to implement for a VCS, but it's still mind-boggling that after nearly two decades, it isn't considered core functionality of a VCS. Recovering from mistakes remains a pain point in pretty much any VCS, but shouldn't be.

Commit graph visualization is another problem that's just not handled very well by either Git or Mercurial and hasn't really improved much since their early incarnations, if at all. "git log --graph" or "hg log -G" don't really produce output fit for human consumption if you have even a moderately complex branch structure.

Version control systems are still generally very low-level, giving you a lot of primitives and very few high-level operations that aim at making complex workflows less complex.


> why don't version control systems (especially ones that can change history) have undo/redo functionality out of the box?

It's true. And Jujutsu has undo functionality out of the box, too. It's not just Sapling. :) https://github.com/martinvonz/jj




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: