Using Git with OS X

February 19, 2009

Every developer needs to be using a source control system.  When I used to work for a big software company working on Windows based development systems we used Perforce.  Starting to work on my own with OS X Tiger, I initially used Perforce there too.  Perforce is a client/server system, but I was running both on the same computer. Installation is far from straightforward.  There’s no Mac installer – you are directed to a server install for Darwin – the open source Unix underlying OS X.  And you need to know your way around a Unix system to install it.  When I moved to a new Mac with Leopard and tried to install Perforce on that, I didn’t suceed at all. I’m sure it can be made to work, but it was beyond my Unix skills and one really shouldn’t have to work so hard just to install software.  It doesn’t bode well for the future.

Meanwhile there’s been a lot of buzz around a new SCM system from Linus Torvalds called Git.  So I thought I’d give that a try instead.

If you have Leopard the installation is really easy.  Get the OSX Git Installer from Google Code, and it’ll do all the work for you with a standard OS X GUI installer.

To start working with it it pretty simple too.  Rather than keeping one source code repository for everything you do as Perforce does, Git keeps a seperate repository for each project.  Open a terminal window and change to your project directory.  The one with your project file in.  Then type

git init

That will create a new and empty repository in a subdirectory called “.git”. The leading dot means that the directory will be invisible ordinarily.

Next thing is to tell Git about files that you don’t want to store in the repository.  For example you don’t want to save all your build files.  You can store this information separately for every project you create, but that would be repetitive, so I suggest you set this globally.  Create a file in you user directory called .gitignore.  I suggest this as the contents:

.DS_Store
*.swp
*~.nib
build
*.pbxuser
*.perspective
*.perspectivev3

Next you’ll have to make git know about that file. Type

git config core.excludesfile ~/.gitignore

Now, in your project directory, type

git add .
git status

Git add tells git what files you want to track. In this case all in the current directory and subdirectories (ignoring those mentioned in .gitignore). git status confirms that you’ve done.
Then actually store all your files in the repository for the first time with

git commit -m "Initial commit of project"

OK that was a very quick summary of installation and getting started up to the first commit. Git does take some earnign though before you can use it properly. I recommend reading: Pragmatic Version Control using Git – The pdf version is available for $22.
Also, if like me you need to really know what’s going on under the hood in order to be confident wielding it, this free pdf is great for that: Git From The Bottom Up


Interface Builder Drag & Drop

January 26, 2009

I’ve been trying to implement a drag and drop feature like the one in Interface Builder where the image is one thing over the source window and a different image when over the target window. Having tried various ways to achieve this it looked to me like it’s not possible. I wondered whether IB was actually using real drag & drop at all.

So I tried dragging from the IB library to my own destination window, with a breakpoint on the draggingEntered: method. Sure enough it wasn’t called.

Then it struck me. When you initially drag a window out of the IB Library, you then drag it to nothingness. The desktop doesn’t know what it is. So real drag & drop wouldn’t work for IB. It’s an internal implementation of drag&drop.


Improved NSView to NSImage for Drag and Drop

January 26, 2009

Drag and Drop in Interface Builder

Here’s an improvement on the last post’s method for grabbing a view and converting it into a drag image. This copies the bitmap directly instead of redrawing ir with a PDF, so is faster, and pixel perfect.

// Take a snapshot of the view bitmap.
[self lockFocus];
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc]
    initWithFocusedViewRect: [self bounds]];
[self unlockFocus];
NSImage* viewSnapshot = [[NSImage alloc]
                        initWithSize:[self bounds].size];
[viewSnapshot addRepresentation:bitmap];

// Copy the snapshot to make a seeThru drag image.
NSImage* dragImage = [[NSImage alloc] initWithSize:viewSnapshot.size];
[dragImage lockFocus];
[viewSnapshot dissolveToPoint:NSMakePoint(1,0) fraction:1];
[dragImage unlockFocus];

How to grab an NSImage from an NSView

January 23, 2009

Here’s one way to create an image of a view. There may be a better way, but this certainly works. If you do know of a better way, then please comment.
Self is an NSView.

NSRect boxrect = self.bounds;
NSData* pdf = [self dataWithPDFInsideRect:boxrect];
NSImage* viewSnapshot = [[NSImage alloc] initWithData:pdf];

You can then go on to make a translucent version of the image. This is useful for drag & drop.

NSImage* dragImage = [[NSImage alloc] initWithSize:viewSnapshot.size];
[dragImage lockFocus];
[viewSnapshot dissolveToPoint:NSZeroPoint fraction:0.85];
[dragImage unlockFocus];

Note that I’m using garbage collection here.  Alter as necessary if you need to manage memory.

On Apple’s site there’s a demo of how to do screenshots of windows or the whole screen.  It’s called SonOfGrab and it’s Leopard only.  I’ve not yet tried it myself.


Design a site like this with WordPress.com
Get started