Quick guide: Running stock Debian on the Raspberry Pi 2

At the time of writing, the ‘Raspbian’ port of Debian is often used on the Raspberry Pi. It was created to match the CPU architecture, for better performance. These reasons don’t apply to the newer Raspberry Pi 2, so if you’re a Debian desktop or server user, you can do away with the fork and just run Debian Jessie armhf.

The info from Debian is: https://wiki.debian.org/RaspberryPi2

A bit more background about why this only applies to the Raspberry Pi 2-

  • The Raspberry Pi 1 uses ARMv6 chipset with hard floats
    • The Debian armhf port requires ARMv7
    • The Debian armel port doesn’t use hard floats, so is unnecessarily slow on the Pi.
    • So Raspbian was created for the Raspberry Pi 1’s ARMv6 w/ hard-floats, and gets the most juice out of the CPU on the Raspberry Pi 1.
  • The Raspberry Pi 2 uses ARMv7 with hard floats, so Debian armhf port is fine.

Install the image

Image is linked to from this page:

I will assume that your machine has an SD card slot. To find the device name, list out disks and look for one of the correct size, which appears when you plug in the card:


Download a copy of the image, extract it out, and dd the file on to the card:

wget -c https://images.collabora.co.uk/rpi2/jessie-rpi2-20150705.img.gz
gunzip jessie-rpi2-20150705.img.gz 
sudo dd if=jessie-rpi2-20150705.img of=/dev/sdX bs=4M
sudo sync
umount /media/$USER/*

Plug in the Raspberry pi, and then log in. If you are using SSH, then arp-scan is a good tool to pick up devices on the network:

sudo apt-get install arp-scan
sudo arp-scan -l
ssh root@x.y.z.w

Configure pi- Things like screen resolution and HDMI go here:

cd /boot/firmware/
nano config.txt

Perform a software upgrade:

nano /etc/apt/sources.list
apt-get update
apt-get dist-upgrade

Start fixing security defaults. Remember that this is not a clean install, so start by setting your own passwords:


Check that there are no other accounts with passwords set:

cat /etc/shadow

Regenerate all SSH Server keys (commands from here):

ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t ecdsa -b 521
ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa

Lastly, generate some locales:

sudo locale-gen en_US en_US.UTF-8 en_GB en_GB.UTF-8

How to resize a Windows VM image with virt-resize

I recently had a Windows 7 Virtual Machine stored on an undersized qcow2 file. This post steps through the simplest way that I know to produce a new, bigger disk and expand the filesystem onto it.

Empty out the empty space

Because the guest VM is stored on a QCOW2 file, we can recover un-used space on disk by zeroing it out now. Download the sdelete utility from Microsoft and run it on the system.

sdelete -z

One this is done, power off the guest.

Assuming the host is linux, you need the qemu-utls and libguestfs-tools packages to follow these steps. On Debian-

apt-get install libguestfs-tools qemu-utls

Move the VM image to a new filename and inspect it.

mv windows.img windows.img.bak

The file command indicates that the disk is about 30GB expanded.

$ file windows.img.bak 
windows.img.bak: QEMU QCOW Image (v3), 32212254720 bytes

The qemu-img command shows that the disk is 83% full:

$ qemu-img check windows.img.bak 
No errors were found on the image.
411337/491520 = 83.69% allocated, 5.66% fragmented, 0.00% compressed clusters
Image end offset: 26961969152

Check out your FS names, note that /dev/sda2 is the disk we want to up-size in this case

$ virt-filesystems -a windows.img -l
Name       Type        VFS   Label            Size         Parent
/dev/sda1  filesystem  ntfs  System Reserved  104857600    -
/dev/sda2  filesystem  ntfs  -                32105299968  -

Make a new, bigger disk image

Create a new disk of the desired size. In my case, 50G is sufficient:

$ qemu-img create -f qcow2 windows.img 50G
Formatting 'windows.img', fmt=qcow2 size=53687091200 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16

The file command shows that this new empty disk image is larger than the old image.

$ file windows.img
windows.img: QEMU QCOW Image (v3), 53687091200 bytes

Copy the old disk to the new one. The --expand option names a partition which will be grown to fill the extra space.

virt-resize --expand /dev/sda2 windows.img.bak windows.img

The virt-resize command shows a progress bar while it works, and zero-blocks will be reclaimed as a result of the output format:


The final line of output suggests holding on to your backup until you’ve checked it, which is wise:

Resize operation completed with no errors. Before deleting the old disk,
carefully check that the resized disk boots and works correctly.

Check that the new disk is valid and contains partitions at the expected size:

$ virt-filesystems -a windows.img -l
Name       Type        VFS   Label            Size         Parent
/dev/sda1  filesystem  ntfs  System Reserved  104857600    -
/dev/sda2  filesystem  ntfs  -                53579939840  -

Boot up the guest

When the machine boots up, you may get a disk check prompt. Because the console I was using triggered the ‘Press any key to cancel’ prompt, I had to reboot and leave the console disconnected in order for the check to start.



After booting, the C:\ drive should display at its new size:


Convert a PC to a HTPC with Debian and Kodi

I recently converted an old workstation to run as a home-theatre PC (HTPC). I’ve noted down the setup here for others who are making an installation like this. Some steps depend on using a radeon chipset, and will need to be adjusted for your computer.


First up, Desktop ‘towers’ are not a good form-factor for sitting in TV cabinets. If your PC is this sort of size, then source a small form-factor case and power supply, and load the computer’s components into it:


I also used a Logitech k400r keyboard and mouse for wireless input.

Install Debian and apps

Write the latest copy of Debian Stable to a CD or flash drive (this is version 8.3 at time of writing), and install it on the computer. Check “Debian Desktop environment” / GNOME during setup.

After installation, open a terminal, and type “su” to get root privileges.


Edit the software sources to include ‘contrib’ and ‘non-free’, as well as ‘jessie-backports’.

nano /etc/apt/sources.list
deb http://ftp.us.debian.org/debian/ jessie main contrib non-free
deb-src http://ftp.us.debian.org/debian/ jessie main contrib non-free

deb http://security.debian.org/ jessie/updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free

# jessie-updates, previously known as 'volatile'
deb http://ftp.us.debian.org/debian/ jessie-updates main contrib non-free
deb-src http://ftp.us.debian.org/debian/ jessie-updates main contrib non-free

# jessie-backports
deb http://ftp.us.debian.org/debian/ jessie-backports main contrib non-free
deb-src http://ftp.us.debian.org/debian/ jessie-backports main contrib non-free

Update sources and install Kodi:

apt-get install --install-suggests kodi

Also install the firmware packages that you may need.

apt-get install firmware-linux-free firmware-amd-graphics



sudo allows you to run commands as root from your regular user account. Install the package and add yourself to the sudo group:

apt-get install sudo
usermod -a -G sudo mike

To apply the change, log out and back in again. The rest of this guide assumes you are logged in as yourself, and will use sudo where necessary.

Auto-start Kodi

Open the tweak tool, and locate the list of startup programs.


Add Kodi to the list, log out, log in, and Kodi will launch automatically.


For a PC attached to a TV, user permissions are not so importnat, so set the user to log in automatically.

sudo nano /etc/gdm3/daemon.conf

Un-comment this block and enter your username:

# Enabling automatic login
#  AutomaticLoginEnable = true
#  AutomaticLogin = user1

Plymouth start-up screen

Install plymouth and configure grub to change the Debian boot sequence (a menu with timeout, followed by lots of text) into a graphical splash screen. This takes a bit of configuration.

sudo apt-get install plymouth

Set it up according to these instructions:

sudo nano /etc/initramfs-tools/modules

Set drm correctly for your chipset:

radeon modeset=1

Configure grub:

sudo nano /etc/default/grub

Update grub, set the theme in Plymouth:

sudo update-grub2
sudo /usr/sbin/plymouth-set-default-theme --list
sudo /usr/sbin/plymouth-set-default-theme joy

Run update-initramfs to apply the changes

sudo update-initramfs -u


Samba will let you share folders over your network. A basic folder with guest read/write is simple to set up:

sudo apt-get install nautilus-share samba libpam-smbpass winbind
sudo usermod -a -G sambashare mike

Log out, and back in to apply the group change, and then share the Public folder over the network by right-clicking on it and opening the “Sharing Options”:


Gnome will warn that the folder as shared if you open it:


Test the setup by typing smb://localhost into the address bar:


Overscan correction

In my case, I was able to set the TV to treat the input as a “PC” input. If that doesn’t work for you, then use xrandr in a login script:

Find the name of your input:

xrandr --query

Set underscan (get the horizontal and vertical values by trial and error):

xrandr --output HDMI-0 --set underscan on
xrandr --output HDMI-0 --set "underscan hborder" 32 --set "underscan vborder" 16

Kodi plugins

Add these as needed. The Australian catchup TV plugins repository from GitHub worked well.

Kodi RSS

The RSS feed shows Kodi updates by default, and is part of your user profile.


Edit the configuration file, and adjust the paths to your news sources of choice.


Boot speed

Readahead is the tool of choice for boot speed optimisation. Install it, and reboot.

sudo apt-get install readahead
sudo touch  /.readahead_collect
sudo reboot

Desktop Apps

If you quit Kodi, you are dropped back to the GNOME desktop. These apps are simply to improve the desktop user experience.

Google Chrome

Download the .deb file for Chrome from Google, install with dpkg, and then clean up dependencies:

dpkg -i google-chrome-stable_current_amd64.deb 
apt-get -f install


Download and extract the Firefox for Linux tarball from Mozilla.

Move it to /usr/share, and change the owner to match other applications there.

mv firefox /usr/share/
cd /usr/share/
ls -Ahl
chown root:root firefox
chown -R root:root firefox

Find the main menu editor, and add Firefox to the menu.


Firefox Web Browser



Test the new icon by searching:


Auto-clear browser profiles

Because you don’t need a password to log in to the user account, you can add this as a bit of insurance so that your box wont remember any passwords or sessions.

crontab -e

This job removes the Firefox and Chrome user profiles each boot.

@reboot rm --preserve-root -Rf --~/.config/google-chrome ~/.cache/google-chrome ~/.mozilla/firefox ~/.cache/mozilla/firefox


For file format support, best to have another media player:

sudo apt-get install vlc


You should now have a PC which boots into Kodi for media and TV, and lets you quit into a desktop to browse the web or run regular desktop apps.



On the 1GB RAM/ dual core workstation, the shortened the boot to around 45 seconds from BIOS handing over control, to Kodi being ready.

How to regenerate SSH client keys

Recently, a SSH client bug was discovered that could let the server read client private keys in some situations.

If you’re affected, then follow these steps. SSH regulars will be familiar with most of the commands used.

If you use keys

If you do use keys, you should regenerate them. Start by backing up your old key. Assuming it’s at the default location, just use-

$ mv ~/.ssh/id_rsa ~/.ssh/id_rsa.old
$ mv ~/.ssh/id_rsa.pub ~/.ssh/id_rsa.pub.old

Next, create or edit ~/.ssh/config, and add the following line. This disables the roaming feature, which was part of the reason:

UseRoaming no

Generate new keys-

$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/home/example/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/example/.ssh/id_rsa.
Your public key has been saved in /home/example/.ssh/id_rsa.pub.

Now copy the new key over, using the old keys. You would normally use ssh-copy-id, but it adds keys rather than replacing them, which is why I’ll do it manually-

scp -i ~/.ssh/id_rsa.old user@example.com:/home/user/id_rsa.new

SSH in with the old key:

ssh -i ~/.ssh/id_rsa.old

Replace all current authorized keys with the newly generated one:

mv -f id_rsa.new ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Logout, log back in with the new key to make sure it works, and you’re done.

If you don’t use keys

If you don’t use keys for login, now could be a good time to start. Public-key authentication provides much stronger protection from brute force attacks, and also prevents the need for the server to be sent your password each time you log in.

Create or edit ~/.ssh/config as above, and make sure it contains this line-

UseRoaming no

Generate a keypair and add your public key to the server-

ssh-copy-id user@example.com

Test it out-

ssh user@example.com

At his point, you should disable password-based authentication in OpenSSH server. If you don’t control the server, then just get a good random password for your account to prevent it being brute-orced:

openssl rand -base64 32
cat /dev/urandom | head -c32 | base64

Set it on your account:


Basic Cucumber feature testing

Cucumber is a Behaviour-Driven-Development (BDD) tool. You can use to automate the acceptance tests for your software systems. A real-world example of its use in a large application is the MediaWiki QA process.

This post will show you the steps to get it up-and-running to test a trivial app on a Unix (Mac, Linux) computer. I’ll assume that you already have Ruby installed.

First up, install Cucumber’s Ruby implementation:

$ sudo gem install cucumber
$ sudo gem install rspec

If you’re on Debian, you can also achieve this with apt-get:

$ sudo apt-get install ruby-cucumber-core ruby-rspec

The versions that I got from the install were-

$ ruby --version
ruby 2.2.3p173 (2015-08-18) [x86_64-linux-gnu]
$ cucumber --version

Make a “hello world” project:

$ mkdir cucumber-hello
$ cd cucumber-hello/

One of the under-celebrated features of Cucumber is the quality of its error messages. Simply attempt to run it and you will be told what to do next:

$ cucumber
No such file or directory - features. You can use `cucumber --init` to get started.

Go ahead and run cucumber --init as the program suggests:

$ cucumber --init
  create   features
  create   features/step_definitions
  create   features/support
  create   features/support/env.rb

This has set up your project. In the same vein as Test-Driven Development (TDD), the usual practice is to write the tests before you code.

Most programmers will be familiar with the expected output of a “Hello World” program. In Cucumber, this ‘feature’ would be represented in Cucumber as:

Feature: Test

  Scenario: Hello
    When I run the "hello-world" program
    Then I should see "Hello World"

Save this definition to features/hello.feature in the project directory and attempt to run Cucumber again:

$ cucumber
Feature: Test

  Scenario: Hello                        # features/hello.feature:3
    When I run the "hello-world" program # features/hello.feature:4
    Then I should see "Hello World"      # features/hello.feature:5

1 scenario (1 undefined)
2 steps (2 undefined)

You can implement step definitions for undefined steps with these snippets:

When(/^I run the "([^"]*)" program$/) do |arg1|
  pending # Write code here that turns the phrase above into concrete actions

Then(/^I should see "([^"]*)"$/) do |arg1|
  pending # Write code here that turns the phrase above into concrete actions

The output helpfully contains the skeleton code for writing the test steps in Ruby. Using this as a base, I implemented this using the rspec expectations syntax, to check if the string starts with “Hello World”.

When(/^I run the "([^"]*)" program$/) do |cmd|
  @value = `./#{cmd}`  

Then(/^I should see "([^"]*)"$/) do |val|
  expect(@value).to start_with(val)

Save these steps to features/step_definitions/hello_steps.rb

Finally, its time to code. Write up an implementation of “Hello World” in basically any available programming language, and save the output to an executable file called hello-world:

Using bash:

echo "Hello World"
$ chmod +x hello-world

Manually testing:

$ ./hello-world
Hello World

Automatically testing with Cucumber confirms that the test criteria are met:

$ cucumber
Feature: Test

  Scenario: Hello                        # features/hello.feature:3
    When I run the "hello-world" program # features/step_definitions/hello_steps.rb:1
    Then I should see "Hello World"      # features/step_definitions/hello_steps.rb:5

1 scenario (1 passed)
2 steps (2 passed)

Now that you’ve completed these steps, you should have this project structure:

$ find .

Next steps

Our scenario for the Hello World program has users interfacing with the system entirely with non-interactive shell commands. Cucumber needs to be able to observe the external behaviour of your application, so your steps will end up including some powerful test libraries. Some that are used often are:

How to arrange pages for printing and cutting in LaTeX

This post covers some LaTeX examples that I recently assembled for print-outs where multiple pages-per-sheet will be printed for cutting.

First up, an example file. This is a document filled with random text, on C6 paper.



\section*{Lorem Ipsum}

It renders like so (click for PDF):


1×1 arrangement

Using the crop package, you can wrap the output pages of your document in larger pages. Using the \includepdf macro, these pages can be sourced from our example document.

This example simply renders the document on larger pages, with crop marks displayed at the document edges.

% Sum of dimensions of the pages. We are displaying 1x1 C6 (114 mm x 162mm) pages, which is where 114x162 comes from.

% Include print/output paper size and orientation here, A4 portrait in this example (use 'landscape' option for landscape)


% Restrict page range, and set arrangement of pages per sheet here.


This renders a single C6 page on A4 like this (click image for PDF):


2×1 arrangement

To lay out two images side-by-side, we need to specify the size of the document we’re wrapping (which will be twice as wide as a single C6 page, and the height of a single C6 page), and also change the orientation of the outer paper to Landscape.

The LaTeX code is:

% Sum of dimensions of the pages. We are displaying 2x1 C6 (114 mm x 162mm) pages, which is where 228x162 comes from.

% Include print/output paper size and orientation here, A4 landscape in this example.


% Restrict page range, and set arrangement of pages per sheet here.


Which renders as (click for PDF):


2×2 arrangement

In a similar way, we can slot four portrait C6 pages on to a piece of A4 portait paper like so:

% Sum of dimensions of the pages. We are displaying 2x2 C6 (114 mm x 162mm) pages, which is where 228x324 comes from.

% Include print/output paper size and orientation here, A3 portrait in this example (use 'landscape' option for landscape)


% Restrict page range, and set arrangement of pages per sheet here.


This renders as:


More complex arrangement

Ok, so all of the above setups had one thing in common: 2 or fewer items on each side, meaning that the half-way axis lines could be used to show where each page ends.

If you are printing many small items, you might fit more than two in a direction, and need to add more axis lines so that you know where to cut!

Here is an example PDF which creates tiny name tags:

% Custom page size

% Macro for a name tag


% Make some name tags for a conference
% Names generated via www.generatedata.com/
\tag{Flynn Craig}{ExampleCorp}
\tag{Daniel Cash}{ExampleCorp}
\tag{Griffith Durham}{ExampleCorp}
\tag{Sean Washington}{ExampleCorp}
\tag{James Simon}{ExampleCorp}
\tag{Aidan Cotton}{ExampleCorp}
\tag{Wing Sanders}{ExampleCorp}
\tag{Dean Wilcox}{ExampleCorp}
\tag{Jerome Flynn}{FooCorp}
\tag{Leonard Steele}{FooCorp}
\tag{Zane Pratt}{FooCorp}
\tag{Andrew Hartman}{FooCorp}
\tag{Roth Mccullough}{FooCorp}
\tag{Fritz Taylor}{Quux Ltd}
\tag{Beau Bray}{Quux Ltd}
\tag{Duncan Hampton}{Quux Ltd}
\tag{Daquan Witt}{Quux Ltd}
\tag{Wylie Heath}{Quux Ltd}
\tag{Thaddeus Payne}{Quux Ltd}
\tag{Carson Ayala}{Quux Ltd}
\tag{Oleg Olson}{Quux Ltd}
\tag{Herrod Gillespie}{Bar University}
\tag{Jonas Wyatt}{Bar University}
\tag{Mannix Patrick}{Bar University}
\tag{Cain Ferguson}{Bar University}
\tag{Nasim Mendez}{Bar University}
\tag{Emery Bennett}{Bar University}
\tag{Oscar Bennett}{Bar University}
\tag{William Neal}{Bar University}
\tag{Dieter Cochran}{Bar University}
\tag{Bert Schultz}{Bar University}


The above example renders like this (click image for PDF):


Now, the trick is that crop is hard-coded to show axis lines only at the half-way points, so take a copy of crop.sty called crop-3x7.sty and find this block:


The block uses \vfill and \hfill to make even spaces.

Edit the file to include more axis lines, like so:

%% 'crop-3x7' is not a real package for general use, it is an example only!
%% It is a modified version of the 'crop' package, for rendering
%% additonal axis marks as cutting aids.
% Changed package name here-
\ProvidesPackage{crop-3x7}[2016/01/03 v2.0 crop marks 3x7 (mf)]
    % Changed from one axis on each side to 2 axes on top/lower edge, 6 on each side, for printing 3x7 panels per this example. 

Now simply prepare a page which shows a 3×7 grid of tags, using the same rules as before, and our modified crop-3x7.sty:

% This file demonstrates the use of a customisation to the 'crop' package to render additional axes for cutting up small name labels.

% Sum of dimensions of the pages. We are displaying 3x7 small tags (60 x 30 mm) to a page, which is where 180x210 comes from.

% Include print/output paper size and orientation here, A3 portrait in this example (use 'landscape' option for landscape)


% Restrict page range, and set arrangement of pages per sheet here.


Render the document, and see the small dashes on the sides which will show you where to cut:


The code

Full source for all of the linked files can be found in my tex-examples repository on GitHub.

How to print red/black on an impact receipt printer

I recently deployed an Epson TM-U220 impact receipt printer. These printers work by striking a ribbon onto the paper, like a type-writer. One of the up-sides to using these intead of a thermal printer is the ability to install a red/black ribbon in place of the default (black) one:



I connected up my printer using a USB-parallel cable, so my previous posts (Linux, Windows) apply for the connector setup.

Using the escpos-php driver on GitHub, a line of red text is printed like this:

 * Example of two-color printing, tested on an epson TM-U220 with two-color ribbon installed.
require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("php://stdout");
$printer = new Printer($connector);

try {
    $printer = new Escpos($connector);
    $printer -> text("Hello World!\n");
    $printer -> setColor(Printer::COLOR_2);
    $printer -> text("Red?!\n");
    $printer -> setColor(Printer::COLOR_1);
    $printer -> text("Default color again?!\n");
    $printer -> cut();
} finally {
    /* Always close the printer! */
    $printer -> close();

