A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Git workflow

See also "A successful Git branching model"

Warning: This practice only works if everyone on a team does the same thing. If there is even one developer who doesn't rebase then the whole system breaks down. A much simpler way to do things is to stick with the defaults of pulling via merge (not via rebase) and endure the extra commits and mangled history. Then if you're using Bitbucket, the UI provides special links to 'sync' out-of-date branches before merging; Exclusively using those links is much safer and easier than manually rebasing. /Warning

Best practice

  1. branch from master
  2. make changes
  3. when you're ready to merge back, first rebase onto master
  4. then merge to master in your working directory
  5. squash all your commits into a single commit
  6. push the single commit to master
UPDATE: If you delete your feature branches after merging (perhaps for audit reasons), it seems better not to squash but to have one additional commit (--no-ff) which represents the merge for ease of backing out, viewing the diff of a single feature, etc. while simultaneously keeping full commit history in master.
Branch names are of the format: xxx-123-foo-bar (where xxx is our JIRA project ID, 123 is the Jira story number, and 'foo bar' describes the story)
If anyone has cut a branch off your branch, be nice and tell them before you rebase.

Detailed instructions

Setup
git fetch
git checkout master
git pull origin master
Branch
git checkout -t -b my-branch
# make changes to code
# run tests
git commit
git push origin my-branch
Rebase
git fetch
git checkout master
git pull origin master
git checkout my-branch
git rebase master
# run tests
git push --force origin my-branch
Merge
git fetch
git checkout master
git pull origin master
    # should already be up-to-date, otherwise go back and rebase again
git merge my-branch
git push origin master
NOTE: Rebasing before merging to master is required to keeping all your commits together in a bunch,
and in the right place at the top of the commit log.
NOTE: push --force will change the commits on your branch that you had pushed previously.
Never push --force to master!

Rebasing onto master before merging

If you don't rebase before merging to master, the master commit log could look like this after merging (commits are shown in reverse chronological order):
  • 4pm commit, in master
  • [lots of other commits in master]
  • 3pm commit, from feature branch                   <-- a="" feature="" li="" new="" of="" part="">
  • 2pm commit, in master
  • [lots of other commits in master]
  • 1pm commit, from feature branch                   <-- a="" another="" feature="" li="" new="" of="" part="">
Someone looking at the top of the log would not realise that a feature has just been merged (and probably deployed).
And even if they did find out, they would not be able to easily pick out the commits belonging to the feature branch.
If you do rebase then you end up with this output, where the feature commits appear all together at the top:
  • 3pm commit, from feature branch                   <-- a="" feature="" li="" new="" of="" part="">
  • 1pm commit, from feature branch                   <-- a="" another="" feature="" li="" new="" of="" part="">
  • 4pm commit, in master
  • [lots of other commits in master]
  • 2pm commit, in master
  • [lots of other commits in master]
NOTE: The same useful log view is possible by passing the --topo-order option to git log, which displays the first example (not rebased) in the same order as the second example.

Squashing

You can optionally squash all your commits into a single commit or several large commits for ease of reading. This is quite controversial and there are good arguments for both sides.
The commit history showing that you tried several different approaches before settling on one, or made and fixed typos may be unnecessary noise. On the other hand, it may be useful to see the broad strokes that were taken to solve the problem. Another view is that all commits are valuable and don't need to be changed.

Consider squashing some of your commits which weren't intended for anyone to see, while keeping others to maintain the general workflow in the individual commit history.

To squash some or all of your commits:
git rebase -i $(git merge-base my-branch master)
  • Change the word 'pick' to 'squash' in order to combine that commit into the previous one
    • you may also change the order of the commits if it makes sense
  • save and exit the file

Project branch

AKA Testing branch/QA branch
After making changes and pushing them to a feature branch, we then merge that feature branch to a project/team branch. After the feature has been tested, the feature branch is merged to master.
A major benefit of this approach is that there's no big "final merge" at the end of an iteration where conflicts from all feature branches must be resolved at the same time. As soon as a feature is complete and tested, it is merged to master.
One drawback of this is that conflicts between features will need to be resolved once when merging to the project/testing branch, and then possibly resolved again when merging to master. We consider the benefits to outweigh this drawback.
There is no branching strategy that can completely prevent conflicts if two people are working on the same code simultaneously. Our solution is: Try to avoid conflicts as much as possible simply by not working on the same area of code at the same time as someone else.
If two people are working on the same code, they should resolve conflicts with each other as frequently as possible (e.g. every day or every couple of days), perhaps by using a merged feature branch. A side effect of this is that all their code must be released together.

Multiple feature branches

