Replacing jQuery’s fade functions with silky-smooth CSS transitions both in and out of hover states, a Git strategy for extracting individual commits from a branch’s tree, and how to search a Git repo for a commit by name (which Github unfortunately doesn’t support).
Smooth CSS Transitions to Replace
.hover() events used to add classes with a simple
:hover pseudo-class in the CSS. I also replaced all of the calls to jQuery’s
.fadeOut() with CSS transitions. But here I ran into trouble. I wanted the drop-down menu to fade into and out of hover using
opacity, but in order to keep content below the menu clickable it’s necessary to use
visibility: hidden, which can’t be transitioned (it’s applied immediately). As a result, the menu may fade in nicely, as it’s made visible before the
opacity transitions to
1.0, but instead of fading out it simple disappears, as its
visibility is set back to
hidden before its
opacity can transition back to
If this sounds confusing, Greg Wyvern does a great job of explaining (and illustrating) the problem, and has a fantastically clever solution which uses the selective application of
transition-delay to time everything perfectly. And the transitions aren’t just eye-candy, he points out that they add some important usability to drop-downs, making them more forgiving if the user’s cursor unintentionally exits the menu.
Extracting Commits From The Middle Of a Branch
I found myself in a familiar situation this week. In gearing up for the launch of a new feature, and thus with extra eyes on the website, some unrelated tweaks and requests came in. Expecting the new feature to me merged and launched in the very near future, I absent-mindedly included those commits in my feature branch while continuing development on the new feature. Then I was asked to hold off on deploying the feature, but could I deploy those unrelated tweaks and requests? Of course I could. But I would have to extract them from my feature branch.
This is how I learned about some handy behavior of
git rebase: it will remove any commits on the branch you’re rebasing if they occur earlier in the history. To illustrate, I started out with commits A-D all on my feature branch, but needed to extract and deploy commit C:
D (feature) | C | B | A (master)
First I checked out master and ran
git cherry-pick C, which copied commit C to my master branch and updated the HEAD.
D (feature) | C | B C' (master) | / A
Then, by checking out my feature branch and running
git rebase master, Git rebased the feature branch on to master, removing the duplicate commit C:
D (feature) | B | C' (master) | A
This example is simple, but with multiple commits to extract, it’s handy to just
cherry-pick what you need now and
rebase what you don’t, knowing that
rebase will clean up any duplicate commits.
Searching for Commits By Name
Lastly, I needed to find out when and why a colleague had added and removed the Hirefire gem from a project. Github’s search interface searches only the current version of a project, so it couldn’t help me search for something that was no longer part of the codebase. My next thought was to use Github’s “History” view to see all commits to the Gemfile, but there were a lot of them, and the Hirefire change may have been years ago, so I went looking for a better way.
I didn’t have to look far to learn that Git’s
log command takes a
--grep= argument which will limit the log to only commits which contain a search term.
git log --grep=hirefire instantly showed me the commits which added and removed Hirefire (over 2 years old). Of course, this only works if your team uses descriptive commit messages (
git commit -m "Updates", anyone?), so here’s another great reason to do so.