Edward Loveall

Building a Waiting git Editor

When I commit to a git repository, I don’t like using a command line editor, but using a GUI editor sometimes takes a while to boot up. I’ve settled on using TextWrangler for now since it opens a window reasonably fast, especially if the app is already open.

I always thought it would be cool to build a dedicated git editor that you can launch from the command line, see a nice diff of my changes, and edit using native Mac text editing. If I ever want to do that, I need to figure out how git creates a commit with an external editor.

My git config for the editor looks like this:

$ git config --get core.editor

edit --wait --new-window

Git will open TextWrangler using a couple of options:

--new-window makes sense to me, but how does --wait work? Well, a bunch of things happen when you type git commit:

(I’m sure it does much more than just that, but this is all I need to know for now.)

Great, so now all I have to do is make an editor that writes text and closes its process when its done. A ruby script will exit automatically when its done running, so if I can create a script to write some text to a file, it should work.

Here’s what I came up with:

#!/usr/bin/env ruby

commit_message_path = ARGV.last
puts File.read(commit_message_path)

print 'Commit Message: '
message = $stdin.gets

File.write(commit_message_path, message)

The first line uses a hashbang to tell the rest of the script to be interpreted as a ruby program.

Then, I grab the last argument passed into the program and print all its contents out to the screen. That way I can see all the changes that have happened since the last commit. This printing is optional.

Next, I give the user a prompt to input their commit message. Once they hit return, I write the commit message to the original file. The ruby process closes, git does its thing, and I have a new commit message!

This is obviously very primitive. It’s still a command line UI, not a GUI. It can’t do multiline strings. In fact, it’s less useful than using the -m option with git commit. But now I know (and so do you) how to build a waiting editor.