Where several stories need to be tested together before being finished. First create a feature branch for an umbrella story, and branch all features off there. Merge back to test them together, and finally merge the umbrella branch to master.
Do not cut feature branches from master as usual and merge them to the umbrella branch, as it then gets contaminated with unrelated commits.
If you some changes from master, first rebase the umbrella branch on master, let everyone know, and then rebase each feature branch on the umbrella branch.

Do not merge after a rebase

We've discovered that actually git doesn't hate us, we've just been using it wrong.
Say two people are working on a feature branch (that's been cut from master), they are happily pushing to and pulling from the branch. Then one of them rebases that branch back onto master. The others all pull the new version, and everything looks fine (except the number of commits might look like it's doubled). But everything isn't fine.
When you come to rebase that branch on master again, (perhaps just before you make the final merge back), you will encounter some weird conflicts - the branch will appear to conflict with its own commits.
The solution is: If the feature branch gets rebased, do not use 'git pull' (as that does a merge by default, and merges don't play nicely with rebases). Instead do 'git pull --rebase', and after that, everything will be groovy. It's best to make 'git pull' always do a rebase instead of a merge:
# make 'git pull' on master always use rebase 
git config branch.master.rebase true

# setup rebase for every tracking branch
git config --global branch.autosetuprebase always
Another way to avoid this problem is to never 'pull': If you find you can't push your feature branch because someone else has made commits to it, then make a temporary branch to store your commits, then re-checkout the latest feature branch from origin (or do 'git reset --hard origin/branchname'), and then cherry-pick your commits back into it from the temporary branch.

General advice

Merge frequently

Merge your code upstream as often as possible, in order to resolve any conflicts early, while the code is still fresh in everyone's mind.

Rebase cautiously

If you're the only developer on a branch, rebase frequently.
If others are working on the same branch, or are working downstream, then you must agree a good time to rebase, i.e. after everyone has committed and is prepared to pull (if on same branch) or rebase (if downstream) and resolve any conflicts.

Document your policy

Write down the rules you plan to follow in order to minimise the pain of merge conflicts and other confusion. Make sure everyone understands the rules.

Communicate

Ensure developers working on the same branch, or downstream of others in the team are communicating enough to get advance warning of possible merge conflicts, so these can be resolved as early as possible, and prevent potential conflicts from all building up and causing pain/confusion at the end of the development cycle.

Avoid dependencies

The best way to avoid conflicts is to organise the work to reduce dependencies in the first place.

  • Horizontal slicing is one way to achieve this (e.g. one person works on the model, one on the view, and one on the controller).
  • Making small changes and deploying them quickly is another way.

There's more than one way to do it

If a set of stories/tasks requires distinct sections of code to be written for the same feature, consider cutting a main feature branch, and having each developer cut a sub-branch from that for their individual tasks. Individual developers could also use a sub-branch for wide-ranging experimental changes. Or if developers feel more comfortable committing to a single large feature branch and co-ordinating with each other, or if that just makes more sense for a particular feature, then do that instead.

Git hooks, config and prompt

The config parts are superceded by my .gitconfig file on github.

Git hooks

Git hooks allow you to define a script that will get run at key points in your git workflow.
There are some examples in the xt directory in every repo in the .git/hooks/ directory.
To make them work, either rename the existing ones to remove the .sample suffix, or create a symbolic link like this:
cd working_dir
ln -s .git/hooks/post-commit /home/user/scripts/git/your-post-commit-script
Remember to make scripts executable (chmod +x filename)
To bypass any git hooks, pass the --no-verify flag to the relevant git command

Some useful hooks

pre-commit

Check for common mistakes:
  • SQL files missing transaction commands BEGIN or COMMIT
  • Merge markers accidentally left in: ======== <<<<<<<< >>>>>>>>
  • To do: Check for trailing whitespace (Perl critic does this on Jenkins)
  • To do: Check for missing use strict and use warnings, or their equivalent (e.g. use NAP::policy - Perl critic does this)
  • To do: Prevent merging more than one commit to master (best practice says they should be squashed into a single commit)

pre-rebase

Prevent rebasing for commits that exist in more than one branch (i.e. have been pushed or pulled).
Stops you accidentally rebasing when it's going to confuse your colleagues working on the same branch or downstream.
To bypass this check, simply pass the --no-verify flag to 'git rebase'
Warning: Always run it with rebase -i (for interactive). it could behave unpredictably if you miss out the -i.

post-checkout

Sometimes I forget to do 'git fetch' when I pull, so this hook always runs 'git fetch' after 'git checkout'.
You can easily see if you then need to do a pull, by using the intelligent git prompt below.

Useful configuration

Diff3

More useful diffs when merging
git config --global merge.conflictstyle diff3
(source)

Rerere

Setting this makes git remember your conflict resolutions, and apply them again automatically if you happen to make the same merge again. This has saved me lots of time.
git config --global rerere.enabled 1

More explanation

Pull --rebase

Rebase and merge don't play nicely together. If two people are merging to a common feature branch and one of them rebases, you need to make sure you always do a git pull --rebase instead of the default git pull (which does a merge). Otherwise you'll end up with a lot of confusing duplicated commits. We really don't want those ending up in master.
These commands make git pull always do a rebase instead of a merge:
# make 'git pull' on master always use rebase 
git config branch.master.rebase true

# setup rebase for every tracking branch
git config --global branch.autosetuprebase always

No fast-forward

The fast forward flag is set for merges by default, meaning if a merge can be fast forwarded then there will be no extra commit to represent the merge. Unsetting this flag makes there always be a separate commit to represent a merge.
It's useful because it makes it more obvious what was merged, and a merge can also easily be reverted if there is a problem, by reverting a single commit.
git config --global merge.ff false

Safer push --force

Prevent yourself from accidentally force-pushing to all branches by mistake:
git config --global push.default upstream

Useful commands/aliases

gitbranch

Quickly create a new branch (-b) that tracks the current branch (-t) and check it out. Tracking means 'git status' tells you how far ahead it is from this branch.
git checkout -t -b new_branch_name

gitlog

Display the log with branch names/tags (--decorate), with full not truncated filenames (--stat=200,200), the shortest possible commit hashes (--abbrev-commit) and accept any other options passed ($@).
git log --color --stat=200,200 --decorate --abbrev-commit --relative "$@"

Intelligent prompt

This prompt works best with the post-checkout hook above, ensuring git always knows the state of the branch at origin and the upstream branch. It's intended to take up the least amount of screen space while providing the most information.

Examples

New branch, no edits
(feature-branch) clean ~/dev/source/xt $
New branch, some uncommited edits
(feature-branch) ~/dev/source/xt $
New branch, two commits, no other edits
(feature-branch) 2> clean ~/dev/source/xt $
New branch, two commits, plus some other uncommited edits
(feature-branch) 2> ~/dev/source/xt $
New branch, no edits, but upstream has moved on by five commits
(feature-branch) 5< clean ~/dev/source/xt $
You have made two new commits, but upstream has moved on by five commits (branch has diverged)
(feature-branch) 5< !! 2> clean ~/dev/source/xt $

Code

I replaced the update_prompt function in my ~/.bashrc_nap file in my VM with the following:
function __git_commits_behind {                                                if [[ -n "$gitstatus" ]]                                                   then                                                                           echo $gitstatus | perl -ne'm{Your branch is behind.+by (\d+) commit} && print "$1< "'
    fi                                                                     }                                                                                
function __git_commits_ahead {                                                 if [[ -n "$gitstatus" ]]                                                   then                                                                           echo $gitstatus | perl -ne'm{Your branch is ahead of.+ by (\d+) commit} && print "$1> "'
    fi                                                                     }                                                                                
function __git_branch_diverged {                                               if [[ -n "$gitstatus" ]]                                                   then                                                                           echo $gitstatus | perl -ne'm{and have (\d+) and (\d+) different commit\(s\) each, respectively} && print "$2< !! $1> "'
    fi                                                                     }                                                                                
function __git_branch_clean {                                                  if [[ -n "$gitstatus" ]]                                                   then                                                                           echo $gitstatus | perl -ne'm{nothing to commit} && m{working directory clean} && print "clean "'
    fi                                                                     }                                                                                
function update_prompt {                                                       export branch=$(git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
      
    if [ -f .git/index ]                                                       then                                                                           # we are in a git working directory                                        # display the git prompt                                                   export gitstatus=$(git status)                                             export PS1="\[\033[${branch_colour}m\](${branch}) $(__git_commits_behind)$(__git_commits_ahead)$(__git_branch_diverged)$(__git_branch_clean)\[\033[00m\]\w \$ "
    else                                                                           # normal prompt                                                            export PS1="\[\033[${host_colour}m\]\h\[\033[00m\]/\u \[\033[${branch_colour}m\]${branch}\[\033[00m\]\t \w\n\$ "
    fi                                                                     }                                                                                
export PROMPT_COMMAND=update_prompt


(copied and pasted from Confluence, so please excuse any CSS)

Enforcing breaks away from the screen

There's a need to interrupt oneself, to avoid spending too much time constantly staring at the screen/sitting down, etc. to prevent RSI, eye strain, back injury, etc.
  • RSIBreak - Looks promising, but falls prey to multi-monitor taskbar bug and is hidden behind taskbar, also greying out of screen doesn't work. And doesn't seem to always alert me. And "lock screen" button doesn't work. Nor does "run on startup". (Ubuntu 12.04).
  • Workrave - In some ways looks better than RSIBreak. Easier to configure/understand notification times, has numbers countdown instead of a clock, and suggests exercises to do in the breaks. But it doesn't match up small breaks with long breaks like RSIBreak does, so it often pops up an alert soon after I've just taken a break.


Faster count(*) in postgres

For an approximate count you can do:

SELECT reltuples FROM pg_class WHERE oid = 'schema_name.table_name'::regclass;

(replacing schema_name and table_name)

(source)

How to REALLY disable game center on iphone

How to prevent annoying game center login prompt (or freezing and popups if you're logged in):
  • Log out of game center
  • Start game center
  • Instead of logging in, create a new Apple ID (bottom of game center logon screen). Doesn't matter what you create as this is bogus. You are now logged into game center with a different ID than you use for other features such as the App Store
  • Log out of game center
  • Start a game, press cancel, and exit the game
  • Do this three times, and game center will prompt you if you want to disable it. Select yes.

For then on, you'll never be prompted for game center logon, or get the game center notifications.

If you download a new app from the App Store, it will use your original Apple ID, which is the behaviour you want.

Confirmed working for iOS6.

(source)

Poor notification features on iPhone

The notifications on iPhone are really poor compared to Android or Blackberry.

First of all, the list of default sounds are all so horrible! They irritate my ears. Why not include some soft and pleasing sounds as well as the loud and harsh ones?

On my android I used the vibrate function to discretely notify me of an incoming message. On iPhone the vibration is so loud that it can be heard by the entire room, it's as loud as the notifications themselves - what's the point in that?

Then there's a central list of notifications settings. But lots of apps (even Apple's built-in apps) don't allow you to configure the notification sound from that list, e.g.:

  • Built-in clock's Timer function. Not in the notifications list, only configurable in-app, and limited to a set of loud, harsh sounds. "Buy More Tones"...? Yeah, right. Why can't I choose my own sounds for this?
  • Built-in clock's Alarm function. Again, only configurable in-app. At least here I can "Pick a song" and use any mp3 I can come up with. But no vibrations possible.
  • WhatsApp - only has a switch to turn sounds on/off. Notifications are in the app, and severely limited to one of seven loud, irritating sounds that are impossible for me to use at work. And there is no custom vibration possible. Okay, maybe this one's not Apple's fault, but I was perfectly happy with notification in the Android version of this app.

Why is it important that all apps appear in the notifications list? Simply because any improvements to the central notification functionality will then be usable with those apps. If it's not in the list, it will be left behind with a lame in-app out-of-date feature-less custom notification system.

In the accessibility settings you can set the LED to flash when a message comes in, but it only flashes once! Not very useful - what if you miss it? On Blackberry you can make it keep flashing until you see the message.

In the Sounds section of iPhone settings, there's "Sounds and Vibration Patterns". An excellent feature where I can tap the screen to design a vibration pattern pleasing to me, such as a vibration hard enough to be felt by me, but soft enough so no-one can hear it. Unfortunately there are some fatal flaws in the feature:
(1) It only lists Apple's built-in apps, plus Twitter and Facebook (i.e. no WhatsApp). Why isn't this feature connected to the central notifications list?
(2) It's damn difficult to tap in the right way to produce the vibration I want. I need to be able to design the vibration using numbers like some apps on other platforms: On for 100ms, off for 1000s, on for 100ms, etc.

These are killer features for me and ultimately they will prevent me from using the iPhone for any length of time. I'm sure things will be slightly better with iOS7, but I'm sure Apple's built-in apps will still fail to integrate consistently with any new central notification features.

Gmail on iPhone "username or password is incorrect"

"The user name or password for imap.gmail.com is incorrect"

To fix, go here and enable access:
http://www.google.com/accounts/DisplayUnlockCaptcha

But what you really want to do is create a one-time application-specific password:
  • Go to Google account settings: https://www.google.com/settings/account
  • Click "security"
  • Click "Manage your application specific passwords"
  • Create a new password and use that on your device
(source)

Sync Google contacts with iPhone

iOS 7 should just work when you add a Google mail account.

iOS 5 or 6:
Settings > Mail, Contacts, Calendars > Add Account... > Other > Add CardDAV Account

(source)

Change the date of a git commit

Author date:

git commit --amend --date="Wed Feb 16 14:00 2011 +0100"

Commit date:

GIT_COMMITTER_DATE="Wed Feb 16 14:00 2011 +0100" git commit --amend

You've got to love git.

(source)

Query installed packages on Ubuntu

Ubuntu uses debian packages, not RPMs so yum isn't relevant.

List all packages:
dpkg-query -l

Display summary info for a package:
dpkg-query -s package_name

Display files installed by a package:
dpkg-query -L package_name

Instant message notifications on Linux

Pidgin

Pidgin is an IRC client for Linux and Windows.

By default, pidgin's notifications on Linux that someone is messaging you are not very visible, they're in the title bar of the application, and can easily be missed.

There's a plugin included that causes the notifications to pop-up using libnotify, but they only appear from a short time and are not customisable, so are also easy to miss. "notify-send" is one command to send notifications using libnotify.

Growl is a notification system (originally for Mac) designed to be customised with a particular display style. There's a growl plugin (written in Perl) on the official Pidgin plugins page, but it seems to be designed to work with growlnotify, which doesn't run on Linux.

There's a port of growl for Linux (the daemon). To send it notifications you can use growl_notify.pl which is a wrapper for Growl::GNTP, the Growl protocol. The growl plugin mentioned above could be modified to use growl_notify.pl.

You could then choose your desired display style for Growl, e.g. something that stays on top of other windows and can't be missed.

There's also a prototype notification plugin that uses zenity, a package that displays simple dialog boxes that are much harder to miss.
To use it, download this pidgin zenity plugin, put it in your ~/.purple/plugins directory (create it if it doesn't exist), and it will appear in your Pidgin plugins list.
As it's a prototype, it will currently notify for every message in a conversation, but you may prefer being notified too much rather than too less. Email the developer if you want it to be improved.

Skype

It's also easy to miss incoming Skype messages. But Skype has an "Execute the following script" option for incoming chat messages. That can be set to something like this:

/usr/bin/zenity --warning --title "Skype message" --text "You have received a message in Skype"

Upgrade Ubuntu 12.04 to 12.10

Change the 'Update Manager' settings to notify you of any new Ubuntu versions (source).

Sound systems in Ubuntu

May have to fiddle with all of these to make sound work correctly:
  • pulseaudio
  • alsamixer
  • sound settings
  • skype sound devices

When Thunderbird's calendar broke

Events weren't displayed properly in Thunderbird email client and its Lightning calendar plugin, for two weeks. There were complaints.

To fix it, manually download a previous version of Thunderbird (24.0) and its associated old version of Lightning (2.6).

(Missing step here regarding how to have Synaptic recognise an old version of Thunderbird. Disabling upgrade in Synaptic may not be necessary if Thunderbird is run outside of any package manager)

Then fix them both so they don't upgrade automatically:

  • Use Synaptic package manager to find Thunderbird, the click the 'Package' menu and select 'Lock Version'.
  • For Lightning, go to Add-ons, Extensions, right-click Lightning and 'Show more information', then switch off 'Automatic Updates'.

After a while, the developers will probably fix it. After that happens, you can unlock the packages and upgrade again.

It's times like this that make me appreciate Microsoft Outlook :(

Pop-up notifications on linux

Alternatives:
  • notify-send hello # works, but disappears too fast, and can easily be missed
  • growl # advanced, haven't figured out how to use it
  • knotify # apt-get install kde-baseapps-bin
  • zenity # zenity --warning --text "meeting is now"
Hook one of these into your calendar application.

Or for IRC, using pidgin, try one of:
Or write your own pidgin plugin like I did, to use a notification system of your choice:

Working with RPMs

Use -q to query:
    rpm -qi package_name # display info about the specified package
    rpm -ql package_name # list all the files in the specified package
    rpm -qa # list all installed packages

Add -p if you're querying an RPM file, omit it if you're querying an installed package.

How to view .msg files on Ubuntu

wget http://www.matijs.net/software/msgconv/msgconvert.pl
sudo apt-get install libemail-outlook-message-perl
sudo apt-get install libemail-localdelivery-perl
perl msgconvert.pl YourMessage.msg

Thanks to this software

How to install CPAN Perl modules on Ubuntu using apt-get package manager

script:

PACKAGE=$(echo "$1" | perl -e '$x=<>; chomp($x); $x=~s/::/-/g; $x=lc($x); print "lib$x-perl"')
sudo apt-get install $PACKAGE

Thanks

Configuring Ubuntu

After upgrading from Ubuntu 11.04 (Natty Narwhal) to 12.04.2 (Precise Pangolin), I couldn't make my original account log in to gnome. So I had to copy over all the settings to a new user account. Also, a number of things are different in Ubuntu 12.
  • To bypass Unity, select 'Ubuntu classic' window manager at login screen
  • In Synaptic package manager, find overlay-scrollbar and uninstall it, then reboot
  • There is no top-level settings menu like 11.04, instead look under the Applications menu
  • Gedit: Set tab width to 4, insert spaces instead of tabs, and use automatic indentation
  • Nautilus: Edit | Preferences | Views (tab) | View new folders using: List View
  • Increase terminal buffer to 'unlimited'
  • Copy over SSH keys:
    • cp -rp ~olduser/.ssh ~newuser/
  • Install chromium, copy settings from chrome:
    • sudo cp -Rp ~olduser/.config/google-chrome/ ~newuser/.config/chromium/
  • Install Thunderbird 24 + Lightning calendar plugin, copy user profile across
    • mv ~newuser/.thunderbird/axhtibx7.default{,.backup}
    • sudo cp -Rp ~olduser/.thunderbird/sw5u8ylf.default ~newuser/.thunderbird/axhtibx7.default
    • The 'Accept' button is missing for some event invites
      • "This message contains an event that this version of lightning cannot process"
      • This is a bug (reported and fixed via developer's patch)
    • Sort by 'Received' and 'Threaded' to get threads ordered by last received message
  • Install Firefox, copy user profile:
    • mv ~/newuser/.mozilla/firefox/ce3ut43x.default{,.backup}
    • cp -rp ~oluser/.mozilla/firefox/ra129tce.default/ ~/newuser/.mozilla/firefox/ce3ut43x.default
  • Install Pidgin for IRC, copy config across:
    • cp -rp ~olduser/.purple/ ~newuser/
    • Error, Pidgin crashes with "SIGSEGV in pthread_mutex_lock()"
    • So, re-set up pidgin for all networks
    • Disable smileys as they intefere with pasted code:
      • Tools | Preferences | Themes | Smiley Theme | None
  • Install VirtualBox, go to "Machine | Add", and browse to your VM on disk
  • Install Skype 4.0.0.8, because 4.2.x crashes on incoming calls:
    • Type Ctrl-O to reach the options screen to set the proxy in 4.2.x (source)
    • Disable 'contact online' and 'contact offline' notifications because of this
    • Skype has no sound, in fact Ubuntu has no sound:
      • killall pulseaudio (sourcesource)
      • restart Skype (may need to "kill -9 skype")
  • To find the exact version of Ubuntu I'm running:
    • This only shows 12.04: Applications | System Tools | System Settings | Details
    • This command tells you the exact version (12.04.3):
      • lsb_release -a
  • Configure multiple workspaces:
    • Right-click in the bottom-right-hand corner and edit preferences (source)
    • Still can't actually switch workspaces though without the screen freezing up.
    • Hold Ctrl-Alt-Del for 5 seconds to get back.
  • Fix Alt-tab:
    • sudo apt-get install compizconfig-settings-manager
    • Scroll to bottom, check 'Static application switcher' (source)
  • Fix the date display:
    • Use dconf-editor | com | canonical | indicator | appmenu | datetime (source)
  • I get "Ubuntu internal error" sometimes, that never happened under 11.04.
  • Beware of cancelling a logout. An application preventing the logout may eventually crash or close, and the logout will happen at that point without further warning.
  • Problem: Sound comes out of both the laptop speakers and the headphones at the same time.
  • Problem: Workspaces don't work properly. Cannot right-click on window's title to send it to a new workspace. Clicking on a new workspace in the bottom right doesn't work.
  • Problem: The top and bottom taskbars are visible even when the screen is locked, when using multiple monitors (bug report).

Can't push to github




The problem:

Git asks you for your password, when it should just accept your SSH key.

$ git push origin master
Password for 'https://github@github.com': 


The solution:

1) First, read the github documentation to ensure your SSH keys are set up correctly

2) Then add this to your ~/.ssh/config:

Host github github.com
Hostname github.com
User git
IdentityFile ~/.ssh/github/id_rsa


3) Finally, clone using ssh instead of https:

git clone https://github.com/username/project-name.git # wrong

git clone git@github.com:username/project-name.git # right

4) Push should now work as expected


