Posted on August 2, 2007 at 07:53 UTC,
filed under the category
Over the last few days I’ve been experimenting with distributed version control. I’ve finally settled on git. My large projects (Bugdar, namely) will remain in Subversion for the foreseeable future because I don’t want the hassle of converting. However, one of the drawbacks of SVN is the fact that it needs a dedicated svnserve or Apache2 DAV. Most web hosts offer neither of these, which will make it impossible for me to publish my smaller works. In a few months when my current Subversion server will be taken offline forever (because I will no longer maintain it at college) this will cause problems. This left me with two options: create Sourceforge.net projects for each small project (which I didn’t want to do as some may die very quickly, others are too small and not worth it, etc.), or find a new version control system that didn’t require special servers. Hence, I went shopping for a version control system that works over plain old HTTP.
First, I tried Bazaar. It was okay. Nothing spectacular, however. And it seemed rather immature. SVK sounded interesting but it still relied on the SVN repository layer so it was done before it got started. I then thought about creating a Ruby-based CGI WebDav implementation and then adding a layer on top of that with the SVN SWIG bindings. However, I ultimately decided against this because it sounds like a total pain in the a$$ to maintain the SVN part of the equation (though I still may write the WebDav Ruby CGI as it sounds like a fun challenge).
So I was back at square 0. Then I decided to look at git. I briefly glanced at git in my searchings before but I was turned off by the command set. But I finally went back and had a thorough look. And I’m now using it to manage a new project I’m working on (more on that in another post).
Using git is straightforward (for most things).
The only feature I wish I had was the ability to do the equivalent of “svn revert” on specific files instead of “git reset –hard” on the entire working copy. I also miss incremental revision numbers. But I’ll live. Because git is fast, and doesn’t get in your way at all. It makes perfect sense.
And git has some amazing features. The first of which is a compile-instantly and an install-without-being-root installation. Then there’s the whole notion of the “index” (or a staging area for commits). I like this a lot as it forces me to be more careful with what I commit. Also, the two built-in GUI commands (gitk and git-gui), while unattractive, are very useful and it’s great they come out-of-the-box without any work. But my favorite thing is definitely the ability to go back and edit the last commit! It’s fantastic to be able to fix a mistake without having to make a whole separate revision.
So I’ve been using git locally for a few days now, and I decided it would be a good idea to try push-ing it to bluestatic.org to make sure that public repositories will actually work! After many, many failed attempts all I could get was this cryptic message:
bash: git-receive-pack: command not found
fatal: The remote end hung up unexpectedly
error: failed to push to [removed]
And then, by chance, and after a good 20 minutes of searching, I found this perfect answer on Google:
Many installations of sshd do not invoke your shell as the login shell when you directly run programs; what this means is that if your login shell is bash, only .bashrc is read and not .bash_profile. As a workaround, make sure .bashrc sets up $PATH so that you can run git-receive-pack program.
So I solved this error by simply creating a .bashrc file with this in it:
I thought I’d just write about this in hopes of helping others out.
Can you go into a little more detail on how you setup the public repository? I’m also trying to move from svn to git and the central repository is giving me a little trouble. With svn, while setting up Apache was a bit of work, there were no issues using it because its just HTTP traffic. Wigh git, I guess I need to setup the ssh tunnel first (not sure if that has firewall implications).
Also, do you just copy the .git folder to your public repository or do you copy it along with the current directory tree?
To revert a specific file y can do:
git checkout HEAD — path/to/file
Or to go a few revisions back do:
git checkout HEAD~3 — path/to/file
man git-checkout and man git-rev-parse is your friend.
@David: Sure. I followed the instructions here: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#public-repositories
What I did to set it up was this (where ~/proj is your “working copy” so to speak):
git clone –bare ~/proj proj.git
git –bare update-server-info
chmod a+x hooks/post-update
[upload proj.git to wherever I wanted it on my web server]
Then back in ~/proj I added it to my remote repository shortcuts:
git remote add public ssh://email@example.com/path/to/htdocs/proj.git
Then whenever you want to update the public repository, just type:
git push public [branch name]
@robewald: Thanks! I didn’t expect that to be in git-checkout.
You might also be interested in this method of securely hosting git repos – the guy who wrote the blog post has since written some software to manage all that shell stuff, but i don’t think he’s published it yet..
Just what I was looking for, thanks!
I had the exact same problem when using “git push” – the info in your post resolved the issue, thanks!
Woo. Exactly the answer I needed.
Many thanks man, you saved me a lot of work.
Thank you, so many sites kept telling me “Your path is incorrect”, which doesnt help when it works for my normal user.
thanks, that was a big help.
Didn’t work for me! Anyway, there’s an explicit option in git-push for this:
–receive-pack /path/to/your/personal/git-receive-pack – OR –
Hope this helps!
Addendum: it turned out that my .bashrc file had this at the very beginning:
# If not running interactively, don’t do anything
[ -z “$PS1” ] && return
so it was hardly setting the PATH! Moving the command to the start of the file solved the issue without the need for the additional parameter. Thanks!
Thanks! Really helpful little tip that saved me a bunch of time.
You save my life. I had the same exact problem on dreamhost. Thanks!
For those of you who like me, are using Zsh, the correct file to update your path in is .zshenv. .zshrc doesn’t get sourced for non-interactive shells.
Thanks for the tip! That was exactly what I was needing.
Worth mentioning that if you don’t want to (or can’t) change paths on the upstream machine, you can do this:
git config remote.origin.uploadpack /some/path/bin/git-upload-pack
git config remote.origin.receivepack /some/path/bin/git-receive-pack
Thanks, this worked perfectly on Bluehost!
Thank you — had the same problem, googled “git-receive-pack: command not found,” and your note solved my problem without my brain having to work.
This was useful, thanks!
I had setup a new slice running Ubuntu 8.10 and had created a git user to deal with hosting my git repos.
While I had run:
$> sudo apt-get install git
I did not run:
$> sudo apt-get install git-core
git-core is needed for git-receive-pack. Once I installed that on my Ubuntu slice everything seemed to start working.
Hi! I was surfing and found your blog post… nice! I love your blog. 🙂 Cheers! Sandra. R.
Thanks for this information.
My 2 cents:
A general and more scalable solution would be to add sym links to git to a common area on the ssh daemon’s path. If multiple users are to work with git on this machine you will ever only have to configure this solution once; rather than once per user.
Another option that you can use is
git push –receive-pack=/path/to/git-receive-pack server.com:/path/to/repo.git
Where –receive-pack actually points to the location of the git command on the remote system. This is useful if you don’t have access to change the PATH command on the remote system.
Many thanks for the info about the ‘command not found’ tip. Just the answer I needed.