By Nathan L. Walls

  • Silhouettes II/Washington, DC
  • Silhouettes I/Washington, DC
  • On the Red Line/Washington, DC
  • Silver S

Tool Sharpening: July 21, 2014

For some background on what’s going on here, see the first tool sharpening post

It’s been far longer than I’d hoped with my previous entry. Sometime reasonably soon, I’ll have some thoughts on stress and creative energy. In short, I’ve found that a lot of the creative energy I would otherwise have put into my tool sharpening was going into other, more stressful arenas. Ergo, when I was home and otherwise “available” to make some of these tool sharpening changes, I found that my will and energy to do so was exhausted. Consequently, I’ve spent a lot of time reading fiction. Doing that, I could focus on material far away from my normal day-to-day routine as a stress-reducer. I’m disappointed that I wasn’t writing or making tooling improvements. I am happy about doing what I needed to in order to take care of myself.

The situation that resulted in said stress is improving. After a very relaxing weekend, I’m back to tool sharpening. Onto the batch of recent changes:

  • Added a TextExpander shortcut to correct my constant misspelling of visibility
  • Added additional mailing list filters
  • Adjusted my git commit message template to use BBEdit placeholders to move from segment to segment
  • Set-up a typing.io account to begin language specific typing practice
    • This was a pick from Ruby Rogues Episode 147
    • I suspect I’m a slow coding typist and I want to get better
    • My first Ruby on Rails lesson resulted in a 35 wpm typing speed with an unproductive keystroke overhead of 10 percent
  • Opened a RubyTapas account and watched episodes 219 and 221
  • Found a few options for converting PDFs to EPUB format
    • I’m taking a hint from Michael R. Bernstein and attempting to read more papers
    • A lot of the papers I see linked around are in PDF format
    • I’d prefer to use an EPUB, where I have better control over the text sizing. I can also highlight and comment
  • Updated git.bbpackage, Source.bbpackage and ryans_rails.bbpackage to latest versions

Tool Sharpening: June 8, 2014

For some background on what’s going on here, see the first tool sharpening post

This past week found me still getting over the last vestiges of a cold, then traveling for a conference. Consequently, not a whole lot this week. But, on to it:

In Mail.app, I created a Smart Mailbox for any email that contains the word “unsubscribe”. I caught this somewhere in my online travels in the last week, but I’m not able to put a finger on who I picked it up from. When I find out, I’ll update with credit. The goal here is to review for mailing lists in general from one spot and decide if they’re still valuable.

I created a training session template in BBEdit for note-taking during RubyNation 2014. I focus on talks and lectures by writing notes down in outline format. It was a habit I built up during college lectures, and one that I retain when I’m processing new material. This template gave me the ability to quickly create a Markdown with YAML front matter document, tab through some placeholders to fill-in some document tags, the name of the talk and the presenter. From there, I just need to name the document and I’m ready to take notes. During the two day conference, I created 21 documents, iterating on the template during the first quarter of those sessions.

I’ll have more to say on the conference itself later this week. As a preview: Good to great talks and a whole lot of processing to do with some thought provoking material.

Tool Sharpening: June 1, 2014

For some background on what’s going on here, see the first tool sharpening post

This week was slower than previous weeks. I’ve been sick the second half of the week and just being moderately productive Thursday and Friday was a challenge. Excuses aside, here’s what’s new, this week:


OmniFocus 2 was officially released. The new release has presented an opportunity to make some adjustments.

  • Created some new custom perspectives
    • “Fast Actions” for items that I can complete in 15 minutes or less
    • “Oldest” shows items by order of creation. This will be useful for looking at items that have been lingering for weeks, months or longer and make a call about whether I’m ever going to carry those actions out and, if not, delete them
  • Set custom icons for all of my custom perspectives from Josh Hughes' set


Not a developer thing, but bear with me.

  • Updated token so favorited articles will post to my Pinboard account. I’d like to do some link blog mining using this workflow as a starting point
  • Renewed my Instapaper subscription to gain access to full-text search

Tool Sharpening: May 25, 2014

For some background on what’s going on here, see the first tool sharpening post