POD servers

You know, POD.
  • Pod::Simple::HTMLBatch - The best one. Properly marked up HTML, so fully customisable with CSS. Split into top-level directories. Doesn't do .t files, but can use a subclass of Pod::Simple::Search rigged to recognise .t files. Submitted patch.
  • Pod::Server - Basic default output, one single list. Docs lacking. What about CSS?
  • Pod::Webserver - Lots of dependencies, Catalyst, etc. GUI looks great. Couldn't get it to read from local dirs though.
  • Pod::POM::Web - Untested

How to download a gmail attachment on mobile

How to download a gmail attachment on your mobile:

  • Go to the gmail website on your mobile, the mobile version will load
  • Click the 'Basic HTML' link at the bottom
  • A download link will now be visible in your emails


Simple small Perl webservers

Quick start, if it's just a proof-of-concept and won't be running for long:

More complicated to set up, but much more robust:

Perl: Try::Tiny vs TryCatch vs Syntax::Feature::Try

From NAP::Policy (thanks dakkar):

       Using TryCatch you’d write:

         try { ... }
         catch (SomeClass $e) { use($e) }
         catch (SomethingElse $e) { use($e) }
         catch ($e) { use($e) }

       Using Try::Tiny you’d write:

         try { ... }
         catch {
          # here you get the exception in $_
          when (match_instance_of('SomeClass')) { use($_) }
          when (match_instance_of('SomethingElse')) { use($_) }
          default { use($_) }
         }; # note the semi-colon

       On the other hand, if your TryCatch use did not have a unqualified "catch ($e)", you need to write "default { die $_ }" to re-throw the unhandled exception (yes, you really have to write "die
       $_", read the documentation of die to learn the ugly details; "die" without arguments won’t do anything useful there).

       Also, keep in mind that the blocks used by Try::Tiny are actually anonymous subroutines, so they get their own @_ (nothing in the case of the "try" block, the exception in the case of the
       "catch" block), and "return" will return from the block, not the containing subroutine.


      Devel::Declare (via TryCatch) is deep scary voodoo.


From #backend:

  • Try::Tiny is the less magical and scary (and fragile) version of TryCatch
  • Syntax::Feature::Try is currently the least offensive of the alternatives, but it has quite a way to go
    • it does nasty things with the call stack
    • preferrably it would splice the optree, like a compiler macro
  • How does return work? TryCatch returns from the surrounding sub, Try::Tiny returns form the try {} block

Developing on Android basics

Initial steps to take:

  • Turn on USB Debug mode
    • Old devices: Settings | Applications | Development | USB debugging (will disable SD card access)
    • New devices: Settings | About phone | Build number | Tap 7 times (yes, really). Dev settings will now appear on the menu.
  • Troubleshooting connection:
    • Verify USB cable works
    • Verify USB port works
    • Re-plug in the cable about 20 times (yes, really)
    • Windows: Run "Android SDK manager" (sdk\tools\android.bat) and install 'Google USB driver' under Extras
    • adb devices # error "???????????? no permissions usb:3-3
      • adb kill-server
      • sudo adb start-server # server must be started as root
      • adb devices
  • ADB Shell commands:

Breaking coder's block

Take a break, go for a walk, anything that doesn't involve thinking about coding.

Just start writing something, anything, the smallest step you can think of, and commit to version control as you go along. Clean up later.

Tell yourself "I am not this coding problem".

Ask a colleague for ideas.

(source, source, source)

How to sync over FTP

Don't re-invent the wheel.

1) Install rsync instead, which is designed with syncing in mind.

