One Liner: Cleaning Up Old Git Branches

I am very lazy about deleting local git branches. I just checked and I have 100+ branches! WTF. That makes it a real pain to find the one I was working on yesterday. So first, let me get rid of the ones that I’ve already merged into master.

git branch --merged | egrep -v '(master|develop)' | xargs git branch 

But I still have 58 branches left! Lets try sorting by committer date:

$ git for-each-ref --sort=committerdate refs/heads/ --format='%(refname:short) "%(committerdate:relative)"'

This command gives me a list of branches sorted by commit date. The output looks something like:

BL-1302567-dnp-global-dns "10 months ago"
BL-1311324-scheduled-scale-down "8 months ago"
hackweek-dnp-deploy "4 months ago"
BL-1305305-dnp-secretsmanager "3 months ago"
BL-1311060-dnp-deploy-v2.6.1 "3 months ago"
dnp-breakfix "3 months ago"
BL-1307167-sas-api-elb "2 months ago"
BL-1307165-patch "9 weeks ago"
BL-1307166-sas-dns "8 weeks ago"
BL-1307441-product-project "8 weeks ago"
sas-deploy-fix "8 weeks ago"

Now I can use this to find branches where the top commit is older than a few months

git for-each-ref --sort=committerdate refs/heads/ --format='%(refname:short) "%(committerdate:relative)"' | egrep -v "(master|develop)" | egrep "([4-9]|[1][0-2]) months ago" | xargs -n2 bash -c 'git branch -D $0'

Here I used egrep to remove the master and develop branches as a precaution, then again to select only branches that are 4 “months ago” or older. Then just pass the output to xargs and you’re all set.

One-liners: Stopping all your docker containers

Let’s say you have multiple docker projects on your laptop and in the course of a day you bounce around between them. It’s easy to forget which ones have been shut down and which haven’t. If you’re using docker-compose this could mean several containers are running and eating your battery. Here’s a simple one-liner to shut them all down.

docker ps -q | xargs docker stop

How to Bind to Eloquent Model Event in Laravel 5

Whenever a Laravel model is modified there are a number of events that fire that allow you to trigger your own action(s). For example, in my PoliticsEQ application I needed to calculate some statistics about keywords and sentiment scores and store them in a separate table to improve performance for some of the front in graphs. The challenge was making sure the keyword statistics table was updated whenever a keyword was added or updated.

Laravel gives you the following events right out of the box: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored. You can get the particulars here. Most of them are pretty intuitive.

In my case it made sense to use the “saved” event. To make this happen was remarkably. All I had to do was create a new “Service Provider” and use the Event::saved pattern in the provider’s boot method.

So first I created a KeywordStats provider.

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Keyword, App\KeywordStat;
use Log;