With this result:


How to connect a USB receipt printer up on Mac OS X

This post will show you how to set up a USB receipt printer on Max OS X. These steps were written on Yosemite, but should work on 10.6 onwards (ie, also Snow Leopard through to El Capitan).

This is another post in a series, which has so far covered direct USB printing on Windows and Linux. The printer tested here is this Epson TM-T20:


CUPS is the printing system that’s used on Mac, but most users would be more familiar with the system print dialog:


In our case, we need to set up the printer via the CUPS web interface. This is accessed via a web browser at this address:


At first, you will get knocked back:


To fix this up, open up Applications → Utilities → Terminal and type in:

cupsctl WebInterface=yes

You can then reload the browser and click through to Administration:


Click Add Printer and log in:



Select the USB printer from the list, and optionally share it:



Click Select Another Make/Manufacturer, and select Raw → Raw Queue:




Use the defaults for the other options:


Test print

Type some junk into a file called foo.txt and attempt to print it, using the CUPS printer name:

nano foo.txt
lpr -o raw -H localhost -P EPSON_TM-T20 foo.txt

The prints will be delayed for a few moments, as CUPS spools the jobs.

Disable CUPS web

Once you’re done, for security reasons you should reset this option from before, to disable the web interface to CUPS:

cupsctl WebInterface=no