2) ftpsync was written a decade ago. Perhaps it has been updated since.

3) lftp syncs over FTP and is being actively maintained.

4) Perl package turbo-ftp-sync may also fit the bill.

Email gateways

I want to write my tweet in an email and have it tweet for me, because I don't like most twitter clients. Email is also available on all devices (like old blackberries) where there aren't good apps.
  • ping.fm - used to work, but it got shut down
  • ifttt.com - couldn't get it to work
  • everything else - closed

List git branches by date and author


if [[ "$1" == "-r" ]]
then
    REMOTE="-r"
else
    REMOTE=""
fi

for k in `git branch $REMOTE | perl -pe s/^..// | sed 's/.\+ -> //'`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset (%cn)" $k|head -n 1`\\t$k; done | sort

Who created an RPM?

You can get a clue by finding out the name of the host on which it was built:

    rpm -pqi foo.rpm

Vector graphics editors for linux

Vector graphics files can be saved as .svg, and stay in high resolution no matter how far you zoom in. The source data is XML/text and can be committed to version control.
  • Gimp - full graphics but no vectors
  • Karbon - vectors
  • Inkscape - vectors
  • SVG Edit - vectors. Basic, but browser-based. Can't zoom out. Things were misaligned.

Git set upstream

git branch --set-upstream-to

