I think my main problem with git (though I use it) is that things that should be simple are mind numbing hard. At 2:00am when I working, having to read pages and pages to decide if git pull is the right thing is just painful.
I never felt that type of pain with SVN, it more or less just maps to directories.
To each his own I wish there was the right way to use git in 50 words or less. If I need to read a book to correctly use it ... grrrrrrr.
Some people like git pull, but I prefer git fetch. This gets all's the history from the remote repo without applying any changes. Then you can run something like 'git rebase -i origin/master' which is where I think git can really shine.
There is an excellent link out there that explains git in layman's terms. I think it's called git for hackers or something of the sort. It's much easier than the docs in my opinion.
Pulling is equivelent to doing a fetch then a merge. Unless you plan on doing something between the two steps (like inspecting FETCH_HEAD yourself), then there is no advantage to not simply pulling.
Of course, if (like thrush) you do not plan on doing a merge, then you will need to do the fetch manually and do what you do want to do. Although, git pull does have a --rebase option, but I am not sure if you can pass the -i flag to it.
Having taught people how to use git, I found that it is easier to not show them the pull command until they are used to doing fetch && merge.
Partly because the terminology tends to be slightly different than other source code control systems use. Also partly because if you do any research on git usage patterns you will find like 6 totally different ways you can use git to do roughly what you used to do in svn, and any one of the options you choose of those will have pages and pages of blog posts explaining why doing it that way is stupid and wrong and you should really do it in this other of the 6 ways, with no real authoritative explanation of when you should use which pattern.
The end result is a situation where you have to learn a lot about how git works internally to actually have an idea if how you are using it makes sense or not in relation to your project.
git isn't nearly opinionated enough for simple usage patterns, IMO. I like the flexibility it offers but it would be nice for new adopters if it were more hidden and there was a more obvious "happy n00b path" to take when first starting with it for the majority of projects that don't have the sort of distributed development challenges that the linux kernel does.
Note: I'm not the OP and I'm really comfortable with git now, but I've been where OP is and totally understand.
"I never felt that type of pain with SVN, it more or less just maps to directories."
Ironically, that's one of my major fatal objections to SVN, the way it casually encourages developers to have a code checkout that doesn't actually exist in the source repo, as you check out various versions in various subdirectories without even thinking about it if you aren't careful. Back in my SVN days I lost track of how many times it worked on somebody else's box and not on mine, because one or the other of us (or both!) had a checkout that didn't actually represent any particular revision.
"Well, don't do that then!" Of course not, but A: I can still be bitten by other developers doing it and B: SVN really, really affords this. By accident, sure, but it is afforded nonetheless.
In fact in a lot of ways SVN vs. Git reminds me of static vs. dynamic typing... many of the "easier" things that SVN does are also wrong, and many of the things that people are objecting to about git are actually the underlying model being correct, and refusing to be wrong. I don't mean the UI, which is sort of dodgy, sure, but the underlying model.
(Git submodules are sort of that way... in many ways, the difficulties in using them are reflective of the fact that correctly embedding one source code repo in another is actually fundamentally hard, and anything that makes it easy is probably just glossing over some fundamental problems. It is probably possible to make it easier, but if it has been made easy, one should immediately be very suspicious.)
> I can't also see any practical solution for a separation of concerns. Some users could e.g. work only on translation and need only to checkout XML files and push them back to the repo. With Git, that would have to be a separate repo.
I am far from being good with Git yet but why couldn't the translator simply branch out and only merge back his XML files ?
Perhaps the issue is that there's no technical barrier to them messing around with something else, perhaps by accident. (And if you try to deal with this by playing around with filesystem-level write positions in the repo, then they can't pull down new versions of the rest of the project either.)
The only really clean solution is to use submodules (or the newer variation on the theme, git subtree). But those aren't entirely smooth either.
The idea of Git is that everybody has their own local copy of a whole repo so it doesn't really matter what they do with it or if they mess it up. If other people want to merge the changes to their repos they will see what was changed and what wasn't so if you get pull request from "XML only guy" you just verify if only XML files were changed.
You seem to think about it in terms of one master which isn't Git way.
And you're thinking about a workflow in which no one ever uses "git push". If most devs do, and "the XML guy" can't (because someone else needs to look over his commits), that's a headache, which could be solved technically.
Come to think of it, it could be solved technically even with git -- the XML guy's repo gets a pre-commit hook that verifies that he's committing changes only to the files he's allowed to edit. (We're now requiring him not to mess with that hook, but if that's a problem, maybe they shouldn't have source code access at all. The point is that now a tool is doing the checks, which frees up the humans for things that really do require human judgment.)
Used both SVN and GIT on different types of projects. Gotta admit, it's been a little harder to get used to GIT. It has a more complex interface and ways of doing things.
However, it feels like comparing SVN to GIT is like comparing horses to automobiles at this point.. Yes, a horse can heal minor damages without a mechanic, your car can't. And it can swim if need arises, good luck with a car on that.
Woudn't choose a horse for anything serious though. Maybe for fun and sports.
I agree git has a more complex interface - I think I've read it described as "not quite user-hostile, but only expert-friendly", which I think fits.
That said, I think the model of how commits work is far more intuitive than anything else I've come across. A commit is just a diff and a pointer to the commit that came before it, and a branch is just a pointer to a particular commit.
That's true. I simplified for the sake of not delving too far into the details, because it makes sense at the smaller level. It's also true that a commit isn't always just one pointer to the commit that came before it, in a merge there are two pointers, from commit_head and merge_head
Used both too, the main reason we are moving away from SVN is the hell created when something deletes a folder outside of SVN. Storing .svn inside every single folder creates a world of pain with web apps that update themselves.
These are extremely superficial reasons to criticize git, leading me to believe that the author knows very little about git internals. I'll take the first critique and leave the second to someone else...
You can't pull a portion of the repo because the current state of the repo is built from the tree of commit diffs... This and the fact that git itself is a hash database leads to very efficient use of space. If you want a single folder within a repo, why isn't that folder its own repo?
Between that, the passive aggressive ;-) and the unfortunate advocacy of SVN... ugh.
I don't agree with the criticism of the article (though there are plenty of UX reasons to be critical), but this is hardly a punching yourself in the face kind of behaviour.
You can't pull a portion of the repo because the current state of the repo is built from the tree of commit diffs... This and the fact that git itself is a hash database leads to very efficient use of space.
Sure, but knowing that is essentially irrelevant if your workflow involves a need to check out a partial tree, and Git makes it (hard|impossible|unwieldy|whatever) to do that.
If you want a single folder within a repo, why isn't that folder its own repo?
Because needless proliferation of tiny repos is a problem in its own right?
and the unfortunate advocacy of SVN... ugh.
There's nothing unfortunate about advocating SVN, if SVN is a better fit for your workflow - and by extension, presumably, someone else's workflow which happens to mirror yours.
o Complex, confusing terminology including multiple non-obvious names for various components.
o Huge number, about 148, of commands with many sub-commands that often do non-obvious, even unrelated things.
o git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
o Git has been bundled with code review systems like Gerrit which encourages developers to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes, debug, engage in trial and error, or all the other things developers actually do. When a bug does slip through as if often does despite the supposed quality-control benefits of code review, then reconstructing what happened from the rebased "history" can be a nightmare.
o There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
o A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches, making locating changes and reconstructing the history of changes extremely difficult. A change can occur on a local branch on one developer's computer, be rebased into another local branch and then finally rebased or merged into the shared "master" branch.
o Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files as well as snapshots of the entire project. Even if you track down the tricks to compile the SHA into a program or file name, the SHA is not sequential making it difficult to know which version of a file or group of files is in a program.
o These many flaws in git and its command line interface have resulted in a proliferation of third-party add-on tools like the Android project's repo utility, gitk, magit in Emacs, sourcetree, many of which fail to fully wrap the complexity of Git forcing users to both master the wrapper tool and the Git command line especially on more complex projects. Some of these GUI/wrapper tools like Android repo seem to have serious bugs as well.
o Lack of backward compatibility with RCS-style version control systems like Subversion. Instead of building on 30+ years of success and experience with RCS-style version control systems, but extending them sensibly for distributed projects, Git took a "reinvent the wheel badly" approach.
o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Git.
Sounds like you were bit by rebasing, rather than by git itself.
Yes, the API is large and complex. But git itself is easy to learn, and extremely powerful. Whatever situation you might have gotten yourself into, git probably has a good way to handle it.
There's one rule I abide by, which makes my git usage sane: no rebasing. Everything stays in the history, and there's no reason to squash commits into one giant context-less commit.
The only common case in which rebasing is valuable is in getting rid of meaningless commits constantly merging the latest master into a feature branch.
I don't get the "rebasing sucks" argument about why git is bad, at all. Most professional arenas will have a source control best practices document, how hard is it to say "no rebasing allowed"? Just because a feature exists does not mean it has to be used or even should ever be used.
> o Git has been bundled with code review systems like Gerrit which encourages developers to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes, debug, engage in trial and error, or all the other things developers actually do. When a bug does slip through as if often does despite the supposed quality-control benefits of code review, then reconstructing what happened from the rebased "history" can be a nightmare.
I've never seen anyone do that in a professional environment. My coworkers laugh at me because my most common commit text?
"fixed XYZ??"
Sometimes, multiple times in a row.
> o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Git.
I think this stems from hanging out in online forums. Git is flawed.
Git's virtues are the size of its ecosystem, the fact it is distributed, and the fact it is useful to some people.
> Git has been bundled with code review systems like Gerrit which encourages developers to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes,
I am not sure if I understood you correctly... say the doc string has a typo and you already merged in, are you suggesting you rather see a separate commit rather than rebase it?
My workflow can be different depending on what I do. For most personal projects, since I am the only audience, I will just rebase as many times as I want. However, I would use git's branching for experimental stuff if I don't want to touch the master branch. For professional / real OSS I will create new branch, submit pull request and merge in. For real project, before I merge in, a code review is necessary. And I keep my work using git's branch or mercurial's patch queue.
> o Complex, confusing terminology including multiple non-obvious names for various components.
Yes, this is obviously the first thing that makes me unhappy. I switch between git and mercurial and sometimes after using one or the other for far too long, I will forget the correct syntax. I wish both will just work together and standardize a set of command once and for all.
Editing the commits has always seemed the inappropriate fix. Editing commit messages and tagging commits seems like a more reasonable approach - tag a commit as a typo/mistake/intermediary and tag the "build-ready" commits as such.
> say the doc string has a typo and you already merged in, are you suggesting you rather see a separate commit rather than rebase it
You probably mean amending an existing commit, not rebasing. Gerrit encourages repeatedly amending a commit to incorporate review feedback, thereby erasing history from git.
And why NOT have the typo fix as a separate commit? Are you paying by the SHA1 hash? The thing is, you aren't really keeping a clean history, you're just redirecting it to another, less flexible abstraction layer. The complete history is still in gerrit for anyone to look at, but now it can't participate in git blame, git bisect, etc.
> For real project, before I merge in, a code review is necessary
But this is just begging the question. Why is it necessary to do a code review before a merge, instead of after?
> You probably mean amending an existing commit, not rebasing.
Hmm yes correct.
I have never used Gerrit so I don't know what that whole fuzz is about. I am more into what he meant by rebase is bad.
> But this is just begging the question. Why is it necessary to do a code review before a merge, instead of after?
By merging I am talking about merging with the master repo, or upstream in Git's world.
You work on your local repo, preferably a new branch so you can work on multiple stories (I use branch as patch). Before I want to merge into the upstream for real professional project, I want to do a proper code review. If I work with people using Mercurial, I prefer people use patch queue. I don't like history to be ugly. I want each history has its own meaning. Why? Because when I blame I want to narrow down quickly (yes there are ways to do that really fast, but let's stick to just browsing on Github). If you edit the same line twenty lines just to fix a small typo, wow, that's not cool. I've dealt with projects and some people like this:
fix typo
fix typo2
fix as suggested in comment 2
fix as suggested in comment 5
This is particularly painful in Mercurial if you don't use patch. Rebase in mercurial is pretty tough for me, at least my experience. So I apply the same logic to git: branch, rebase and submit PR, bug found, back to branch, fix, rebase, repeat. In the end what I care about is the commit links to the issue # and a good commit message.
Would you rather read the commits above or "Fixed #1913 XXXXXXXXXXX"? I try to make sure every commit follows something like "Fixed #" in my professional repo. Sometimes I fail to do that, but I try my best. It's my workflow and I think it's reasonable.
--EDIT--
I just want to make sure we are clear about professional vs personal.
In a professional OSS project, there are many users and so rebasing on a master repo is not acceptable because someone might already working on the older version. The only time I will ever rebase the master commit is if I need to remove "sensitive data" leak (yes, at that point I am screwed because someone might have checked out the original commit). In a professional setting, a typo found in master commit should be filed as a new bug and fixed as a new commit.
In a personal project it's up to me to decide. I can be lazy like committing hundreds of "fix this fix that." But I usually don't.
The main argument against not having a separate commit is that with large projects the history becomes useless when every commit is type fixing.
In the case of fixing typos or making tiny changes that don't really deserve their own commit, the person making the tiny changes should also be the person who made the last big changes too.
---
> Why is it necessary to do a code review before a merge, instead of after?
Because most of the time you want master to be working, and working as well as possible. In a team environment, you shouldn't all just be throwing everything on master, that leads to unnecessarily crazy history.
You review it before to say "alright, this is good, we all like this, this could be placed in production now if we wanted".
o Complex, confusing terminology including multiple non-obvious names for various components.
o Huge number, about 148, of commands with many sub-commands that often do non-obvious, even unrelated things.
> Git has a learning curve. No way around it. I would argue that it is an extremely powerful vcs worth spending the time to learn.
o git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
> There are some situations where rebase are permissible. Again, this goes back to the learning curve. On most teams, though, I find it helpful to just put a ban on rebasing.
o Git has been bundled with code review systems like Gerrit which encourages developers to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes, debug, engage in trial and error, or all the other things developers actually do. When a bug does slip through as if often does despite the supposed quality-control benefits of code review, then reconstructing what happened from the rebased "history" can be a nightmare.
> I've never heard of this/this happening but this doesn't sound like a specific gripe against Git. Either way I don't know enough to counter it.
o There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
> These commands do similar, but different things. Part of the allure of Git is its immense flexibility and power. On the CLI, the only way to do this really is to have a lot of commands and options. Again, take the time to learn Git and you will be rewarded.
o A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches, making locating changes and reconstructing the history of changes extremely difficult. A change can occur on a local branch on one developer's computer, be rebased into another local branch and then finally rebased or merged into the shared "master" branch.
> This is a workflow problem. You need to talk to your teammates and establish habits to stay in sync.
o Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files as well as snapshots of the entire project. Even if you track down the tricks to compile the SHA into a program or file name, the SHA is not sequential making it difficult to know which version of a file or group of files is in a program.
> I've never found this to be an issue whatsoever.
o These many flaws in git and its command line interface have resulted in a proliferation of third-party add-on tools like the Android project's repo utility, gitk, magit in Emacs, sourcetree, many of which fail to fully wrap the complexity of Git forcing users to both master the wrapper tool and the Git command line especially on more complex projects. Some of these GUI/wrapper tools like Android repo seem to have serious bugs as well.
> The CLI is fine and consistent IMO. Sourcetree is great if you prefer GUI and has all the power most users need.
o Lack of backward compatibility with RCS-style version control systems like Subversion. Instead of building on 30+ years of success and experience with RCS-style version control systems, but extending them sensibly for distributed projects, Git took a "reinvent the wheel badly" approach.
> That is a ridiculous thing to say. Git brings a very unique and powerful paradigm to VCS which is the distributed model. It also allows for a variety of different workflows and usages due to its flexibility. Not adhering to an existing standard is not ipso facto a flaw.
o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recog...
>git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
This is a common complaint but it's based on a preconceived notion of the word "history" rooted in intuition instead of re-evaluating what "history" means in the universe of Git. (Actually the generalized universe of DVCS and not just Git.)
One type of "history" is something immutable and suitable for forensics. Examples such as a history log file of changed bytes written to database blocks. This history must be perfect and unchangeable or things like db recovery and master+slave replication will not work. Another example is "history" of financial credits and debits across accounts. That type of "history" shouldn't be changed because it would render financial audits and fraud investigations useless.
In Git, there's another perspective on "history". It is a "history for public dissemination" which is very different purpose than database log history or financial accounts transaction history. Since the "D" in DVCS is "distributed", it's this "history for public consumption" that expands how "history" should be viewed in Git/DVCS.
If you're working 100% local private repository and never collaborating with others, you can avoid rebase and just do merges. However, as a social courtesy to other distributed programmers, rebase is a cleaner public presentation of new changes for others to see/review. Whether you did your work against on a public tree you pulled down on Monday or Wednesday makes no difference to people upstream looking at your changes. Rebase eliminates a lot of noise.
It's letting go of forensics type history and embracing social public consumption type of history. This type of disseminated history was important enough that Mercurial also added an extension for it[1]
When I am debugging a complex program, I need the "real history" to find subtle bugs as quickly as possible. Similarly, if the project is shared with others and they need to debug my code efficiently, they will need access to the actual history, warts and all, not a "history for public dissemination" produced by the project's Ministry of Truth.
Version control systems were developed to enable developers to quickly and efficiently find the specific change that caused a bug or other problem discovered later. Rewriting history, for example squashing numerous changes into a single commit using Git's interactive rebase, defeats this main purpose of version control.
It is difficult to see a good reason for a "history for public dissemination." This is the sort of thing Orwell decried in Animal Farm and 1984 as well as his factual writing. Instead of highly subjective code reviews that introduce politics and personal prejudice, focus on objective tests of the performance of the software.
The more sensible approach is to share the project's actual development history for developers and tag production releases and release candidates in some way. Obviously only developers need to worry about non-production versions of the code.
The Linux kernel has ~15 million lines-of-code with 1100+ contributors. I think you would agree they have to deal with complex and subtle bugs as well. They also extensively use rebase. Dealing with a thousand commits that say "fixed spelling error in code comment" to satisfy your idea of "pure unchanged history" would be maddening.
In any case, it's a matter of perspective I guess.
In Git workflow,
the "real history" --> git reflog.
the "idealized history" is output of --> git rebase.
If I interpreted you correctly, what you want is:
"real history" --> git log
"idealized history" --> git tag -l
It's understandable you feel that way but I'm glad Git chose the first way. It fits better with the philosophy of the "D" in DVCS.
Version control systems were developed to enable developers to quickly and efficiently find the specific change that caused a bug or other problem discovered later. Rewriting history, for example squashing numerous changes into a single commit using Git's interactive rebase, defeats this main purpose of version control.
That's not a problem of git, but the person using it. In fact, I often saw people using Subversion making jumbo commits, since Subversion makes it so hard to split changes in a working tree up in multiple commits and makes branching painful.
You mention finding bugs. I'd rather look at a history that was rewritten in 5 tidy commits than 10 commits where 5 are 'fixed indenting', 'fixed typo', or intermediate data structure changes.
No, it's pretty widely regarded as a good, but not perfect, DVCS.
Complex, confusing terminology including multiple non-obvious names for various components.
DVCS is inherently complex. Git's terminology might possibly be improved, but it's not really all that bad. It just requires a bit of learning.
Huge number, about 148, of commands with many sub-commands that often do non-obvious, even unrelated things.
That's the same point. There are a lot of tasks to accomplish in a DVCS, which requires a lot of commands. You don't have to use these: they just have to be available for those that need them.
git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
Rebasing allows a user to rewrite history such that it makes sense, in terms of the changesets applicable to the repository as a whole. That's not a subversion - it's intentional.
Git has been … reconstructing what happened from the rebased "history" can be a nightmare.
This is a workflow problem, not a tool problem.
There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
This is the same thing as your first two points. These command all do similar, overlapping tasks, but are all useful in different circumstances.
A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches
Yes, and git's lightweight branches are great. I have never been in a situation where this causes problems; if you are encountering those, then you have a problem with workflow. Don't blame the tools.
Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files
I don't even know how you think that would work in the context of a DVCS.
* These many flaws in git and its command line interface have resulted in a proliferation of third-party add-on tools*
That "third party tools exist" is not a valid complaint.
Lack of backward compatibility with RCS-style version control systems like Subversion. Instead of building on 30+ years of success and experience with RCS-style version control systems, but extending them sensibly for distributed projects, Git took a "reinvent the wheel badly" approach.
Git can be used in almost the same fashion as SVN by learning that a couple of commands have different names.
A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Git.
Not that I've observed. Git is popular because it's quite good - equivalent or better to other DVCS systems. That's not a cult of personality.
tldr; git isn't that bad - it's quite complex, and it's a powerful tool that relies on users to be responsible. But that's not really a bad thing, as far as I'm concerned. It's certainly better than subversion for every project I've worked on.
Note: Overrated means something is widely regarded as good ... but isn't.
A version control system should be very simple, hardly noticeable like the original RCS.
1. checkin the current version after each change.
2. if a serious problem is encountered, checkout an earlier version to see what happened and find when and where bug was introduced.
That is about it and RCS does it with a handful of commands.
The obvious question is why can't a distributed version control system like Git hide most of the complexity of managing a network of distributed repositories from the developer, at most adding a few network commands, e.g. clone, pull, push? Where do the 148 commands come from?
Why not just use the standard RCS command line interface with a small number of additions and let the back end deal with the distributed repositories? Extend the RCS/CVS/SVN sequential ids with a suffix to identify something like repository/branch to keep track of local changes?
A version control system should be [...] hardly noticeable
And that right there is the fundamental philosophical difference which is preventing you from understanding why people like Git. It's not just a revision control system, it's a tool for crafting code and patches. Git is a fundamental part of my workflow for how I write code locally, even without contributors, and beyond backup/undo use-cases. However, with contributors, patches count as communication, and tools to help me craft those patches effectively were missing from my toolbox prior to Git.
I think I have a good understanding of why people like Git. I question whether they should.
In my experience, the time to learn Git for people unfamiliar with it is significantly larger than for any RCS-style version control system including Subversion which is probably the most complicated RCS-style version control system. Similarly, even if you are proficient with Git, on average it takes significantly longer to use Git to do the same things as an RCS style version control system. This is true even if you use Git in a very simple way. If you use it in one of the very complex ways like the Android project/Git/Gerrit/Jenkins morass, it will take a lot longer.
This time is a real cost to a business or an open-source project or what have you. Simplicity is often faster, cheaper, and better.
I argue that it is more effective in a team project to share the actual history of the development in a shared development branch -- warts and all. Production and release candidates -- the works of art that you are trying to create -- can be tagged or identified in some other way.
Oh c'mon, this is handwavy no-true-Scotsman bullshit. Anybody who says you're wrong, that they're faster, will be referred back to your unsourced claim of "on average".
As for me: I administered and supported SVN at a shop with about a hundred and twenty developers and about half a million commits and an overall trunk size in the gigabytes. I've spent time in the SVN codebase and am comfortable saying I understand it and can wield it better than most people who aren't committers. And guess what? I'm significantly faster at using Git for pretty much anything I've ever had occasion to do with it, while being able to leverage the conceptually-very-simple plumbing architecture of Git to do things that make other developers a lot faster.
(Git isn't perfect. Mercurial is better. But the answer isn't regression to a poorer model.)
o Complex, confusing terminology including multiple non-obvious names for various components.
o Huge number, about 2000, of commands with many sub-commands that often do non-obvious, even unrelated things.
o There are numerous commands to do similar, overlapping but nonetheless different tasks.
o A supposed virtue of Linux is that it makes it extremely easy to create "mounts." This often leads to a proliferation of mounts, making locating files extremely difficult.
o Cryptic "paths" for identifying files instead of sequential numbers for individual files as well as snapshots of the entire project.
o These many flaws in Linux and its command line interface have resulted in a proliferation of third-party add-on tools like GNOME, KDE, many of which fail to fully wrap the complexity of Linux forcing users to both master the wrapper tool and the Linux command line especially on more complex projects. Some of these GUI/wrapper tools like GNOME seem to have serious bugs as well.
o Lack of backward compatibility with real mode-style version control systems like DOS. Instead of building on 20+ years of success and experience with DOS-style operating systems, but extending them sensibly for distributed projects, Linux took a "reinvent the wheel badly" approach.
o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Linux.
Actually many of these are genuine problems with Linux specifically and Unix in general. This is one of the reasons Microsoft Windows dominates.
For example, cryptic non-English commands like grep, ls, rm, etc. make the Unix command line difficult to learn, remember, and use.
One exception:
Despite their faults, the Linux/Unix file paths are far more human readable than a Git SHA (hexadecimal code). The issue with Git versus RCS-style version control systems is that a RCS-style sequential numbering scheme such as 1.2.3 (major release number, minor release number, patch) is much more human readable than a SHA (a3fee20). The analogy in the satire misses the mark.
Linux actually has suffered from a fanatical cult-like following mesmerized by Linus Torvalds that often was (still is sometimes) unable to recognize and acknowledge weaknesses of Linux versus Microsoft Windows. Linux has had to play catch up to provide a comparable GUI, installers for software packages, and other usability features in Windows and the Mac.
Those are definitely fair criticisms. However I personally believe that the foundation of both Linux and Git are very solid and that's why I will always prefer them.
oh come on, windows dominates the desktop market purely for historical reasons.
It has nothing to with windows' developer tools, which are significantly more obscure than the unix equivalents.
Have you written powershell scripts? How about .bat files?
Youre partially right; some unix tools are obscure, and have odd invokation syntax (find for example)... but I think you've completely lost the plot (or never actually developed for the platform) if you think windows has done a better job.
In the 1990's and early 00's, Linux was significantly more stable (and cheaper) than Windows. The infamous "blue screen of death" occurred frequently. Linux gained a lot in server-land compared to Windows for this reason.
Windows has gotten more reliable in the last decade. It is rare that it out and out crashes anymore, but it still seems to start doing odd things that go away after rebooting. I would still pick Linux for reliability of the underlying OS any day.
On the other hand, Linux was (still is) difficult for a typical end-user on the desktop. It was easier to install and operate software due to the Windows GUI etc. Linux has played catch up with GUI desktops etc.
As far as development tools (I have developed both Windows and Unix software), Microsoft Visual Studio has some very nice features such as IntelliSense compared to the Unix/Linux vi/vim and emacs tools. Notably, emacs has the CEDET project which is working hard to add IntelliSense like capabilities to emacs.
No offense, but seems your problems coming your unwillingness to learn git properly. If you would take the time and learn it (reading Pro Git book, learning from visual tools, which there are a ton, etc) (Again, no offense, just suggestion.)
> Huge number, about 148, of commands with many sub-commands that often do non-obvious, even unrelated things.
You don't need to know all 148 of them. If you only know 16 (1/9 of them): add, branch, checkout, commit, config, fetch, log, pull, push, rebase, reflog, remote, reset, show, stash, status, You can do pretty complex things already. For day-to-day usage, these are more than enough.
> git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
Git rebase enables very simple workflows, like the GitHub workflow[1], which IMO is quite simple, small overhead workflow, pretty useful and scalable.
Git rebase is also for local repo only. In every tutorial and even git command recommends against pushing rebased branches to an already pushed remote repository. If you keep this in mind, it makes sense.
> ... to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes, ...
I think the reason is not that they want to hide their mistakes, but to clean the history. Would you rather see typos in a history? IMO it's just cruft, an amend or rebase pretty much just a clean up you can read it more easily, and you don't have to deal meaningless 'Fixed a typo' comments...
> There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
git revert is not the same as git reset. git revert creates a new commit on top of the commit you want to revert. git reset move the HEAD. Totally different operations.
git reset --hard, --soft, etc does the same thing, just differ how they handle the index and working tree, and once you understand I think it makes sense.
> A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches, making locating changes and reconstructing the history of changes extremely difficult.
If you stick to a simple workflow and rebase constantly, this is not a problem at all. Not everybody needs git-flow[2]. If you work on the same files with somebody, I think this will always be a problem, no matter what VCS you use, but with git there are a couple of merging strategies which can facilitate the process.
> Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files as well as snapshots of the entire project.
The SHA1s are for security. A commit's SHA is actually the SHA1 of that snapshot, so if you change any bit of that snapshot manually, git will complain about it[3]. It is basically that nobody can change code unnoticed!
> Lack of backward compatibility with RCS-style version control systems like Subversion.
I don't really understand what you mean here, but there is the command git svn, which is perfectly compatible with SVN. Recently I converted a whole SVN repository to Git without even losing one commit or message or anything...
Also Git supports many more workflows[4], not just centralized.
> ... many obvious problems with Git.
Of course git is not perfect, but instead of ranting about it, you could learn it in a couple of days and work with it, becase many of us think it's pretty flexible and as simple as you want it to be. Actually, if you learn only two commands: add and commit, you can use Git, nobody stops you doing that if you find the other parts difficult.
I actually have been using Git extensively for 1 1/2 years. I have read the Pro Git book and many other sources cover to cover several times. I use magit with Emacs and gitk extensively. I gave up on the Android repo utility after it repeatedly goofed up the equivalents of git pull --rebase.
My complaints about Git are based on direct experience and watching others struggle with it.
Yes, I can and have set up Git in a very simple way not unlike an RCS project that avoids most of the issues that I discuss. No rebasing. Minimal use of branches, just a simple approximation of a development/production branch system. Nonetheless there are several problems with Git that still bit me such as the lack of sequential ids for files and the confusing terminology (staging areas, the index, etc.) and documentation.
For a better Git:
1. Clean up the documentation and man pages to remove the confusing terminology. Settle on one name for the "index" and so on.
2. Ditch rebasing.
3. Use sequential ids with a suffix of some sort for local changes. e.g. 1.2 on the master, 1.3.repo.branch or something like that for local changes. Keep the SHA, hide the SHA, but give users an easy intuitive way to access the SHA if needed.
1.1
1.2
1.3 \
1.4 1.4.myrepo.master
1.5 |
| /
1.6
1.7
I would guess there is some scheme like this in some other distributed version control system.
You really are completely clueless. Rebasing is invaluable for use on private branches that no one will ever see but the developer. It allows you to clean up your history before others see it.
EDIT: oh, and you can make a hook (like I did from day 1) that disallows non-fast-forward pushes to certain public repos.
Absolutely. Like, normal git log wouldn't show them only the branch merges but if you dig deeper then you'd see them. Or even allow to mark a commit as "superficial" (wikipedia has superficial edits). It is very easy to hide commits but once rebase destroys them it is impossible to see them even if needed.
Consider how scientific research works: you write down everything you do, preserve them and publish a book/paper/etc at the end. If it turns out you were not right then it's possible to peek at the notebooks later but if you were, noone ever will care.
I never rebase commits which clearly shows how I got from point A to point B, even if I was wrong at the first time, but keeping typos in the log I think is silly.
It is true that Git can be used in a fairly simple way, although it is still significantly more complex than RCS. RCS has the whopping total of nine commands, admittedly with various options and subcommands. $git --help yields a list of twenty-one commonly used commands out of the 148.
However, in practice, Git is being used in rather complex ways that are error prone and often lead to using other commands than the twenty-one "commonly used" Git commands such as git reflog, cherry-pick and others not in the "commonly used" list.
I have seen people combine a large number of changes into a single commit using Git's interactive rebase. The actual history remains in a local "private" branch on someone's computer. If it later turns out there was a bug introduced in this rebased mega-commit, it may be impossible to find the actual history and localize the actual change that caused the problem.
Even with access to the local repository, the actual changes may be found only in a feature or fix side branch with a cryptic name, one of hundreds generated using the lightweight branching in Git. There is no simple linear history of the changes with rebasing.
git reflog, in principle, gives a complete history but it is a confusing log of everything done and the information stored in it has an expiration time, which defaults to 90 days.
--expire=<time>
Entries older than this time are pruned. Without the option it is taken from configuration gc.reflogExpire, which in turn defaults to 90 days. --expire=all prunes entries regardless of their age; --expire=never turns off pruning of reachable entries (but see --expire-unreachable).
The obvious question from a usability perspective is: if twenty-one commands are all you really need, why confuse users with 148?
Actually, I got an astonishing 165 git commands using
It is true that Git can be used in a fairly simple way, although it is still significantly more complex than RCS.
What's the point? RCS is not fit for distributed workflows/projects. Once you start to work in such a fashion, you want multiple remotes, tracking branches, rebasing (if only to make submitted patches as clean as possible), security/consistency per SHA hashes, etc. This simply implies more complexity and commands.
Sure, git could be simpler, some argue that Mercurial is easier. But RCS is definitely not the program you want to compare git with.
My point is the user interface, the command line interface, should be really simple, not much more than RCS's nine commands. Any necessary complexity should be hidden from the software developer so he or she can focus on developing the software and getting it working as quickly and effectively as possible.
There are many examples of simple user interfaces layered on top of very complex programs and algorithms. Media players usually have a very simple GUI with a PLAY/STOP/PAUSE buttons and a volume control. Audio/video codecs, display drivers and so forth are extraordinarily complex but ideally the end user should not need to worry about this at all.
Many of the Git GUI tools like sourcetree are an attempt to address this usability problem with the Git command line interface.
I actually think an entire repo of libraries is the wrong way to go. With the git model, we have however many repos acting as the source for these libraries. This repository that contains all of these submodules can then be the arbiter of which version should be included in the release.
> Yes, some will say - but this is good - centralization is bad... Well, it depends. If you can spend time to figure out who is who, then it will work for you.
And this problem doesn't exist with SVN? Sure, maybe if you are the sole publisher of all these libraries it might be ok, but with most real world examples, there exists multiple contributors. Now they need to go through you when there needs to be a specific update to that library. With git, the maintainer of the repo of libraries(submodules) just updates the specific submodule to whatever release works for their tastes.
Most of these complaints sound like an SVN user having some pain when trying to think in git.
A benefit of git, for which I can forgive a lot of git's flaws, that was not mentioned in the conclusion is the light-weight branching. The ability to quickly make a branch, experiment, branch off that, merge back, cherrypick commits from another branch, etc. makes me more efficient by spending less time worrying about affecting stable code with experimental changes.
Yup this is exactly it. For developers fluent in git, it is a very real part of their development cycle (branching, rebasing, etc). What I've seen of most SVN (and going back to CVS) is that their SCM is more or less just an archiving tool. A place after you've done all your hard work you use it as a fancy rsync tool to back it up. I don't see a lot of SVN users making svn the same part of their workflow the way git devs do. Maybe it's just the developers I work with though.
re: the "Impractical for single repository of libraries" section... The author seems to think the only way to manage many different plugins is to split them into different repos: "If you have e.g. 100 plugins, you should have 100 repos."
Many times, 1 repo works perfectly fine for 100 plugins. As for wanting to only work with a subset of the files, the way git wants you to do that is to branch and change the subset you want to change (someone else has already pointed that out too here in the comments). What to split into how many repos is often a very subjective call, and depends on team, respository size, and workflow.
A real-world example where 1 repo works perfectly fine is the Linux kernel. Within one repo, you have all sorts of drivers for all sorts of hardware, and you have arch-specific support for a dizzying amount of processors and variants. The repo takes a while to clone the first time since it's kind of big, but thereafter works perfectly fine as you whizz between branches and jump between tags.
On some level, I understand the author's frustration with git, since it's quite a paradigm shift from centralized repos like Subversion. I made that shift myself once, and at first I didn't like being forced to play by git's rules of the universe (or more correctly, the DVCS rules of the universe). I have come to deeply appreciate those new rules over time.
There are, in fact, valid criticisms of git. One that comes to mind is the complexity and amount of operations... looks like others have already commented on this sort of criticism.
Sounds like the author has a workflow problem here. Most of the reasons given of why Git sucks could be from the OP's inability to adapt their workflow.
SCM is a matter of choice; there is no right or wrong answer and people need to get over being right.
> In Git, you can checkout neither a single folder nor a file.
Yes, you can. It's called sparse checkout[1] and not that hard.
Also, you can subtree merge[2][3] directories back and forth preserving all the history and merging back if you wish (cutting a directory out of the repository to a separate one and putting it back). It's pretty easy to do in git>2.0 because there is a builtin subtree command[4] for it.
There is no practical difference. Yes, you clone and have the whole repository on the disk, but after a sparse checkout you only have to deal with the files you are interested in.
The only problem can be with Facebook-sized repositories, but I believe in modularizing that big of a system instead of storing everything in one vast repository.
It's impressive how a software became a defacto standard when things like mercurial or SVN existed long before it.It's not just hype or Github,though it helps.It's the distributed nature of the software that makes it powerfull, also the fact that git itself is more like a protocol than a piece of software.But git dont work for every use cases though( big binary blobs ),so there is still room on the market for such cases.
I'm a fan of using the right tool for the job. If you can't use git effectively or it just doesn't fit into your workflow, then, hey, don't use it.
But, having used both, I'd actually like to know... Why are these things (that the author is claiming git can't do) so important? For instance, is checking out a partial tree ever necessary? Is it that you'd want more granularity over what subsets of the repo you are storing locally? Is it that you don't want to have to set up a bunch of (sub-)repositories?
I ask because... I once worked on a codebase that was so absurdly huge most of us couldn't store it all on disk at once. And it sucked. Hard. I WISH it had been started as a bunch of distinct submodules, with extension points baked into the core build system so it would be easy to add/remove sections of the codebase. But the product predated git. And SVN for that matter. (Granted, the majority of the issues we suffered -- nightmarishly complex build systems, lack of transparency into what changes are being made, a bottleneck of devs lining up to commit changes -- were caused by process issues, not source control. But the source control did absolutely nothing to help either.)
I really understand the frustration when it comes to git. It took me a LONG time to wrap my head around why it works the way it does, because I wanted/expected it to work like SVN, where the repository is like a giant tree of files reflecting exactly what I see on disk, with different branches of code getting their own branch of the tree. Instead, git was this concise, magical pile of data structures that somehow kept causing me to break things whenever I strayed too far from a basic commit & push workflow.
But then I changed jobs a couple times. And, for some reason, I no longer found git a huge pain. In part because it just started becoming more natural and I knew what kinds of things to avoid, but also because I decided to sit down and really learn what I was doing. For one thing, I began making more active use of rebasing. Initially so I didn't need a ton of useless merge commits to keep up-to-date with the master branch, but eventually as a way of tidying up my work on a feature branch (i.s. squash, reorder, amend, etc) to make the set of changes concise and easy to follow. When working locally on a new feature branch, my commit log went from looking like this:
> okay one more try at part A [tests pass]
> fixing typo [tests pass]
> one last thing for part C [tests fail]
> part B bugfix [tests pass]
> fixing bug in part C [tests fail]
> finishing part B [tests fail]
> trying this again (feature A) [tests fail]
> part C, work in progress [tests fail]
> part A, I think [tests fail]
...
To this (more or less):
> part C [tests pass]
> part A (final implementation) [tests pass]
> part B [tests pass]
> part A (initial implementation) [tests pass]
...
Depending on who you are, you'll either love that, or you'll scream at my lying, revisionist git log before wrenching out your eyes and hurling yourself out a window. But, for me, for the team I was working with, and for the codebase I was working on, it worked WONDERFULLY. I found myself feeling like I really controlled the readability of my changes. Each of those commits could be submitted individually for code review with no problems, and even though I was wiping out a ton of minor changes, I could still preserve a record of alternate implementations in case we wanted to refer to them later.
Anyway, this post has become a long ramble. But, suffice it to say, I've found git to be very freeing. I just had to give up any expectations about how the process would work, and let myself start forming a new process around the power and flexibility that git offers. I believe I could say the same for mercurial (though I don't have much experience on it). And I don't think I can say as much for SVN, though I'm sure it d...
I just wanted to say that even if you don't read this article, this discussion here on HN is very enlightening for people who tend to only use a small subset of git operations in their day-to-day small-team dev tasks (like me).
81 comments
[ 4.0 ms ] story [ 151 ms ] threadI never felt that type of pain with SVN, it more or less just maps to directories.
To each his own I wish there was the right way to use git in 50 words or less. If I need to read a book to correctly use it ... grrrrrrr.
There is an excellent link out there that explains git in layman's terms. I think it's called git for hackers or something of the sort. It's much easier than the docs in my opinion.
Things should be fetched then merged with two separate commands.
Of course, if (like thrush) you do not plan on doing a merge, then you will need to do the fetch manually and do what you do want to do. Although, git pull does have a --rebase option, but I am not sure if you can pass the -i flag to it.
Having taught people how to use git, I found that it is easier to not show them the pull command until they are used to doing fetch && merge.
The end result is a situation where you have to learn a lot about how git works internally to actually have an idea if how you are using it makes sense or not in relation to your project.
git isn't nearly opinionated enough for simple usage patterns, IMO. I like the flexibility it offers but it would be nice for new adopters if it were more hidden and there was a more obvious "happy n00b path" to take when first starting with it for the majority of projects that don't have the sort of distributed development challenges that the linux kernel does.
Note: I'm not the OP and I'm really comfortable with git now, but I've been where OP is and totally understand.
Ironically, that's one of my major fatal objections to SVN, the way it casually encourages developers to have a code checkout that doesn't actually exist in the source repo, as you check out various versions in various subdirectories without even thinking about it if you aren't careful. Back in my SVN days I lost track of how many times it worked on somebody else's box and not on mine, because one or the other of us (or both!) had a checkout that didn't actually represent any particular revision.
"Well, don't do that then!" Of course not, but A: I can still be bitten by other developers doing it and B: SVN really, really affords this. By accident, sure, but it is afforded nonetheless.
In fact in a lot of ways SVN vs. Git reminds me of static vs. dynamic typing... many of the "easier" things that SVN does are also wrong, and many of the things that people are objecting to about git are actually the underlying model being correct, and refusing to be wrong. I don't mean the UI, which is sort of dodgy, sure, but the underlying model.
(Git submodules are sort of that way... in many ways, the difficulties in using them are reflective of the fact that correctly embedding one source code repo in another is actually fundamentally hard, and anything that makes it easy is probably just glossing over some fundamental problems. It is probably possible to make it easier, but if it has been made easy, one should immediately be very suspicious.)
I am far from being good with Git yet but why couldn't the translator simply branch out and only merge back his XML files ?
The only really clean solution is to use submodules (or the newer variation on the theme, git subtree). But those aren't entirely smooth either.
Come to think of it, it could be solved technically even with git -- the XML guy's repo gets a pre-commit hook that verifies that he's committing changes only to the files he's allowed to edit. (We're now requiring him not to mess with that hook, but if that's a problem, maybe they shouldn't have source code access at all. The point is that now a tool is doing the checks, which frees up the humans for things that really do require human judgment.)
However, it feels like comparing SVN to GIT is like comparing horses to automobiles at this point.. Yes, a horse can heal minor damages without a mechanic, your car can't. And it can swim if need arises, good luck with a car on that.
Woudn't choose a horse for anything serious though. Maybe for fun and sports.
I agree git has a more complex interface - I think I've read it described as "not quite user-hostile, but only expert-friendly", which I think fits.
That said, I think the model of how commits work is far more intuitive than anything else I've come across. A commit is just a diff and a pointer to the commit that came before it, and a branch is just a pointer to a particular commit.
You can export a commit as a diff+pointer-to-prev-commit, but when git imports it, it gets turned back into a full tree.
You can't pull a portion of the repo because the current state of the repo is built from the tree of commit diffs... This and the fact that git itself is a hash database leads to very efficient use of space. If you want a single folder within a repo, why isn't that folder its own repo?
Between that, the passive aggressive ;-) and the unfortunate advocacy of SVN... ugh.
Pointing out technical reasons why git doesn't do the job he wants doesn't make it useful for him, it just points out why the problem is hard to fix.
.. though it never used to.
I don't agree with the criticism of the article (though there are plenty of UX reasons to be critical), but this is hardly a punching yourself in the face kind of behaviour.
Needing to know about the internals of git is a flaw of git, not a feature.
They are use cases which matter to the author. That's basically the opposite of superficial.
> If you want a single folder within a repo, why isn't that folder its own repo?
The author addresses this -- because the folder is not significant enough to warrant the overhead of placing it in a separate repo.
Sure, but knowing that is essentially irrelevant if your workflow involves a need to check out a partial tree, and Git makes it (hard|impossible|unwieldy|whatever) to do that.
If you want a single folder within a repo, why isn't that folder its own repo?
Because needless proliferation of tiny repos is a problem in its own right?
and the unfortunate advocacy of SVN... ugh.
There's nothing unfortunate about advocating SVN, if SVN is a better fit for your workflow - and by extension, presumably, someone else's workflow which happens to mirror yours.
Other problems include:
o Complex, confusing terminology including multiple non-obvious names for various components.
o Huge number, about 148, of commands with many sub-commands that often do non-obvious, even unrelated things.
o git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
o Git has been bundled with code review systems like Gerrit which encourages developers to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes, debug, engage in trial and error, or all the other things developers actually do. When a bug does slip through as if often does despite the supposed quality-control benefits of code review, then reconstructing what happened from the rebased "history" can be a nightmare.
o There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
o A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches, making locating changes and reconstructing the history of changes extremely difficult. A change can occur on a local branch on one developer's computer, be rebased into another local branch and then finally rebased or merged into the shared "master" branch.
o Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files as well as snapshots of the entire project. Even if you track down the tricks to compile the SHA into a program or file name, the SHA is not sequential making it difficult to know which version of a file or group of files is in a program.
o These many flaws in git and its command line interface have resulted in a proliferation of third-party add-on tools like the Android project's repo utility, gitk, magit in Emacs, sourcetree, many of which fail to fully wrap the complexity of Git forcing users to both master the wrapper tool and the Git command line especially on more complex projects. Some of these GUI/wrapper tools like Android repo seem to have serious bugs as well.
o Lack of backward compatibility with RCS-style version control systems like Subversion. Instead of building on 30+ years of success and experience with RCS-style version control systems, but extending them sensibly for distributed projects, Git took a "reinvent the wheel badly" approach.
o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Git.
Yours truly,
Bit by Git
Yes, the API is large and complex. But git itself is easy to learn, and extremely powerful. Whatever situation you might have gotten yourself into, git probably has a good way to handle it.
There's one rule I abide by, which makes my git usage sane: no rebasing. Everything stays in the history, and there's no reason to squash commits into one giant context-less commit.
The only common case in which rebasing is valuable is in getting rid of meaningless commits constantly merging the latest master into a feature branch.
I've never seen anyone do that in a professional environment. My coworkers laugh at me because my most common commit text?
"fixed XYZ??"
Sometimes, multiple times in a row.
> o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Git.
I think this stems from hanging out in online forums. Git is flawed.
Git's virtues are the size of its ecosystem, the fact it is distributed, and the fact it is useful to some people.
I am not sure if I understood you correctly... say the doc string has a typo and you already merged in, are you suggesting you rather see a separate commit rather than rebase it?
My workflow can be different depending on what I do. For most personal projects, since I am the only audience, I will just rebase as many times as I want. However, I would use git's branching for experimental stuff if I don't want to touch the master branch. For professional / real OSS I will create new branch, submit pull request and merge in. For real project, before I merge in, a code review is necessary. And I keep my work using git's branch or mercurial's patch queue.
> o Complex, confusing terminology including multiple non-obvious names for various components.
Yes, this is obviously the first thing that makes me unhappy. I switch between git and mercurial and sometimes after using one or the other for far too long, I will forget the correct syntax. I wish both will just work together and standardize a set of command once and for all.
You probably mean amending an existing commit, not rebasing. Gerrit encourages repeatedly amending a commit to incorporate review feedback, thereby erasing history from git.
And why NOT have the typo fix as a separate commit? Are you paying by the SHA1 hash? The thing is, you aren't really keeping a clean history, you're just redirecting it to another, less flexible abstraction layer. The complete history is still in gerrit for anyone to look at, but now it can't participate in git blame, git bisect, etc.
> For real project, before I merge in, a code review is necessary
But this is just begging the question. Why is it necessary to do a code review before a merge, instead of after?
Hmm yes correct.
I have never used Gerrit so I don't know what that whole fuzz is about. I am more into what he meant by rebase is bad.
> But this is just begging the question. Why is it necessary to do a code review before a merge, instead of after?
By merging I am talking about merging with the master repo, or upstream in Git's world.
You work on your local repo, preferably a new branch so you can work on multiple stories (I use branch as patch). Before I want to merge into the upstream for real professional project, I want to do a proper code review. If I work with people using Mercurial, I prefer people use patch queue. I don't like history to be ugly. I want each history has its own meaning. Why? Because when I blame I want to narrow down quickly (yes there are ways to do that really fast, but let's stick to just browsing on Github). If you edit the same line twenty lines just to fix a small typo, wow, that's not cool. I've dealt with projects and some people like this:
fix typo
fix typo2
fix as suggested in comment 2
fix as suggested in comment 5
This is particularly painful in Mercurial if you don't use patch. Rebase in mercurial is pretty tough for me, at least my experience. So I apply the same logic to git: branch, rebase and submit PR, bug found, back to branch, fix, rebase, repeat. In the end what I care about is the commit links to the issue # and a good commit message.
Would you rather read the commits above or "Fixed #1913 XXXXXXXXXXX"? I try to make sure every commit follows something like "Fixed #" in my professional repo. Sometimes I fail to do that, but I try my best. It's my workflow and I think it's reasonable.
--EDIT--
I just want to make sure we are clear about professional vs personal.
In a professional OSS project, there are many users and so rebasing on a master repo is not acceptable because someone might already working on the older version. The only time I will ever rebase the master commit is if I need to remove "sensitive data" leak (yes, at that point I am screwed because someone might have checked out the original commit). In a professional setting, a typo found in master commit should be filed as a new bug and fixed as a new commit.
In a personal project it's up to me to decide. I can be lazy like committing hundreds of "fix this fix that." But I usually don't.
In the case of fixing typos or making tiny changes that don't really deserve their own commit, the person making the tiny changes should also be the person who made the last big changes too.
---
> Why is it necessary to do a code review before a merge, instead of after?
Because most of the time you want master to be working, and working as well as possible. In a team environment, you shouldn't all just be throwing everything on master, that leads to unnecessarily crazy history.
You review it before to say "alright, this is good, we all like this, this could be placed in production now if we wanted".
> Git has a learning curve. No way around it. I would argue that it is an extremely powerful vcs worth spending the time to learn.
o git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
> There are some situations where rebase are permissible. Again, this goes back to the learning curve. On most teams, though, I find it helpful to just put a ban on rebasing.
o Git has been bundled with code review systems like Gerrit which encourages developers to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes, debug, engage in trial and error, or all the other things developers actually do. When a bug does slip through as if often does despite the supposed quality-control benefits of code review, then reconstructing what happened from the rebased "history" can be a nightmare.
> I've never heard of this/this happening but this doesn't sound like a specific gripe against Git. Either way I don't know enough to counter it.
o There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
> These commands do similar, but different things. Part of the allure of Git is its immense flexibility and power. On the CLI, the only way to do this really is to have a lot of commands and options. Again, take the time to learn Git and you will be rewarded.
o A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches, making locating changes and reconstructing the history of changes extremely difficult. A change can occur on a local branch on one developer's computer, be rebased into another local branch and then finally rebased or merged into the shared "master" branch.
> This is a workflow problem. You need to talk to your teammates and establish habits to stay in sync.
o Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files as well as snapshots of the entire project. Even if you track down the tricks to compile the SHA into a program or file name, the SHA is not sequential making it difficult to know which version of a file or group of files is in a program.
> I've never found this to be an issue whatsoever.
o These many flaws in git and its command line interface have resulted in a proliferation of third-party add-on tools like the Android project's repo utility, gitk, magit in Emacs, sourcetree, many of which fail to fully wrap the complexity of Git forcing users to both master the wrapper tool and the Git command line especially on more complex projects. Some of these GUI/wrapper tools like Android repo seem to have serious bugs as well.
> The CLI is fine and consistent IMO. Sourcetree is great if you prefer GUI and has all the power most users need.
o Lack of backward compatibility with RCS-style version control systems like Subversion. Instead of building on 30+ years of success and experience with RCS-style version control systems, but extending them sensibly for distributed projects, Git took a "reinvent the wheel badly" approach.
> That is a ridiculous thing to say. Git brings a very unique and powerful paradigm to VCS which is the distributed model. It also allows for a variety of different workflows and usages due to its flexibility. Not adhering to an existing standard is not ipso facto a flaw.
o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recog...
This is a common complaint but it's based on a preconceived notion of the word "history" rooted in intuition instead of re-evaluating what "history" means in the universe of Git. (Actually the generalized universe of DVCS and not just Git.)
One type of "history" is something immutable and suitable for forensics. Examples such as a history log file of changed bytes written to database blocks. This history must be perfect and unchangeable or things like db recovery and master+slave replication will not work. Another example is "history" of financial credits and debits across accounts. That type of "history" shouldn't be changed because it would render financial audits and fraud investigations useless.
In Git, there's another perspective on "history". It is a "history for public dissemination" which is very different purpose than database log history or financial accounts transaction history. Since the "D" in DVCS is "distributed", it's this "history for public consumption" that expands how "history" should be viewed in Git/DVCS.
If you're working 100% local private repository and never collaborating with others, you can avoid rebase and just do merges. However, as a social courtesy to other distributed programmers, rebase is a cleaner public presentation of new changes for others to see/review. Whether you did your work against on a public tree you pulled down on Monday or Wednesday makes no difference to people upstream looking at your changes. Rebase eliminates a lot of noise.
It's letting go of forensics type history and embracing social public consumption type of history. This type of disseminated history was important enough that Mercurial also added an extension for it[1]
[1]http://mercurial.selenic.com/wiki/RebaseExtension
Version control systems were developed to enable developers to quickly and efficiently find the specific change that caused a bug or other problem discovered later. Rewriting history, for example squashing numerous changes into a single commit using Git's interactive rebase, defeats this main purpose of version control.
It is difficult to see a good reason for a "history for public dissemination." This is the sort of thing Orwell decried in Animal Farm and 1984 as well as his factual writing. Instead of highly subjective code reviews that introduce politics and personal prejudice, focus on objective tests of the performance of the software.
The more sensible approach is to share the project's actual development history for developers and tag production releases and release candidates in some way. Obviously only developers need to worry about non-production versions of the code.
Bit by Git
In any case, it's a matter of perspective I guess.
In Git workflow,
the "real history" --> git reflog.
the "idealized history" is output of --> git rebase.
If I interpreted you correctly, what you want is:
"real history" --> git log
"idealized history" --> git tag -l
It's understandable you feel that way but I'm glad Git chose the first way. It fits better with the philosophy of the "D" in DVCS.
That's not a problem of git, but the person using it. In fact, I often saw people using Subversion making jumbo commits, since Subversion makes it so hard to split changes in a working tree up in multiple commits and makes branching painful.
You mention finding bugs. I'd rather look at a history that was rewritten in 5 tidy commits than 10 commits where 5 are 'fixed indenting', 'fixed typo', or intermediate data structure changes.
No, it's pretty widely regarded as a good, but not perfect, DVCS.
Complex, confusing terminology including multiple non-obvious names for various components.
DVCS is inherently complex. Git's terminology might possibly be improved, but it's not really all that bad. It just requires a bit of learning.
Huge number, about 148, of commands with many sub-commands that often do non-obvious, even unrelated things.
That's the same point. There are a lot of tasks to accomplish in a DVCS, which requires a lot of commands. You don't have to use these: they just have to be available for those that need them.
git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
Rebasing allows a user to rewrite history such that it makes sense, in terms of the changesets applicable to the repository as a whole. That's not a subversion - it's intentional.
Git has been … reconstructing what happened from the rebased "history" can be a nightmare.
This is a workflow problem, not a tool problem.
There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
This is the same thing as your first two points. These command all do similar, overlapping tasks, but are all useful in different circumstances.
A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches
Yes, and git's lightweight branches are great. I have never been in a situation where this causes problems; if you are encountering those, then you have a problem with workflow. Don't blame the tools.
Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files
I don't even know how you think that would work in the context of a DVCS.
* These many flaws in git and its command line interface have resulted in a proliferation of third-party add-on tools*
That "third party tools exist" is not a valid complaint.
Lack of backward compatibility with RCS-style version control systems like Subversion. Instead of building on 30+ years of success and experience with RCS-style version control systems, but extending them sensibly for distributed projects, Git took a "reinvent the wheel badly" approach.
Git can be used in almost the same fashion as SVN by learning that a couple of commands have different names.
A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Git.
Not that I've observed. Git is popular because it's quite good - equivalent or better to other DVCS systems. That's not a cult of personality.
tldr; git isn't that bad - it's quite complex, and it's a powerful tool that relies on users to be responsible. But that's not really a bad thing, as far as I'm concerned. It's certainly better than subversion for every project I've worked on.
A version control system should be very simple, hardly noticeable like the original RCS.
1. checkin the current version after each change. 2. if a serious problem is encountered, checkout an earlier version to see what happened and find when and where bug was introduced.
That is about it and RCS does it with a handful of commands.
The obvious question is why can't a distributed version control system like Git hide most of the complexity of managing a network of distributed repositories from the developer, at most adding a few network commands, e.g. clone, pull, push? Where do the 148 commands come from?
Why not just use the standard RCS command line interface with a small number of additions and let the back end deal with the distributed repositories? Extend the RCS/CVS/SVN sequential ids with a suffix to identify something like repository/branch to keep track of local changes?
Sincerely,
Bit by Git
In my experience, the time to learn Git for people unfamiliar with it is significantly larger than for any RCS-style version control system including Subversion which is probably the most complicated RCS-style version control system. Similarly, even if you are proficient with Git, on average it takes significantly longer to use Git to do the same things as an RCS style version control system. This is true even if you use Git in a very simple way. If you use it in one of the very complex ways like the Android project/Git/Gerrit/Jenkins morass, it will take a lot longer.
This time is a real cost to a business or an open-source project or what have you. Simplicity is often faster, cheaper, and better.
I argue that it is more effective in a team project to share the actual history of the development in a shared development branch -- warts and all. Production and release candidates -- the works of art that you are trying to create -- can be tagged or identified in some other way.
Bit by Git
As for me: I administered and supported SVN at a shop with about a hundred and twenty developers and about half a million commits and an overall trunk size in the gigabytes. I've spent time in the SVN codebase and am comfortable saying I understand it and can wield it better than most people who aren't committers. And guess what? I'm significantly faster at using Git for pretty much anything I've ever had occasion to do with it, while being able to leverage the conceptually-very-simple plumbing architecture of Git to do things that make other developers a lot faster.
(Git isn't perfect. Mercurial is better. But the answer isn't regression to a poorer model.)
Other problems include:
o Complex, confusing terminology including multiple non-obvious names for various components.
o Huge number, about 2000, of commands with many sub-commands that often do non-obvious, even unrelated things.
o There are numerous commands to do similar, overlapping but nonetheless different tasks.
o A supposed virtue of Linux is that it makes it extremely easy to create "mounts." This often leads to a proliferation of mounts, making locating files extremely difficult.
o Cryptic "paths" for identifying files instead of sequential numbers for individual files as well as snapshots of the entire project.
o These many flaws in Linux and its command line interface have resulted in a proliferation of third-party add-on tools like GNOME, KDE, many of which fail to fully wrap the complexity of Linux forcing users to both master the wrapper tool and the Linux command line especially on more complex projects. Some of these GUI/wrapper tools like GNOME seem to have serious bugs as well.
o Lack of backward compatibility with real mode-style version control systems like DOS. Instead of building on 20+ years of success and experience with DOS-style operating systems, but extending them sensibly for distributed projects, Linux took a "reinvent the wheel badly" approach.
o A fanatical, cult-like following apparently mesmerized by Linus Torvalds that is unable to recognize or acknowledge the many obvious problems with Linux.
Yours truly,
Inspire satire
For example, cryptic non-English commands like grep, ls, rm, etc. make the Unix command line difficult to learn, remember, and use.
One exception:
Despite their faults, the Linux/Unix file paths are far more human readable than a Git SHA (hexadecimal code). The issue with Git versus RCS-style version control systems is that a RCS-style sequential numbering scheme such as 1.2.3 (major release number, minor release number, patch) is much more human readable than a SHA (a3fee20). The analogy in the satire misses the mark.
Linux actually has suffered from a fanatical cult-like following mesmerized by Linus Torvalds that often was (still is sometimes) unable to recognize and acknowledge weaknesses of Linux versus Microsoft Windows. Linux has had to play catch up to provide a comparable GUI, installers for software packages, and other usability features in Windows and the Mac.
Sincerely,
Bit by Git
It has nothing to with windows' developer tools, which are significantly more obscure than the unix equivalents.
Have you written powershell scripts? How about .bat files?
Youre partially right; some unix tools are obscure, and have odd invokation syntax (find for example)... but I think you've completely lost the plot (or never actually developed for the platform) if you think windows has done a better job.
Windows has gotten more reliable in the last decade. It is rare that it out and out crashes anymore, but it still seems to start doing odd things that go away after rebooting. I would still pick Linux for reliability of the underlying OS any day.
On the other hand, Linux was (still is) difficult for a typical end-user on the desktop. It was easier to install and operate software due to the Windows GUI etc. Linux has played catch up with GUI desktops etc.
As far as development tools (I have developed both Windows and Unix software), Microsoft Visual Studio has some very nice features such as IntelliSense compared to the Unix/Linux vi/vim and emacs tools. Notably, emacs has the CEDET project which is working hard to add IntelliSense like capabilities to emacs.
Bit by Git
> Huge number, about 148, of commands with many sub-commands that often do non-obvious, even unrelated things.
You don't need to know all 148 of them. If you only know 16 (1/9 of them): add, branch, checkout, commit, config, fetch, log, pull, push, rebase, reflog, remote, reset, show, stash, status, You can do pretty complex things already. For day-to-day usage, these are more than enough.
> git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
Git rebase enables very simple workflows, like the GitHub workflow[1], which IMO is quite simple, small overhead workflow, pretty useful and scalable. Git rebase is also for local repo only. In every tutorial and even git command recommends against pushing rebased branches to an already pushed remote repository. If you keep this in mind, it makes sense.
> ... to rebase heavily to create a false history presenting themselves as fantasy 10X programmers who don't make mistakes, ...
I think the reason is not that they want to hide their mistakes, but to clean the history. Would you rather see typos in a history? IMO it's just cruft, an amend or rebase pretty much just a clean up you can read it more easily, and you don't have to deal meaningless 'Fixed a typo' comments...
> There are numerous commands to do similar, overlapping but nonetheless different tasks. If for example you want to back up to earlier versions of code you can do git revert, git reset --hard, git reset --soft, git checkout -- <SHA>, git checkout <SHA> -- all of which do different but overlapping things.
git revert is not the same as git reset. git revert creates a new commit on top of the commit you want to revert. git reset move the HEAD. Totally different operations. git reset --hard, --soft, etc does the same thing, just differ how they handle the index and working tree, and once you understand I think it makes sense.
> A supposed virtue of git is that it makes it extremely easy to create "branches." This often leads to a proliferation of branches, making locating changes and reconstructing the history of changes extremely difficult.
If you stick to a simple workflow and rebase constantly, this is not a problem at all. Not everybody needs git-flow[2]. If you work on the same files with somebody, I think this will always be a problem, no matter what VCS you use, but with git there are a couple of merging strategies which can facilitate the process.
> Cryptic hexadecimal SHA for identifying commits instead of sequential numbers for individual files as well as snapshots of the entire project.
The SHA1s are for security. A commit's SHA is actually the SHA1 of that snapshot, so if you change any bit of that snapshot manually, git will complain about it[3]. It is basically that nobody can change code unnoticed!
> Lack of backward compatibility with RCS-style version control systems like Subversion.
I don't really understand what you mean here, but there is the command git svn, which is perfectly compatible with SVN. Recently I converted a whole SVN repository to Git without even losing one commit or message or anything... Also Git supports many more workflows[4], not just centralized.
> ... many obvious problems with Git.
Of course git is not perfect, but instead of ranting about it, you could learn it in a couple of days and work with it, becase many of us think it's pretty flexible and as simple as you want it to be. Actually, if you learn only two commands: add and commit, you can use Git, nobody stops you doing that if you find the other parts difficult.
[1]: NumberSix ↗ @Walkman e40 ↗ 2. Ditch rebasing. chx ↗ > Would you rather see typos in a history? Walkman ↗ I never rebase commits which clearly shows how I got from point A to point B, even if I was wrong at the first time, but keeping typos in the log I think is silly.
I actually have been using Git extensively for 1 1/2 years. I have read the Pro Git book and many other sources cover to cover several times. I use magit with Emacs and gitk extensively. I gave up on the Android repo utility after it repeatedly goofed up the equivalents of git pull --rebase.
My complaints about Git are based on direct experience and watching others struggle with it.
Yes, I can and have set up Git in a very simple way not unlike an RCS project that avoids most of the issues that I discuss. No rebasing. Minimal use of branches, just a simple approximation of a development/production branch system. Nonetheless there are several problems with Git that still bit me such as the lack of sequential ids for files and the confusing terminology (staging areas, the index, etc.) and documentation.
For a better Git:
1. Clean up the documentation and man pages to remove the confusing terminology. Settle on one name for the "index" and so on.
2. Ditch rebasing.
3. Use sequential ids with a suffix of some sort for local changes. e.g. 1.2 on the master, 1.3.repo.branch or something like that for local changes. Keep the SHA, hide the SHA, but give users an easy intuitive way to access the SHA if needed.
1.1
1.2
1.3 \
1.4 1.4.myrepo.master
1.5 |
| /
1.6
1.7
I would guess there is some scheme like this in some other distributed version control system.
4. Simple checkin/checkout commands like RCS
Sincerely,
Bit by Git
You really are completely clueless. Rebasing is invaluable for use on private branches that no one will ever see but the developer. It allows you to clean up your history before others see it.
EDIT: oh, and you can make a hook (like I did from day 1) that disallows non-fast-forward pushes to certain public repos.
Absolutely. Like, normal git log wouldn't show them only the branch merges but if you dig deeper then you'd see them. Or even allow to mark a commit as "superficial" (wikipedia has superficial edits). It is very easy to hide commits but once rebase destroys them it is impossible to see them even if needed.
Consider how scientific research works: you write down everything you do, preserve them and publish a book/paper/etc at the end. If it turns out you were not right then it's possible to peek at the notebooks later but if you were, noone ever will care.
o git rebase enables users to rewrite history which subverts what should be the main, if not only, function of a version control system.
These two show me that your post is mostly hyperbole.
First, there could be 1000 commands and it wouldn't matter, because there are only a small number that people need to know.
Second, rebase isn't for rewriting history of public branches, and I think you knew that. It's complete BS pretending it is.
However, in practice, Git is being used in rather complex ways that are error prone and often lead to using other commands than the twenty-one "commonly used" Git commands such as git reflog, cherry-pick and others not in the "commonly used" list.
I have seen people combine a large number of changes into a single commit using Git's interactive rebase. The actual history remains in a local "private" branch on someone's computer. If it later turns out there was a bug introduced in this rebased mega-commit, it may be impossible to find the actual history and localize the actual change that caused the problem.
Even with access to the local repository, the actual changes may be found only in a feature or fix side branch with a cryptic name, one of hundreds generated using the lightweight branching in Git. There is no simple linear history of the changes with rebasing.
git reflog, in principle, gives a complete history but it is a confusing log of everything done and the information stored in it has an expiration time, which defaults to 90 days.
--expire=<time>
The obvious question from a usability perspective is: if twenty-one commands are all you really need, why confuse users with 148?Actually, I got an astonishing 165 git commands using
$ git help -a
with Git version 1.7.9 on Cygwin
versus nine (9) RCS commands.
Bit by Git
What's the point? RCS is not fit for distributed workflows/projects. Once you start to work in such a fashion, you want multiple remotes, tracking branches, rebasing (if only to make submitted patches as clean as possible), security/consistency per SHA hashes, etc. This simply implies more complexity and commands.
Sure, git could be simpler, some argue that Mercurial is easier. But RCS is definitely not the program you want to compare git with.
There are many examples of simple user interfaces layered on top of very complex programs and algorithms. Media players usually have a very simple GUI with a PLAY/STOP/PAUSE buttons and a volume control. Audio/video codecs, display drivers and so forth are extraordinarily complex but ideally the end user should not need to worry about this at all.
Many of the Git GUI tools like sourcetree are an attempt to address this usability problem with the Git command line interface.
Bit by Git
Submodules?
I actually think an entire repo of libraries is the wrong way to go. With the git model, we have however many repos acting as the source for these libraries. This repository that contains all of these submodules can then be the arbiter of which version should be included in the release.
> Yes, some will say - but this is good - centralization is bad... Well, it depends. If you can spend time to figure out who is who, then it will work for you.
And this problem doesn't exist with SVN? Sure, maybe if you are the sole publisher of all these libraries it might be ok, but with most real world examples, there exists multiple contributors. Now they need to go through you when there needs to be a specific update to that library. With git, the maintainer of the repo of libraries(submodules) just updates the specific submodule to whatever release works for their tastes.
Most of these complaints sound like an SVN user having some pain when trying to think in git.
Many times, 1 repo works perfectly fine for 100 plugins. As for wanting to only work with a subset of the files, the way git wants you to do that is to branch and change the subset you want to change (someone else has already pointed that out too here in the comments). What to split into how many repos is often a very subjective call, and depends on team, respository size, and workflow.
A real-world example where 1 repo works perfectly fine is the Linux kernel. Within one repo, you have all sorts of drivers for all sorts of hardware, and you have arch-specific support for a dizzying amount of processors and variants. The repo takes a while to clone the first time since it's kind of big, but thereafter works perfectly fine as you whizz between branches and jump between tags.
On some level, I understand the author's frustration with git, since it's quite a paradigm shift from centralized repos like Subversion. I made that shift myself once, and at first I didn't like being forced to play by git's rules of the universe (or more correctly, the DVCS rules of the universe). I have come to deeply appreciate those new rules over time.
There are, in fact, valid criticisms of git. One that comes to mind is the complexity and amount of operations... looks like others have already commented on this sort of criticism.
SCM is a matter of choice; there is no right or wrong answer and people need to get over being right.
That really sums it up. The right answer comes from seeing what you need and using whatever tool fits the job.
Yes, you can. It's called sparse checkout[1] and not that hard. Also, you can subtree merge[2][3] directories back and forth preserving all the history and merging back if you wish (cutting a directory out of the repository to a separate one and putting it back). It's pretty easy to do in git>2.0 because there is a builtin subtree command[4] for it.
[1]: https://www.kernel.org/pub/software/scm/git/docs/git-read-tr...
[2]: https://help.github.com/articles/about-git-subtree-merges
[3]: http://git-scm.com/book/en/Git-Tools-Subtree-Merging
[4]: https://news.ycombinator.com/item?id=3926683
The only problem can be with Facebook-sized repositories, but I believe in modularizing that big of a system instead of storing everything in one vast repository.
You're probably referring to Bitkeeper, which did exist (and was available commercially) before these new VCS's.
`git submodule foreach`
Git has tons of problems but neither of these are important problems.
But, having used both, I'd actually like to know... Why are these things (that the author is claiming git can't do) so important? For instance, is checking out a partial tree ever necessary? Is it that you'd want more granularity over what subsets of the repo you are storing locally? Is it that you don't want to have to set up a bunch of (sub-)repositories?
I ask because... I once worked on a codebase that was so absurdly huge most of us couldn't store it all on disk at once. And it sucked. Hard. I WISH it had been started as a bunch of distinct submodules, with extension points baked into the core build system so it would be easy to add/remove sections of the codebase. But the product predated git. And SVN for that matter. (Granted, the majority of the issues we suffered -- nightmarishly complex build systems, lack of transparency into what changes are being made, a bottleneck of devs lining up to commit changes -- were caused by process issues, not source control. But the source control did absolutely nothing to help either.)
I really understand the frustration when it comes to git. It took me a LONG time to wrap my head around why it works the way it does, because I wanted/expected it to work like SVN, where the repository is like a giant tree of files reflecting exactly what I see on disk, with different branches of code getting their own branch of the tree. Instead, git was this concise, magical pile of data structures that somehow kept causing me to break things whenever I strayed too far from a basic commit & push workflow.
But then I changed jobs a couple times. And, for some reason, I no longer found git a huge pain. In part because it just started becoming more natural and I knew what kinds of things to avoid, but also because I decided to sit down and really learn what I was doing. For one thing, I began making more active use of rebasing. Initially so I didn't need a ton of useless merge commits to keep up-to-date with the master branch, but eventually as a way of tidying up my work on a feature branch (i.s. squash, reorder, amend, etc) to make the set of changes concise and easy to follow. When working locally on a new feature branch, my commit log went from looking like this:
> okay one more try at part A [tests pass]
> fixing typo [tests pass]
> one last thing for part C [tests fail]
> part B bugfix [tests pass]
> fixing bug in part C [tests fail]
> finishing part B [tests fail]
> trying this again (feature A) [tests fail]
> part C, work in progress [tests fail]
> part A, I think [tests fail]
...
To this (more or less):
> part C [tests pass]
> part A (final implementation) [tests pass]
> part B [tests pass]
> part A (initial implementation) [tests pass]
...
Depending on who you are, you'll either love that, or you'll scream at my lying, revisionist git log before wrenching out your eyes and hurling yourself out a window. But, for me, for the team I was working with, and for the codebase I was working on, it worked WONDERFULLY. I found myself feeling like I really controlled the readability of my changes. Each of those commits could be submitted individually for code review with no problems, and even though I was wiping out a ton of minor changes, I could still preserve a record of alternate implementations in case we wanted to refer to them later.
Anyway, this post has become a long ramble. But, suffice it to say, I've found git to be very freeing. I just had to give up any expectations about how the process would work, and let myself start forming a new process around the power and flexibility that git offers. I believe I could say the same for mercurial (though I don't have much experience on it). And I don't think I can say as much for SVN, though I'm sure it d...