Git is a Pain in the Ass
Everyone's been talking about how great and wonderful git is, and I've tried using it for a few projects of my own, on a local basis, sort of like an advanced form of 'rcs'. So I thought I'd try it out in a little bit more complicated setup, for a site I host on my web server. I want to have a main repository, that I "check out" (or 'clone', in git terms) on my laptop. My laptop can't be the main repository, because I also want to be able to commit from the web server (once in a while a quick live update is called for), so I need a stable address. Ok, I'll put it in my home directory on the web server, just to see how things work.
mkdir foobar
cd foobar
git init
Ok, so far so good. Now I try and clone it on my laptop, where I will then add files, commit, then push them.
Oops, that doesn't work. You can't clone an empty repository.
Ok, I add something on the server where I init'ed it, an empty file, just to give it some content. Now cloning it works on the laptop. Great, we're in business! I add a bunch of files from the project to the laptop repository, commit, then push them. Seems to be ok so far... I do a checkout on the remote/server machine, and I see my files. Good. Ok, let's try making a change on the laptop. I remove a file, commit it, push it (which is already an extra step compared to subversion... hrmph). I do a checkout on the server, but it won't erase the file I removed on the laptop. Weird. I google around a bit, and find that this is supposed to be for my own good, so I won't wreck things on the server. I need to do git reset --hard (which isn't a very reassuringly named command) there, and then a checkout, and now things work.
That, however, is a lot of work just to commit and update stuff! I ask for some help on #git, where they mention the --bare option to init. Since I'm just messing around, I go back and redo the init step, wiping the old repository. Now I try and clone that to start over again. Oops, I forgot, I can't clone it because it's empty. Grrrrrr.... this is getting annoying.
So, the kind folks on #git tell me I should push to the new server repository from one that's already populated. Ok, let's try setting up the laptop:
git init
... add/commit some files ...
git remote add origin ...myurl...
Now let's try pushing. Nope, still doesn't do it, I'm missing something. Frustrating. A bit more fiddling and googling, and i find:
get push origin master
Aha! It worked! Weird. And now a simple git push works too. The whole thing seems kind of shaky in the sense that it's not very confidence inspiring: I feel like it wouldn't take much to make a wrong turn and find all my files gone forever. I can see some of the advantages, and will likely stick with it - git is quite convenient for local files that I might not have bothered putting under version control in the past, but it's also a bit more "bureaucratic" in that you have more steps to do, and you have to fill in the forms just so... or else!
Trackbacks
Use the following link to trackback from your own site:
http://journal.dedasys.com/trackbacks?article_id=2127
about 1 hour later:
Do not push to a non-bare repository if you do not know exactly what you're doing. Use a bare repository instead.
about 1 hour later:
Ah, sorry, you discovered that.
about 1 hour later:
I agree with you that Git has a few remaining rough edges in the area of initial repository creation. However, git makes it very hard to actually lose your data.
I do think clone from an empty repository should work.
As for the need for the initial "git push origin master", that occurs because "git push" will only push things that already exist on the remote side. After all, you wouldn't want "git push" to push the "private-hacks" branch without you telling it to.
Finally, several of the problems you ran into came from attempting to push and pull to the checked-out branch of a non-bare repository. Don't do that. Doing so would require "git push" to handle the remote repository's checked-out working copy and index, which might itself have changes, even conflicting changes. Git ought to just prevent you from doing that.
about 2 hours later:
You were doing things in the wrong way, that's why you had to make so many steps...
about 2 hours later:
@ghostbar: Not a very helpful response, there. It seems a fair complaint that Git occasionally doesn't make the right way obvious, particularly in the initial setup of a repository.
about 2 hours later:
Exactly, git has a lot of options, and finding the right set of them is not always obvious. The tutorial helps, and was enough to get me happily going while working on strictly local, only-me repositories, but didn't really help once I wanted to basically recreate a svn style setup. Git is way better than svn in terms of "oh, hey, let's put this code in version control" - git init and you're done. Creating svn repositories is not easy, but it's a fairly straightforward, well understood procedure too. Git could do with a short documentation section on "so, you want to have a repository, here's how". I don't doubt it's out there, to tell the truth, the problem is that there is so much chatter on the net about how to use git that it's a lot to sort through.
about 4 hours later:
Moving from the centralised svn world to the decentralised git world is a big change in tools and work flows. I've done it myself about two years ago and I wouldn't change back to the svn.
Basic version control stuff isn't that different in git and subversion. Both do commits with a single command (git commit -a behaves like svn commit), both clone repositories with a single command (svn checkout vs git clone) etc.
The catch is not to use git as "another subversion". If you do pushing after every single commit, even a simple thing like committing ends up to be frustrating. Same goes with not trusting the push command to do it's job and check the remote/something branch locally (which, actually, isn't a 'live branch' from the server, just a cached copy of what your local repository last "saw" on the server when fetching).
Instead of using git like you used svn, spend a moment or two to learn work flows with decentralised version control. Google propably offers a lots of guides to see how other people do their things. Or ask someone you know using a git, or make your own :). In the end, you probably end up in a point, where knowing the ease of branching and merging, ability to make work-in-process branches easily and all other neat tricks the git (or any other DVCS) has would not make you switch back to svn.
Arguing over little nuisances like not being able to clone empty repository (why would you?) should be set aside, since both systems have their downsides. You just swap a bunch of svn's downsides to a (way smaller) bunch of git's downsides.
And by the way, a colleague of mine made a git hosting tool, Gitosis. Available in Debian too.
about 5 hours later:
Jyrki: I knew that I would have to make some adjustments, that much is clear, and something I was expecting.
What was irritating was the difficulty I encountered in setting things for what is a fairly common workflow: dev -> server -> checkout to live site. The empty repository thing ended up wasn't a minor nuisance, but something that was blocking my way forward. I guess it might seem minor to an experienced user, but to someone just trying to get things working, it seems pretty annoying that it's getting in my way for no discernible reason.
BTW, git commit -a is not like svn commit - svn commit takes a directory or file as an argument, which is convenient. git has other convenient things itself, though, like the automatic use of PAGER for output longer than a screen length, so those kinds of things probably balance out.
about 5 hours later:
it's quite easy to restore every committed change using git - see git reflog.
admittedly git's hard for svn users, because it works differently; do not try to use it as you'd use svn, it'll be an uphill struggle. try to forget svn while learning git.
about 6 hours later:
Looks like you are using git just for the sake of it and then finding that it's too much work. What people should do is look at the features and check if they need them. Git has great features you mention push as an added step when compared to SVN but imagine you are on vacation without internet access or for some reason are working in a series of commits, you can do commit->commit->push, try that with svn. Also branches are awesome. I use git because it fits my needs and it's features easily outweigh the (rather small) extra work.
about 7 hours later:
fwiw bzr can work nearly identically to subversion (commits go directly to a remote repository, updates pull directly from a remote repository), so it might be a bit easier to learn that first.
Needless to say I'm biased by the fact I learned bzr first (after looking at git for 30 minutes and giving up).
That being said you probably ought to learn git as it appears to direction the world minus Python (mercurial) & Ubuntu (bzr) are headed.
ymmv :)
about 7 hours later:
It's not clear what your reasons are for learning git; if you need to learn a tool to do some task, then of course you have little alternative but to do that.
But if you're looking for a flexible DVCS that has a sane user interface, I second the recommendations above for Bazaar http://bazaar-vcs.org/. It is well-documented and friendly.
about 18 hours later:
I would like to third the above recommendations for bzr. For me, it has the same advantages over centralised version control as git, with none of the esoteric behaviour.
1 day later:
Or give mercurial a try. It's nearly as fast as git (whereas bzr can be much slower), and the UI is very natural for subversion users.
2 days later:
I second the recommendation of giving mercurial (hg) a try. It has a very compact and well thought out core command set and a very nice set of extensions that let you handle less common or history changing operations (bugzilla, rebase, patch queues and branches, mail notification). It also has awesome documentation in the mercurial book (similar to svn's redbook).
3 days later:
You might want to spend an hour or two watching the video of Bart Trojanowski's introduction to Git. It's a great introduction that really helps you wrap your head around Git's data model and workflows.
I have to disagree with the recommendation to use bzr. bzr encourages a workflow that discourages making commits. This, combined with a bug in "bzr rebase", caused me to lose hours of work. As a result, I switched to Git, and have been quite happy about it ever since. I posted my rationale on the PyCrypto mailing list.