Or in later versions:

git branch --set-upstream

Thanks

Automatically generated diagrams of Perl code


  • Use UML::Sequence to diagram your method calls - Looks cool but couldn't get the module's tests to pass.
  • Write your own code to produce a Graphviz spec file - Good choice if you want a data structure diagrammed, e.g. State transitions.
  • SchemaSpy works well for database tables.
Untried:
  • UML::Class::Simple - class diagrams, not methods?
  • Devel::Diagram - class diagrams, not methods?
  • Devel::DProfPP

How are my Perl modules being loaded?

Large legacy system?
Confused about how your modules are being loaded?
Getting errors because they are loaded in the wrong order?

Try Devel::TraceUse

Emacs for a vi user

In the past I've exclusively used vi, but now I want to use Emacs as I've heard it has some useful modes, for example 'font-lock-keywords' mode which is one way to easily highlight certain keywords in a program's console output. I don't want to mess around compiling specialised text highlighting programs, and they're not in my standard repos. Emacs is much more likely to already be available wherever I need it.

Emacs commands:
  • To exit: C-x C-c
  • Turn on syntax highlighting: M-x font-lock-mode

Key:
C = Ctrl
M = Meta (Alt)

Thanks to the rest of the web

UPDATE: It turns out font-lock-keywords can easily be implemented in a 3 line bash script. Call it "highlight":

    # Usage: tail -f error.log | highlight "error"
    RED="$(tput setaf 1)"
    RESET="$(tput setaf 7)"
    sed "s/$1/$RED$1$RESET/"

