tubes

My internet:  github / flickr / facebook / tumblr

words

Merging .po files suck

PO files (which stands for “Portable Object” but I call them translation catalogs) are not fun to keep under revsion control.

If two people are working on i18n, there will for sure be merge conflicts.

Maybe it is because gettext is 20 years old (came out in 1995) and pre-dates the predomance of version control (was no one using CVS back then?).

Life became easier when I discovered two things:

  • Git lets you create custom merge drivers for different types of files
  • Installing gettext includes msgcat which has built-in conflict detetion

I created a git merge driver called git-po-merge.

I’m not a fan of shell libs (maybe one day I’ll rewrite) but for now, this has prevented many headaches.

July 16th 2015

Custom git commands - delete local and remote branch

Custom git commands are simple. Create any bin called git-<command> and place it in a directory anywhere on your $PATH.

I want to delete a branch locally and on the remote, I’ll call it git purge. It could be done with an alias but a script will be more robust.

In my bash profile I have:

export PATH="$HOME/.bin:$PATH"

In ~/.bin/git-purge, I have:


#!/bin/bash
set -eu

#
# git purge <branch-name>
#
# Delete a branch (irrespective of its merged status) and
# remove from origin.
#
# See ".bin/profile-additions.sh" for adding autocompletion
#

green='\033[0;32m'
yellow='\033[0;33m'
red='\033[0;31m'
blue='\033[0;34m'
color_off='\033[0m'

# Too lazy to change branches before I delete it
function check_set_branch_name {
  local current_branch_name
  local answer

  if [ -z $branch_name ]
  then

    # no branch name given, delete the current branch
    current_branch_name=$(git rev-parse --abbrev-ref HEAD)
    echo -e "${blue}Delete ${yellow}${current_branch_name} ${blue}?${color_off}"
    echo -ne "${blue}Type 'yes' to continue: ${color_off}"
    read answer
    if [ "$answer" != "yes" ]
    then
      exit 1
    fi
    branch_name="$current_branch_name"
    git checkout master
  fi

  # never delete master or release
  if [ "$branch_name" = "master" ] || [ "$branch_name" = "release" ]
  then
    echo -e "${red}WTF dude, you're deleting $branch_name.${color_off}"
    exit 1
  fi

}


function purge {
  echo -e "${blue}Purging $branch_name ...${color_off}${color_off}"

  # delete the local branch
  if git show-branch "$branch_name" > /dev/null 2>&1
  then
    git branch -D "$branch_name"
  else
    echo -e "${blue}No local branch to delete${color_off}"
  fi

  # delete the remote branch
  git remote prune origin
  if git show-branch "origin/$branch_name" > /dev/null 2>&1
  then
    echo -e "${blue}Deleting remote $branch_name ...${color_off}"
    git push origin ":$branch_name"
  else
    echo "No remote branch to delete"
  fi
}


function fin {
  echo -e "${blue}Happy Days!${color_off}"
}

branch_name=${1:-}
check_set_branch_name
purge
fin

And then for some sugar, to add bash-completion, I have in my bash profile:


source "$HOME/.bin/profile-additions.sh"

And that file has:


# add autocompletion for "git purge". Use all the branches
_git_purge ()
{
  __gitcomp_nl "$(__git_refs)"
}
July 16th 2015

  1. Doug: I'm confused, does it happen before or after the build?
  2. Stefano: dunno when it runs
  3. Stefano: so, could be a or b
  4. Stefano: heisenbehaviour
January 13th 2015