Merge subdirectory from another git repository

Let’s say I have two repositories: cvhci-standards and labeltracks.




I’d like to merge the content of subdirectory python from cvhci-standards into labelstracks/utilities/cvhcistandards. To do this, we use git read-tree, with the following steps:

1. Add remote repository and fetch it:

git remote add -f cvhci-standards git://

2. Merge, but don’t commit just yet:

git merge -s ours --no-commit cvhci-standards/master

3. Read a specific subdirectory from cvhci-standards. We specify the the target subdirectory as prefix, and the source-subdirectory (python) after the colon in the tree-ish repository description.

git read-tree --prefix=utilities/cvhcistandards/ -u cvhci-standards/master:python

4. Commit

git commit -m 'merging in cvhci-standards python module'

5. Pull from cvhci-standards to update the subtree.

git pull -s subtree -X subtree=utilities/cvhcistandards cvhci-standards master

We need to specify the subdirectory to merge to, otherwise git can’t match the subtrees correctly.

Sort strings with numbers naturally with GNU sort

Say you have a list of filenames or identifiers with numbers, e.g.



and you want to sort them “naturally”, e.g. unknown_E1_2 should come before unknown_E1_10. If you would just sort them as strings (character by character), 10 would come before 2, because the character ‘1’ comes before ‘2’, and the trailing ‘0’ just doesn’t matter for the sort order anymore.

sort from the GNU coreutils let’s you do this easily with the -V switch. Note that this not only works for numbers at the end of a string, but also for the numbers in the middle:

# sort -V unknowns.txt

See Ned Batchfelder’s blog post on how to do this in Python. Especially check out Toothy’s comment for a brief solution.

Git: make existing branch track remote branch

If you have an existing branch, say master, that was not cloned from a remote repository, a git pull without further arguments will give you the following error message:

You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull ').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:
[branch "master"]
remote =
merge =

[remote ""]
url =
fetch =

See git-config(1) for details.

Editing .git/config by hand is cumbersome, and I never can remember what the “syntax” for is.

As of git 1.7.0, it is now really easy to set this up:

git branch --set-upstream master origin/master

which will put the following into your .git/config

[branch "master"]
remote = origin
merge = refs/heads/master

Now you can git pull and the remote changes in origin/master will be automatically merged into your local master branch.

Base64 decode on the command line

There are several options to decode a base64-encoded file on the command line, or vice-versa, encode some text to base64. base64 is probably the easiest command to use and easiest to remember, however, it might not be available on every system. In that case the other two options are viable alternatives.


(install with sudo apt-get install coreutils)

Encode/Decode: base64 [-d / -e] infile outfile

Use -d for decode.
Use -e for encode.
Both infile and output can be ‘-‘, meaning that the input will be read from stdin, and/or the output will be written to stdout, respectively.

perl one-liner (found here)

(install with sudo apt-get install perl)

Encode: perl -MMIME::Base64 -ne 'print encode_base64($_)' < infile > outfile
Decode: perl -MMIME::Base64 -ne 'print decode_base64($_)' < infile > outfile


(install with sudo apt-get install openssl)

Encode: openssl enc -base64 -in infile -out outfile
Decode: openssl enc -d -base64 -in infile -out outfile

Add directory hierarchy to PATH, or: addpath(genpath()) in bash

It’s actually pretty simple. Say you want to add all folders below you $HOME/bin to PATH, all you need is the following:

PATH=$(find $HOME/bin -type d | tr "\\n" ":")$PATH

The find $HOME/bin -type d returns a list of all folders below $HOME/bin. The tr "\\n" ":" replace the newlines in the find-result with colons.

How to bring back missing systray icons in Ubuntu/Unity

Ubuntu/Unity does not display any systray (notification area) icons anymore for a while now.  The reasoning behind this is, that not all systray icons behave(d) in a consistent way, therefore limiting the user experience [1].  The goal is to port all systray icons to “indicators”, but unfortunately this just has not happened yet for many popular applications, e.g. xchat.

Nevertheless, the systray is still there, and there is a whitelist which contains a list of all applications (e.g. Skype) that are still allowed to use it.

In order whitelist YOUR_APP, run the following commands (change YOUR_APP to your application)

wlold=$(gsettings get com.canonical.Unity.Panel systray-whitelist)
wlnew=$(python -c "print list(set($wlold + ['YOUR_APP']))")
gsettings set com.canonical.Unity.Panel systray-whitelist "$wlnew"

or, to whitelist all applications:

gsettings set com.canonical.Unity.Panel systray-whitelist "['all']"

You might need to log out and log back in in order for the changes to take effect.


python install with custom build directory

A custom build directory (e.g. --build-base=/tmp/foo) can only be specified for the build command, not the install command. However, build and install can be easily combined in one call:

python build -b /tmp/foo install