Running Emacs from a Windows Explorer context menu

It’s one of those days, thanks to a hard disk going south I ended up having to rebuild the system drive on one of my machines. After putting the important software back on there – “Outlook and Emacs”, as one of my colleagues calls it – I had to reapply some of the usual tweaks that make a generic developer workstation my developer workstation.

One of the changes I wanted to make was to have an “Edit in Emacs” type context menu in Windows Explorer. The only reason I was keeping another editor around was because it’s a feature I use regularly but hadn’t got around to setting up for Emacs.

StackOverflow to the rescue, as usual. I used the registry script provided in the first answer and tweaked it slightly. In contrast to a lot of people, I don’t keep Emacs running all the time but only when I’m editing something. For that reason like my Emacs setups to either start a new instance if there is no Emacs running or use an existing instance as a server if there happens to be one running.

With my little tweaks to start an instance of Emacs even if there is no Emacs server running, this is what the updated registry script looks like:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT*shell]
[HKEY_CLASSES_ROOT*shellopenwemacs]
@="&Edit with Emacs"
[HKEY_CLASSES_ROOT*shellopenwemacscommand]
@="C:\Tools\emacs\bin\emacsclientw.exe -a C:\Tools\emacs\bin\runemacs.exe -n "%1""
[HKEY_CLASSES_ROOTDirectoryshellopenwemacs]
@="Edit &with Emacs"
[HKEY_CLASSES_ROOTDirectoryshellopenwemacscommand]
@="C:\Tools\emacs\bin\emacsclientw.exe -a C:\Tools\emacs\bin\runemacs.exe -n "%1""

There’s another neat little tweak in there, too – the directory “C:toolsemacs is actually a symbolic link to the current installed version of Emacs on this machine so whenever I update my version of Emacs, I don’t have to redo other scripts and settings that try to use the current version of Emacs.

This might be an old hat to most Unixheads, but it’s slightly unusual on Windows so I figured I’ll mention that it’s possible to do something like this on Windows also.

Improving the performance of Git for Windows

Admittedly I’m  not the biggest fan of git – I prefer Mercurial – but we’re using it at work and it does a good job as a DVCS. However, we’re mostly a Windows shop and the out of the box performance of Git for Windows is anything but stellar when you are using ssh as the transport for git. That’s not too much bother with most of our repos but we have a couple of fairly big ones and clone performance with those matters.

I finally got fed up with the performance after noticing that cloning a large repository from the Linux git server to a FreeBSD box was over an order of magnitude faster than cloning the same repository onto a Windows machine. So I decided to start digging around for a solution.

The clone performance left a lot to be desired using either PuTTY or the bundled OpenSSH as the SSH client. I finally settled on using OpenSSH as I find it easier to deal with multiple keys. Well, it might just be easier if you’re a Unixhead.

My search led me to this discussion, which implies that the problem lies with the version of OpenSSH and OpenSSL that comes prepackaged with Git for Windows. The version is rather out of date. Now, I had come across this discussion before and as a result attempt to build my own SSH binary that included the high performance ssh patches, but even after I got those to build using cygwin, I never managed to actually get it to work with Git for Windows. Turns out I was missing a crucial detail. It looks like the Git for Windows binaries ignore the PATH variable when they look for their OpenSSH binaries and just look in their local directory. After re-reading the above discussion, it turned out that the easiest way to get Git for Windows to recognise the new ssh binaries is to simply overwrite the ones that are bundled with the Git for Windows installer.

*** Bad hack alert ***

The simple recipe to improve the Git performance on Windows when using a git+ssh server is thus:

  • Install Git for Windows and configure it to use OpenSSH
  • Install the latest MinGW system. You only need the base system and their OpenSSH binaries. The OpenSSH and OpenSSL binaries that come with this installation are much newer than the ones you get with the Git for Windows installer.
  • Copy the new SSH binaries into your git installation directory. You will need to have local administrator rights for this as the binaries reside under Program Files (or “Program Files (x86)” if you’re on a 64 bit OS). The binaries you need to copy are msys-crypto-1.0.0.dll, msys-ssl-1.0.0.dll, ssh-add.exe, ssh-agent.exe, ssh-keygen.exe, ssh-keyscan.exe and ssh.exe

After the above modifications, the clone performance on my Windows machine went from 1.5MB/s – 2.5MB/s to 10MB/s-28MB/s depending on which part of the repository it was processing. That’s obviously a major speedup for cloning, but another nice side effect is that this change will result in noticeable performance improvements for pretty much all operations that involve a remote git repository. They all feel much snappier.