This past week’s refinements started with more BBEdit adjustments. I’ve been spending a lot of time in the text editor. Thinking through it, it’s overdue. There are several actions in my daily workflow that feel inefficient to me, ones that I know an editor like Emacs or vi(m) has readily available. And, as it turns out, as I have been looking for solutions, I have been finding them.

In my previous entry, I mentioned the BBEdit 10.x release notes containing a lot of information about existing features of which I was taking insufficient advantage of. I alluded to some keyboard binding changes I made in favor of built-in shortcuts. Those are pretty great. What’s also great is that several Mac OS X applications support using a number of Emacs key bindings because there’s a whole range of default shortcuts for text manipulation that work in Mac OS X applications that make use of the Cocoa Text System. What’s very nice about that is effort I put into learning more of the these shortcuts in BBEdit are likely to pay off in other OS X applications I use.

One of these Emacs shortcuts I learned about from BBEdit’s version 10.x release notes is about C-u (Control-u if you’re not versed in how Emacs documentation refers to this). C-u takes a number and then a character to repeat that number of times.

A sample case is this: I will use a series of #’s in a source code file as a header or section separater. I’ve tried approaches from create a clipping for that to typing four or five of them then cut-and-repetitive-pasting. This, instead, gives me something more flexible.

By example:

C-u 20 #

will yield:


There are several other immediately helpful shortcuts, too, such as C-t, which will transpose two selected characters, as such: ab becomes ba. In BBEdit, if the selection range is larger than two characters, the first and last characters in the selection are transposed, so abcd becomes dbca.

Functionality for transposing words also works, but transposing lines does not. If I end up needing that, I’ll just need to use slightly longer shortcuts around line manipulation. If I need it more consistently, I can write a text filter.

Finding these shortcuts have helped to alleviate the low-grade sensation that I was working too hard to edit text. The rest of this week’s changes are below. Enjoy.

Other BBEdit changes

  • Added a shortcut for prefix/suffix line
  • Added a shortcut for reapplying the last text filter used
  • Updated a text filter I’ve been using for a long while that queries a JIRA instance and provides me with the case title and a link in a Markdown list

TextExpander changes

  • I keep a food journal in a text document, so there are a few items I type repetitively. To that end, I want less typing and correct spelling.
    • Replace “Worchester” with “Worcestershire”
    • Expand “CAJ” to “Cup-a-Joe”, a local coffeehouse
    • Expand ;cs to “chicken salad”
    • Expand ;tm to “trail mix”
  • Added a shortcut for “stand-up”
  • Reviewed how to chain shortcuts in TextExpander
  • Created a shortcut that allows me to pre-fill “.webassign.net” for SSH and moves the cursor to right before the first dot in order to

Other misc changes

  • Created a TextExpander perspective in OmniFocus in order to quickly focus on pending adjustments
  • Created new search profiles for Ruby, JavaSCript, HTML + CSS, datastores and “DevOps” tools in Dash

Locally testing destructive Git actions

My team is responsible for maintaining a production line in our various Git repositories. After releases, we’re responsible for merging the development line to the production line, so any bug fix release starts from the basis of what’s currently running in production.

Making a longer story shorter, we had a release that we cancelled and decided to roll into a future release. But this was after we’d already made the merge to the production branch. We further had a mix of fast-forward commits with no merge commit and non-fast-forward merges across the different repositories that comprise a product release. We want to get our production line back to where production is actually at.

I researched a few strategies, centered around git revert and git reset for how to step forward and wanted to test them out.

Since each Git clone is complete unto itself (and we use a single remote versus multiple points of authority), I have the entire public history. So, it’s very easy to make a copy of a repo, make a bare clone as a “remote” and test changes locally.

Before we start

First, some words about safety. Out of an abundance of caution, I recommend the following before we start the experiment:

  • Make sure your remote origin is up-to-date
  • Make sure you are up-to-date with the remote origin
  • Make sure the remote origin is backed-up
  • Disable networking on your machine until the experiment is concluded