But I would still like to see the Perl debugger integrated into Emacs

Colouring terminal output


Thanks to StackOverflow

UPDATE: You can actually do this yourself with pretty much any programming language that has an ANSI colours library.

Drawing software diagrams

Alternatives:
  • Pencil and paper: Extremely easy to use, but no templates, and not online
  • GraphViz: Good for automatically generating a diagram from code, but you need to implement a script to do it. Bad (impossible) for free-form manual drawing.
  • Asciiflow: Good for quickly knocking up a rough drawing of boxes and lines. Bad for editing that drawing.
  • OpenOffice/LibreOffice Draw: Seems to be good for diagrams. Can export to PDF. How do you make the canvas bigger?
  • LucidChart: Free. Online only, but can export to PDF.
  • Dia: Free, but clunky. Dia by name, dire by nature. Exported images are messed up.
  • Visio: Microsoft. You must pay.
  • Omnigraffle: Mac only, but nice.
  • www.draw.io: Free, but not as intuitive as others.
  • Gliffy.com: Free trial. Online only. Quite good.
  • moqups.com: Good. One project per free account.
  • Creately
  • Diagramly?
  • Pencil project?

Fix debian/ubuntu gpg error when updating package sources


When updating the Debian based system, apt-get may display an error message like:

W: GPG error: ftp://ftp.debian.org/ testing Release:       
The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 010908312D230C5F      

