February 6, 2010
If you find yourself on a network with other developers you'd like to share a git repo with, here's a simple way to do that. First, on your machine, the one with the git repo, you run this:
$ git daemon --base-path=/path/to/dir/with/repo --export-all
So if you have a git repo in your home directory called, foo, you would make the base path be your home directory. Then, assuming your IP is 192.168.1.42, others can clone the repo using:
$ git clone git://192.168.1.42/foo
July 7, 2009
Are you using Ruby on Rails? Are you using Git? Do you have a need to track how long you spend on things? Then I have just the thing for you.
I threw together a quick rake task that gets all of your commits in a git repo and parses out the times and commit message from them. Then it formats them with the time and also the time interval between them. You can get the rake task to track your time from this gist.
The output will look something like this:
Fri, Jul 07 10:55AM 20m 49s Added toolbar for controllers using temp...
Fri, Jul 07 10:34AM 21h 52m Added support for using page templates i...
Thu, Jul 07 12:42PM 37m 57s LH#77, fixed issue with tests failing on...
Thu, Jul 07 12:04PM 12m 18s LH#67, added a limit option to the rende...
Thu, Jul 07 11:52AM 17m 30s Removed debug statement ...
Thu, Jul 07 11:34AM 19h 52m LH#66, added :path option to render menu...
Wed, Jul 07 03:41PM Added DSL for modifying portlet behavior...
Tue, Jun 06 02:05PM 18h 44m LH#119, multiple HTML fields on one bloc...
Mon, Jun 06 07:20PM 6h 21m Converted docs to textile ...
Mon, Jun 06 12:58PM Fix for LH#118, create directories in ge...
Sat, Jun 06 10:22PM Added support for other template handler...
Fri, Jun 06 04:49PM 0m 58s bump build ...
Fri, Jun 06 04:48PM 23m 11s Fix LH#106: Section not correctly loadin...
Fri, Jun 06 04:25PM 34m 25s Fix for LH#107, images were not showing ...
Fri, Jun 06 03:51PM 9m 48s Fix for LH#110, can't view usages of a p...
Fri, Jun 06 03:41PM 11m 12s Fix for LH#113, check to see if there is...
Fri, Jun 06 03:30PM 2m 52s Fixed LH#114, documentation typo ...
Fri, Jun 06 03:27PM 0m 38s bump build number ...
Fri, Jun 06 03:26PM 5h 38m Fix for LH#98, tags not getting updated ...
Fri, Jun 06 09:48AM 33m 14s Fixed LH#105, deleted portlets showing u...
It doesn't actually truncate the commit messages, I just did that here to make each one fit on a line. If the time interval is over 24 hours, it doesn't bother printing the interval, because you probably didn't actually work on that one commit for 37 hours straight. I've been thinking if you really want to track time this way then each time you sit down to start hacking on a project, you just make a minor change to the .gitignore or something and then commit it with a message like "started hacking on foo", so then when you commit your first chunk of actual work, you will know how long you spend on that.
January 20, 2009
Inspired by Michael Ivey's recent "My Git Workflow" article, I've decided to write up one of my own. Really this article should be titled "My Git SVN Workflow", because that's how I use it most of the time. At BrowserMedia, we use Subversion (SVN) for version control. I'm not an advanced user of Git by any stretch of the imagination, but here's my experience from switching from SVN to Git.
First off, for small projects that I am doing on my own, I use just straight git, and back it up to my own server as I described in the Quick and Dirty Git Repository article. For stuff that I want to be publicly visible, I push it to github. But for BrowserMedia internal projects, here's what I do.
Assuming it's a rails project, I create the rails app and import it using SVN:
$ rails myproject -d mysql
$ cd rails
$ svn import -m "Initial Rails 2.2.2 App" https://svn.browsermedia.com/myproject/trunk
$ cd ..
$ rm -rf myproject
$ svn co https://svn.browsermedia.com/myproject/trunk myproject
$ svn remove log/*
$ svn commit -m "removing all log files from subversion"
$ svn propset svn:ignore "*.log" log/
$ svn update log/
$ svn commit -m "Ignoring all files in /log/ ending in .log"
$ svn remove tmp/*
$ svn propset svn:ignore "*" tmp/
$ svn update tmp/
$ svn commit -m "Ignoring all files in /tmp/"
$ cd ..
$ rm -rf myproject
Most of this you will recognize from the Rails Wiki article on How To Use Rails With Subversion. So now the project is setup so that anyone can use SVN to work on the project.
One of the cool things about Git is that you can use Git SVN to work with git locally and push your changes to the main SVN repository. I've been using this for months now with no problems. So now let's start working on our project with git:
$ mkdir myproject
$ cd myproject
$ git svn init -s https://svn.browsermedia.com/myproject
Couple of things to note here is that first you have to make the directory for your project first, then change into the directory and run the git command from there. Also, the URL you use is the directory that contains
trunk (and possibly
tags, if you have created those). The
-s means you are using a standard SVN layout. Once you have done this, you run this command to sync up your local repository with SVN:
$ git svn fetch
In this case, this is a fresh project, so if should go pretty quick, but if you are doing this with an existing larger project, this could take quite some time, because this is not just fetching the latest version of the code, but the entire history of the repository.
To make working with git a little easier, I have some aliases defined to make things go a bit quicker:
alias gs='git status'
alias ga='git add .'
alias pull='git pull'
alias push='git push'
alias gc='git commit -m'
alias gca='git commit -a -m'
alias svnpull='git svn rebase'
alias svnpush='git svn dcommit'
And then most of the projects I work on are small teams, so I follow Michael's small team workflow pretty closely:
Hack some stuff
look at what's changed
$ git add .
$ gca "hacked some stuff"
So the first thing I usually do after
git svn fetch is to add a
.gitignore file to the project that looks something like this:
One nice thing I've observed about using Git over SVN is the way it handles directories of files. Git puts one
.git directory at the top level of your project, which is where it keeps the info about the repository, including the local repository itself. SVN puts a
.svn directory in every directory of your project. This only has the info about the repository, which files you have checked out, etc. There is no local repository of course, the repository is on the server.
A case where this makes things easier is managing external dependencies. Let's say you have a gem that you can't or don't want to install on your server. For most gems I recommend installing them on the server, but in some cases that doesn't always work. So in that case, you do
rake gems:unpack to put the gem into the vendor directory. Now let's say you need to update that gem. Again, this is not the normal case, but if you are creating your own gems for your project, you might want to do this. Here's what you can do with git:
$ cd important_gem
$ rake install #installs version 1.0.0 of important_gem locally
$ cd ../myproject
$ rm -rf vendor/gems/important_gem-1.0.0
$ rake gems:unpack
The case here is that
myproject already has a version of
important_gem-1.0.0 checked in, but you've modified
important_gem-1.0.0, so you want to get those updates into
myproject. You only do this in a situation where you haven't released version 1.0.0 of important_gem yet.
Now if you run
gs (short for
git status), you will see that git has just figured out what happened. Whether files were removed, renamed, added or modifed, git knows. You can just run
git add . and then
gca "updated important_gem" and all is well. No need for SVN externals. With SVN, if you wanted to manage your project like that, you are kind of out of luck. The reason is that when you did
rm -rf vendor/gems/important_gems-1.0.0, all of the
.svn directories got destroyed. After
rake gems:unpack, the files are back, but not the
.svn directories, hence SVN is confused and frankly, I never did figure out what you are supposed to do about this.
There are other cases where this is useful besides working on a gem. For example, with BrowserCMS were are using FCKEditor, which comes in a zip file that you just unpack into
public/fckeditor. To put in a new version of FCKEditor, you can just do:
$ cd public
$ rm -rf fckeditor
$ mkdir fckeditor
$ cd fckeditor
$ unzip ~/Downloads/fckeditor-x-y-z.zip
$ cd ../..
$ git add .
$ gca "Upgraded to FCKeditor version x.y.z"
There are probably some errors or inefficiencies in this process and if so, let me know in the comments, but I really like working with Git SVN, which allows me to have my cake and eat it too.
December 29, 2008
Do you have an app you want to keep in version control, put you don't want to put it on Github? Well, you can obviously use git to keep track of your versions, but do you want some way to back it up? Do you have a server you plan to deploy the app to already setup with SSH keys and everything? Assuming you already have git installed on both your machine and the remote machine, here's all you need to do:
Create The Remote Git Repo
$ ssh email@example.com
$ mkdir yourproject.git
$ cd yourproject.git
$ git --bare init
Create The Local Git Repo, If You Haven't Already
$ git init
$ git add .
$ git commit -a "Initial Checkin"
Add The Remote Repo
$ git remote add origin firstname.lastname@example.org:yourproject.git
Push To the Remote Repo
$ git push origin master
Now you have a full copy of the repo locally and on the server.
February 6, 2008
Anyone who keeps up with Rails in blogiverse knows by know that Git is the new hotness. Once you've got a peepcode, well, that's it, you've got the ultimate endorsement from the Rails community. I know nothing about Git and I have resisted the change up to now, but I ran across Dr. Nic's new Rails 2.0 Textmate Bundle and figured it was time to git with the times (pun intended).
So like any good hacker, I google Git, found the download page, downloaded the latest source tarball (1.5.4 as of now), decided against reading any documentation or instructions and just ran
make install. Even thing worked as planed and after following Dr. Nic's instructions, I've got the latest Rails 2.0 Textmate bundle.