How to set up sudo on Debian GNU/Linux

If you just installed Debian, you might notice that one Linux staple, sudo is not installed by default. Here is the quick way to add it, and set yourself up as an administrative user.

1. Install sudo, using the su command to elevate privileges.

bob$ su
root# apt-get install sudo

2. Make yourself an administrator. The default /etc/sudoers file contains this line:

# Allow members of group sudo to execute any command

So simply add your account (‘bob‘ in this example) to the sudo group:

root# usermod -a -G sudo bob

3. Log out and back in again, in order to apply changes to your group membership.

bob$ groups
bob cdrom floppy sudo audio dip video plugdev netdev lpadmin scanner bluetooth
bob$ sudo echo test
[sudo] password for bob: 

Fix merge conflicts in git with Meld

When you’re writing code collaboratively, there’s plenty of situations when you need to combine two sets of changes.

This could happen, for example, if Bob and yourself both fix different bugs by making edits to the same file.


This post assumes that your source code is tracked in git.

First up, install meld. The Meld homepage has instructions for other platforms, but on Debian/Ubuntu, it’s just:

sudo apt-get install meld

Now tell git to use it as a tool:

git config --global merge.tool meld

Once you have a merge conflict, you can then fire up Meld like this:

git mergetool

For each file, you will get a 3-way diff. Click the arrows on the sides to move the code you want into the middle:


Once you’ve saved the file and closed Meld, you will be prompted on the command-line. You just tell it whether you’ve successfully merged the file, until it stops giving you new files to merge.

After this, commit the changes:

git commit


Simpler usage

If you don’t use git, you can simply call Meld from the command-line as well. This shows you differences between files in a similar window, and lets you move blocks of code around as well:

meld foo.c bar.c