class KeywordStats extends ServiceProvider
     * Bootstrap the application services.
     * @return void
    public function boot()
        Keyword::saved(function($keyword) {
          $stat = KeywordStat::where('keyword_name', $keyword->name)->first();
          if (!$stat) {
            $stat = new KeywordStat(['keyword_name'=>$keyword->name]);
          $stat->sentiment_avg = Keyword::where('name', $keyword->name)->avg('sentiment_score');
          $stat->total_usages = Keyword::where('name',$keyword->name)->get()->count();
          Log::info("Updated {$keyword->name} / avg: {$stat->sentiment_avg} / count: {$stat->total_usages}");

     * Register the application services.
     * @return void
    public function register()

Then I simply registered the provider in the config/app.php providers array:


Covert all tables from MyISAM to InnoDB

Here’s a quick one liner to convert all tables on in a specified database from MyISAM to InnoDB:

mysql -Bse "SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' engine=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' and table_schema = 'your_database_name';" | xargs -I {} mysql -e {}

Boom! You’re welcome.

Customize an Ubuntu Launcher Icon

Just a little tip for those Ubuntu users who may be looking to customize the launcher presentation of a particular application. If you right click on the application icon while it’s open and choose “Lock to Launcher” a configuration file is created in the /home/user/.local/share/applications directory, but sometimes the default icon is borked because the application is non-standard or is in a non-standard location or has been moved. But you can easily customize the settings by editing the .desktop file. For instance:

#! /home/mike/.local/share/applications/code.desktop
[Desktop Entry]

Hide WordPress Post from All Queries

Problem: you want to create a variation of a page but you don’t want it to show up on the home page or in any archives or anything. You just need a direct link so you can share it with someone.


add_action('pre_get_posts', 'hide_hidden_posts');
function hide_hidden_posts($query) {
  if ( is_admin() ) {
    return $query;

  if ( is_single() AND $query->is_main_query() ) {
    return $query;
  $ids = wp_cache_get('hidden_posts', 'posts');
  if ( !$ids ) {
    global $wpdb;
    $ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = 'hide_post'");
    wp_cache_set('hidden_posts', $ids, 'posts');
  $query->set('post__not_in', $ids);
  return $query;

This function will modify all WordPress’ frontend queries to exclude any posts with a custom field “hide_post”, except in the case that the query is the main query on a single post page.

Caveat: This will only be functional for plugins and themes using the WP_Query api. Custom queries will not be modified.

Block hacker attacks on WordPress’ xmlrpc.php

It you’re getting a ton of POST requests to your WordPress xmlrpc.php file, here’s a quick way to block all the bad ips via iptables. In my case I’m using nginx and php-fpm, but something very similar would also work for apache.

First, recognize the signature. Your access logs will look something like this: - - [13/May/2015:12:14:59 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:14:59 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:14:59 -0400] "POST /xmlrpc.php HTTP/1.0" 404 168 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:14:59 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:15:01 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:15:01 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:15:01 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:15:01 -0400] "POST /xmlrpc.php HTTP/1.0" 404 168 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:15:02 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;" - - [13/May/2015:12:15:02 -0400] "POST /xmlrpc.php HTTP/1.0" 404 168 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;"

Googlebot will NOT be POSTing your xmlrpc.php like that. Next the trick is to figure out which IP addresses are harassing you. Run this in your terminal:

$> grep xmlrpc /var/log/nginx/access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head

Most likely all of these are hackers since it would be unlikely even Jetpack or some other WordPress service would hit your xmlrpc.php that frequently. But you can decide where the cut off should be by adding -n# the the head request above. In my case I chose head -n8 like so:

$> grep xmlrpc /var/log/nginx/access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head -n8

Sooo …. now you just need to wrap that in a loop that will create the iptable rules to block traffic from the ips:

$> for ip in $(grep xmlrpc /var/log/nginx/access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head -n8 | awk '{print $2}'); do iptables -A INPUT -s $ip -j DROP; done

No more hackers.

High-Performance WordPress Basics

Getting started with high-performance WordPress requires understanding the concepts of speed, scale, and elasticity.

What do we mean by WordPress performance anyway?

You cannot separate the definition of “performance” from the overall purpose of the site itself.

If you’re a small business who just needs to post your store’s hours and contact info, a 1-second improvement in load-time may not be all that important to you — especially once you consider the additional cost. Everyone wants a faster more efficient site, but time is not an infinite resource and–unless you are Bill Gates or Warren Buffet–neither is money.

But if you are a search marketer, obsessing over page rank, bounce rates and conversions then 1 second can change your world and will probably be worth every penny you put into it.

As you read this book always keep recommendations in context of your overall purpose.

Dimensions of WordPress Performance

There are three primary consideration when talking about WordPress Performance:  speed, scale and elasticity. This ebook examines all three but will be mostly concerned with speed and scale. Elasticity comes mostly from the server/infrastructure and as such will only be dealt with in the hosting discussion.

Speed is an easily understood concept. How fast does my page load damnit! That’s all you need to know. It’s not quite this simple of course, but for the introductory chapter it’ll suffice.

Scale is a slightly more complicated concept. What do we mean when we ask can my application scale?

Computing power is a limited resource and the performance of your website or application will be impacted by the available and consumption of that resource.

An analogy.

Imagine a bagel shop owner in a small town. They get healthy foot traffic but not enough to afford an employee so they do everything themselves. They take the orders, make the bagels, ring the register. This can totally work so long as the number of people coming in and placing orders isn’t any more than can be served relatively quickly. But as more people come in, orders pile up, wait times increase, and the customer experience is wrecked.

What worked at the scale of one customer every five minutes broke down once there were two.

Of course our intrepid Bagel-ista will inevitably have to hire someone to help her out. But if she waits too long she’ll risk losing business because of the poor customer experience. She might just go ahead and hire early expecting the increasing demand. But what if business grows slower than expected? She’s spending more than she can afford on help she doesn’t need yet.

WordPress Scaling is a Balancing Act

The same goes for websites and application. You could spend thousands of dollars a month on sophisticated Amazon AWS machinations but not have a single customer to support the investment. Likewise you could go super-cheap with BlueHost or DreamHost and end up with a crashed server on the biggest day of your business.

It’s a balancing act. And there is no right equation or server or plugin that can make the decision for you. But you can plan ahead, accepting that those growing pains will happen and putting yourself in a position to scale as rapidly as possible when that time comes.

Strategies For WordPress Performance and Scale

Given the analogy above you can see to competing strategies developing, an aggressive or over-investment strategy and a conservative or under-investment strategies. Both have advantages and disadvantages and either can be used successfully.

Aggressive v. Conservative

The key consideration of the aggressive strategy is a complete intolerance downtime. In the movie “Social Network”, Mark Zuckerburg is memorably quoted saying:

Okay, let me tell you the difference between Facebook and everyone else, we don’t crash EVER! If those servers are down for even a day, our entire reputation is irreversibly destroyed! Users are fickle, Friendster has proved that.

This is a supremely aggressive strategy, but it was probably warranted given that the ONLY market advantage Facebook had was popularity.

I think too often though those with sites/applications very different from Facebook feel they need the same strategy.

Downtime is definitely a problem, especially when it happens at an inopportune time.The advantage to an aggressive strategy is that if done right, a promo video going viral will be no big deal. But you could easily spend thousands per month on a servers you don’t need in the meantime.

A Conservative approach can be just as effective. In most web hosting scenarios, you can upgrade your site to better hardware and be back online in no time. A few minutes, or even a couple hours downtime, while inconvenient can be tolerated if expected and planned for.

We will discuss this more in later chapters but this concept of expanding quickly to accommodate a change in traffic is known as “elasticity”.

In the next chapter we will ask the question “How do I pick a WordPress Host?”