W: There is no public key available for the following key IDs:      
010908312D230C5F

The same problem in Synaptic package manager appears as:

W: Failed to fetch http://http.us.debian.org/debian/dists/sid/InRelease  
W: Failed to fetch http://http.us.debian.org/debian/dists/sid/Release.gpg

Unable to connect to http.us.debian.org:http: [IP: 128.30.2.36 80]

This is a feature of the apt-get system that guarantees the authenticity of servers for updating Debian.

Simply type the following commands, taking care to replace the number below with that of the key that was displayed in the error message:
gpg --keyserver pgpkeys.mit.edu --recv-key  010908312D230C5F      
gpg -a --export 010908312D230C5F | sudo apt-key add -

Copy+pasted from here

HTML::FormHandler example

package My::Form;

extends 'HTML::FormHandler';

has_field "age" (
    label => "Type",
    required => 0,
    type => 'Integer',
);

____________________________________________________________

package My::Handler;

my $form = My::Form->new;

if ($form->validated) {

    # validate form
    $form->process( params => $c->req->query_params );
    my @errors = $form->errors;
    alert("Error: $_") foreach @errors;

    my $age = $form->field('age')->value;
    $logger->info("User entered age $age");

    # build page
    $c->stash->{age} = $age;
}

Stop Confluence making CamelCase links