I also need your understanding that I’m describing procedures for experimentation, not trying to solve for your problem. We’re going to use git reset below and it is a destructive action. You own your data and are much better equipped to understand your repository and situation. Act with prudence.

If you’re looking for info on addressing various changes to repositories, you’d do worse than having a look at Kai Howelmeyer’s “Git Undo by Example” post.

Local and destructive testing

Our safety pre-check complete, here’s how to test destructive Git repository changes locally:

  1. Determine where you’re going to be working on this test. I recommend something like git-experiment underneath /tmp.

    $ mkdir -p /tmp/git-experiement/
  2. Copy the repository in question to git-experiment, or clone if it’s a small repository. For this example, let’s pretend this repository is named smith. I’m going to refer to this as the local clone.

    $ cp -R /path/to/repo/smith /tmp/git-experiment/smith
  3. Create a bare clone of smith in a new remotes directory. This will allow us to push the local clone to what we’ll call the remote.

    $ cd /tmp/git-experiment
    $ mkdir remotes
    $ git clone --bare smith remotes/smith.git
  4. Go into your experimental copy of smith and open the .git/config file and update the url for the remote origin to point to your bare clone of smith.

    $ cd smith/.git
    $ vim config


    [remote "origin"]
        url = git@example.com:smith.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [branch "production"]
        remote = origin
        merge = refs/heads/production


    [remote "origin"]
        url = file:///tmp/git-experiment/remotes/smith.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [branch "production"]
        remote = origin
        merge = refs/heads/production
  5. Go into the remote clone of smith. Instead of .git/config, open config here. Remove the remote origin block. Also remove branch info that ties back to origin. This isn’t strictly necessary, but we’re just going to keep things clean and not run the risk of pushing changes where they shouldn’t go.

    $ cd ../remotes/smith.git
    $ vim config


    [remote "origin"]
        url = git@example.com:smith.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [branch "production"]
        remote = origin
        merge = refs/heads/production


    [branch "master"]
        merge = refs/heads/master
    [branch "production"]
        merge = refs/heads/production
  6. With this done, clone the bare remote repository as a second working copy, if you’d like to check the workflow once you publish your destructive change.

    $ cd /tmp/git-experiment
    $ git clone remotes/smith.git smith-two
  7. Since there’s a good chance you’ll want to try a few different approaches of your destructive change, make a copy of your test set-up and set it as read only:

    $ cd /tmp
    $ cp -R git-experiment git-experiment.orig
    $ chmod -R ugo-w git-experiment.orig
  8. Go into your experimental clone and make your destructive change and see what happens with it. You can safely push to your remote and see how that process works with doing a push and then git fetching or git pulling changes into the second copy.

    In my case, I was experimenting with reverting branch merges and resetting and doing git push --force to publish changes. Below, I’m using HEAD@{3} but this could just as easily be a hash reference or a tag.

    $ cd /tmp/git-experiment/smith
    $ git checkout production
    $ git reset --hard HEAD@{3}
    $ git push --force

    The --force is important here, because otherwise, Git believes you to be doing something it doesn’t think you should. And 99 percent of the time, Git would be correct, but we’re explicitly seeking to do something destructive.

  9. Go check the results of your experiment in the second local clone:

    $ cd /tmp/git-experiment/smith-two
    $ git checkout production
    $ git pull --rebase
  10. When you’re done, package everything up with a note or just rm -rf /tmp/git-experiment. If you’re saving the iteration, give it a meaningful name:

    $ cd /tmp
    $ tar -czf git-experiment.git-reset.tgz git-experiment

Results and Iteration

The first experiment is complete. You can shake out what to do and discuss it with your team, safely not affecting what other users are seeing on a repository. Determine what your next steps are, then move your original test aside, copy in the back-up and run further iterations.

In particular, you may have other questions to consider, such as determining what happens if you force a merge commit, provide tags, delete branches, and so on. What’s it going to be like publishing the changes? What’s it going to be like trying to fetch or pull the changes? Are there any other workflow considerations? How are you going to inform other users?

Hopefully, these experiments help you sort that out and provide a well-known path for your users. This contained experiment gives you a margin of safety to answer those questions.

Happy experimenting.

← Previous