The reason I think git is complicated isn't because it's complicated conceptually. It's because the commands are intentionally different from other SCMs, which is highly annoying when you know what you want to do but can't figure it out.
For example, how do you revert a file in your working directory?
You seem to think that other version control systems don't have this problem.
Let's consider subversion. Let's say you want to revert commit 1234. You just say "svn revert 1234", right? No. svn revert does something completely unrelated.
In git, "git revert 1234" does revert changeset 1234.
So you see, you actually have to learn about the version control system, regardless of which you choose.
You can't just make stuff up and expect the computer to understand what you mean.
Agreed! But I already know SVN, and Linus intentionally made git different than the other SCMs because he thinks they suck.
I think that's annoying.
And there's no way you can tell me that the git command set is more discoverable than, say, Mercruial's. Many common, every day commands in git are very difficult to figure out without a lot of searching and reading. This is not true with Mercurial.
Between `git help -a` to see all the available commands, and `git help <command>` or `man git-<command>`, I don't see how Git is any worse than any other VCS tool. Git is extremely well-documented, and even goes so far as to provide ASCII-diagrams in the docs to help you visualize what certain commands do.
Or are you just being picky because Git doesn't name everything exactly the same as other tools do?
I started with cvs, years ago, moved on to subversion when it was good and stable, and am now starting to fiddle with git. I like it a lot, but it is "fiddly" feeling. I'm sorry I can't describe it better than that, but it's just a feeling I get from it. Maybe this covers it: I don't get the feeling that it's going to much effort to "make the easy things simple and the hard things possible". We know it can do the latter, but the former is not always true.
"make the easy things simple and the hard things possible"
Well, it's Git, not Perl :)
I like it a lot, but it is "fiddly" feeling.
To assuage this feeling, I recommend reading the source code for both Git and Subversion. After you realize the flaky shoestring-and-chewing-gum model that holds all your data in subversion, you won't worry at all about Git's UI :)
i agree with this. i'm very happy with svn. my one foray into git was when i was working on somebody else's project on github, and i got a vague uneasy feeling about it. for one thing, the output it prints to the terminal seems needlessly complex and verbose.
What are your specific complaints, and are they anything more than the age-old "`git commit` doesn't commit everything by default"? I'm not trying to snark; I'm genuinely interested in what people find difficult about Git, that much more it's possible to "fix".
If there's something complex that you think should be easy, you always have two basic options:
- create an alias in your ~/.gitconfig linking a short command name to a long command/argument sequence
- create a shell script in /usr/libexec/git-core (or the equivalent) that does what you want, and you can instantly use that in the standard `git <command>` method.
For an example, I have aliased 'co' to 'checkout', 'ci' to 'commit -a', 'pullr' to 'pull --rebase', and 'fp' to 'format-patch --binary'.
All SCM tools will frustrate anyone migrating from one to another. I've done migrations among most of the major commercial SCM tools and had to write training documentation for developers.
You do have to realize that if the underlying model for version control is different, then commands and terms will be different even if they share the same name like "checkout." And what you think you can or want to do might not be what you really should do.
So expect some initial frustrations and a lot of referencing of the man pages, documentation, blogs. You're going to have to unlearn a lot of behaviors that may be second nature to you. But at the end, you'll get a much better appreciation of what each tool gets right and an understanding of their limitations.
These always (fail to)address the same old issues. I switched to SVN for some specific features. I've looked and not been able to get definite answers if git supports these. In fact I've mostly gotten "if you don't do it/use it our way you're stupid, go away".
proper directory move/rename history
proper binary handling(that is no merging, newest file wins)
proper line ending handling (that is default to convert to local system's standard but overrideable per file/file pattern)
proper permission handling (track permissions and set them on check out/update/whatever you call it)
git seems focused solely on source code and heavily towards the Linux Kernel development process.
I use svn for website deployments, tracking changes to servers' filesystems(parts thereof), and occasional source code. I don't use anything close to the Linux Kernel dev process.
I think in this case the word "proper" means "the way that seems intuitive to me". This is not bad, but other people have made different technical decisions. Adding the word "proper" tries to make these into quality judgments into opinions, but that's still what they are.
I hope you find a system that works as you prefer.
Yes I agree. I meant and hoped that the (explanation in parens) would be interpreted as my opinion on what was proper. Believed the construct "proper ... (that is ...)" was clear, guess not. Oh, and thanks for not answering any of my questions and ranting off topic.
[an aside; I don't believe in "proper", there is no proper there is only "proper for me", never "proper for you." One should reject others' attempts to inflict "what is proper" on them. Good job btw. My use was to alter people's thinking or simply make them think, even subconsciously. Language is a virus.]
For someone who doesn't have much experience with SCMs, is it worth learning Git or should I learn SVN? I get the general idea behind both - just not sure what I should dive into.
Contrary to what seems like the prevailing view right now, Git is not strictly better than SVN. Some reasons to use SVN are at http://blog.red-bean.com/sussman/?p=90.
It sounds like you want to use SCM in a personal (not collaborative) capacity. I think both SVN and Git are suitable for this purpose, but maybe Git has the edge because its philosophy doesn't privilege a repository.
A very useful link there. Quite pragmatic. It tells us that Subversion's experts believe its future lies in:
- "Huge projects where putting all the current source code on everyone's machine is infeasible."
- systems with very complicated permission schemes where "you just plain aren't allowed to give everyone all the data"
- "organizations whose users need to interact with repositories in complex ways... These things are probably most useful to the corporate world, and to governmental and military organizations." [Karl Fogel]
So, if you recognize yourself in any of those groups, learn SVN. But otherwise I'd start with git. You can pick up the necessary rudiments of SVN (or, god help me, CVS) later when you need them.
I believe Git is strictly better than SVN even for one-person-never-share style of development simply because of much, much, much better branching/merging.
Being able to maintain and merge multiple branches without any effort is a huge, in my opinion. I don't think you can get away without using at lest some branching features in any project: at the minimum you'd need to maintain tags for released versions and keep "latest stable" from "development/experimental" code separated. And this is where Git shines.
I'm not saying SVN can't do branches or tags, I'm saying it takes more effort, and tools in general are supposed to make hard things easy.
By strictly, I think most developers mean one SCM tool's functionality is a strict superset of another's. That is not the case with git and svn! Git is probably qualitatively better for most competent developers, but for strictly, every feature counts -- git's support for handling binary files, in terms of size and content, is not as complete as svn's; and tree tracking is just completely different.
This means some developers will want things that svn can do but git can't. I don't think it's fair to deny that these gaps exist when some projects depend on it.
I'd say git is better for that situation because it's so simple to set up. That's one thing it really does well. Tons of branches and other stuff are likely to be less of an issue on small, personal, non-shared projects.
I don't see why you shouldn't leverage branching in any small, personal, non-shared project. I got in the habit of making a branch any time I want to try anything out, after all most of my small projects are experimental in nature, and branching is perfect for experimenting with changes and ideas that you might otherwise be afraid to try using a single, linear history.
I don't get the argument that git is better for branched projects. I worked this way in subversion for years -- svn copy and svn merge work just fine. You can branch! You can merge! Huzzah!
Granted, git is a bit faster for branching (it can take svn a few seconds to set up a branch, especially if you're doing it remotely), but that slight time savings is more than offset by the time you spend reading man pages, only to learn that the various git commands really don't mean what you think that they mean (and don't get me started on the quirks and inconsistencies and bugs in git...)
I am not a fanboy -- just a guy who doesn't want to think about his version control, any more than he wants to think about his toothbrush.
It's not just that Git is faster at branching. The concept of a branch in Git is conceptually different to a branch in Subversion. In Subversion, a branch is analogous to a directory, and creating a branch is essentially a cheap and efficient directory copy. In Git, a branch is more akin to a reference or pointer to a particular piece of historical data.
The Git idea of a branch is somewhat more flexible than the Subversion idea of a branch. For instance, say I'm hacking away at a new feature, but I haven't thought ahead and created a new branch for my commits. A user then comes along and asks me to fix a bug. In Git, this is no problem, because branches are just references. I first assign a branch to my current work:
git branch new_feature
Then I rewind my master branch back to before I started working on the new feature, 4 commits ago.
git reset --hard HEAD~4
I then commit and push the bug fix:
git commit -am "Bug fix"
git push
Now the user is happy and I can continue working on my feature. But now I'd like the bug-fix to be included in the history of my branch, since I've pushed the bug-fix but not my new feature. So I change the 'base' of my branch using rebase:
git checkout new_feature
git rebase master
Now I can continue working on my branch as if nothing had happened.
Using Git is a bit like having a time machine you can use to alter history so you didn't forget your wallet this morning.
Golly. That took six commands, history unwinding, a rebase, and a few obscure flags. I'm beginning to see your point...how in the world would the lowly subversion user surmount such a catastrophically complicated conundrum without the raw power of git to save him?
Hmm....
svn copy ./my_code ./my_new_feature; cd ./my_new_feature
...hack hack hack...
(user interrupts! a bug! oh noes! must fix!)
cd ../my_code
...fix fix fix...
svn commit -m "fixed a bug! i rock!"
cd ../my_new_feature; svn merge -c HEAD ../my_code
...hack hack hack...
Oh well. Guess it wasn't that hard, after all. Nevermind.
I think you're missing the point. In your workflow, you create the branch before you started work on your new feature. In my Git example, I created the branch retroactively.
If you were to attempt the same feat in SVN, it would get a little messy. You'd have to first roll back the repo:
cd ../new_feature
svn merge -c HEAD ../my_code
svn commit -m "Merged bug fix"
And once you've done all that, your commit history looks like:
A
B
C
D
Reverted last 4 commits
Imported reverted commits to new_feature
Fixed bug
Merged bug fix
Whilst in Git:
Fixed bug <- master
A
B
C
D <- new_feature
Now, obviously you'd never actually do all this in SVN if you were sensible, but that's exactly my point. The Git concept of a branch being a reference to a commit is more flexible than the SVN idea of a branch being akin to a directory. Things that are perfectly natural to do in Git are rather more complex to do in SVN, and leave behind a messy history of merges.
I'm not missing the point -- I'm saying that your point is silly. You're fixated on doing everything in the same directory, when in fact it's far easier not to do it that way, and the only argument you're making for doing it that way, is that it's more "flexible". But flexibility is not a virtue, unless you need the flexibility!
"obviously you'd never actually do all this in SVN if you were sensible"
Exactly. You'd never do it. You don't need to do it. You can get the job done without doing it. And that's what matters.
Git fanboys are hilarious sometimes...every argument is made from the position that none of the rest of us really understand git, and that if only we did, we'd fall in love with git in all of it's fiddly glory. What they miss is that many of us hate complexity, and we avoid complexity that doesn't justify itself with true functional advantages.
I like simple tools that get the job done. Git makes my life harder; I have to think about more things to do the same, basic tasks that were made trivially easy in subversion. That's the point.
I'm not claiming that Git is better than Subversion, or that you should use it. I'm merely pointing out that branches in Git have other advantages as well as being faster.
The fundamental problem with Subversion branches, at least in my view, is that you have to know ahead of time that you want a branch. Perhaps this isn't a problem for you, but it is for me. Sometimes I find myself thinking, "Hang on, is this really the right way to solve this problem?" In Git, I can save my current work in a branch, trot back a few revisions, and try a different approach.
In contrast, Subversion encourages a largely linear style of development. I expect some people, like yourself, prefer this approach, finding it conceptually simpler. And that's fine; I'm not saying that's wrong or bad, or that you should stop using Subversion. That's clearly what you're most comfortable with.
But a linear development model isn't for everyone. Those of us who like to experiment and backtrack tend to develop in a tree-like fashion, branching off shoots all over the place and pruning the ones that turn out to be a dead end. For this style of development, Git's branching model is significantly better than Subversion's.
I think the git repository model is pretty much a clear win over the svn repository model.
Subversion would be better off writing a front-end on top of git. The subset of a repository issue is indeed something that git still doesn't handle very elegantly, but I think ultimately if the right front-end was built, the underlying git repo model would prove better even for this case than the subversion model.
It seems like the issues described there can be dealt with in Git by dividing things up into submodules, if submodules work well. (I haven't used them much.) They also only seem to apply to really big projects — dozens of contributors, and dozens of gigabytes to terabytes.
If you have a choice about what SCM to use, I would just learn Git or (my favorite) Mercurial because as others have pointed out, they are just better than Subversion, even for single user access.
Both git and hg are easier to set up, faster, and feature better merging.
If you have to work with people who are using Subversion already, you should understand how to use it effectively, too.
learn both. get comfortable with both. i don't see SVN being abandoned, and a lot of companies/projects use it. i like GIT over SVN, but am glad i'm comfortable with both.
I have never used CVS/SVN (beyond very, very basic checkin/checkout) so git was my first SCM, and looking back at the last one-and-a-half year, it has only done me good.
I switched from bzr to hg when I decided I wanted my prompt to include a count of unchecked-in files. `svn st` and `hg st` are effectively instant; `bzr st` was taking about half a second to a second. That kind of delay on my prompt was highly annoying, and it was enough for me to switch to hg.
The only thing I worry about with git is getting really raw developers who have never, ever used version control up and running in a semblance of a reasonable manner of operation.
I mean, I know people who were resistant to using subversion because they didn't understand how it was supposed to work. I sort of shudder to think about the mental reaction to being dropped into git. Because of this I originally supported Darcs. I still would if they could clean up some of the patch resolution problems that they have and the Darcs GitHub-like got halfway decent (maybe with Camp).
Source Control is one of the fundamental tenets of development and getting newbs trained on it is so incredibly important. We, collectively, can't afford for it to be a tough thing to get a handle on. Even if it takes time to really understand, it needs to be easy to get going and using the tool in a good semblance of the proper manner.
Just to reference another HN discussion "My web is text based" (here http://news.ycombinator.com/item?id=488030 ) - this is the sort of topic where I think video and screencasts would be helpful.
Not a screencast of someone typing DVCS commands into a shell, mind you, or a video of someone talking about DVCS that could be transcribed to text with no loss of explanatory power whatsoever, or, $deity forbid, a video of someone reading inaudibly from illegible slides.
A decent animated introduction to distributed version control explained by characters worthy of Pixar, set in a world of fantasy physics where things can pop into and out of existance.
DVCSs do things which are non linear, text and talk are extremely linear. Text and audio shouldn't be the only two forms of media on the web, video explanation shouldn't mean linear explanation.
For example, how do you revert a file in your working directory?
Oh, git checkout HEAD file -- obviously!