You can include the following code in the page, or make a macro out of it.
Note: You need to attach JQuery to one of your wiki pages, and edit the URL in the code.
{html}
<script type="text/javascript" src="/download/attachments/59835554/jquery-1.2.6.js"></script>
<script type="text/javascript"> 
//The $ notation is used by DWR. So we rely on jQuery namespace only
jQuery.noConflict();          
jQuery(document).ready(function() {
   //The camel case links have class createlink. So fetch all such links and remove the html part and retain the text part
   jQuery("a.createlink").each(function(index){
    var text = jQuery(this).text();
    if(isValidCamelCase(text)){//Only filter where we have a camelcase text and not valid yet to be created link
       jQuery(this).after(text).remove();
    }
    return true;
   });
});

function isValidCamelCase(s){
 if(s == null || s.length == 1){
  return false;
 }
 
 if(s.indexOf(' ') != -1){
  return false;
 }

 //Check for case where valid link is being created like [Test123]
 var indexOfNonUpperCaseChar = -1;
 for(var i = 0; i < s.length; i++){
  var c = s.charAt(i);
  if(!isUpperCase(c)){
   indexOfNonUpperCaseChar = i;
   break;
  }
 }
 
 if(indexOfNonUpperCaseChar == -1){
    return false;
 }
 
 var lowerCase = s.toLowerCase().substring(indexOfNonUpperCaseChar);
    var originalCase = s.substring(indexOfNonUpperCaseChar);
    if(originalCase == lowerCase){
     return false;
    }
 return true;
}

function isUpperCase(char){
 return char >= 'A' && char <= 'Z'
}
</script>
{html}

Thanks