Configuring Git for font projects: repository structure

As I’m fond of mentioning at every opportunity, my twin passions are web development and typeface design. It was curious though that until recently, for me, I never considered combining the two disciplines. Fonts are pieces of software after all.

Software engineers are typically familiar with the following concepts:

  • Source control. A source control system such as Git can be used to track and manage a complete history of changes to your project.
  • Writing tests. A developer may write a suite of tests to ensure that a piece of software behaves as intended. This is especially useful to ensure that, when new functionality is added to a project, it does not break existing behaviour.
  • Continuous Integration/Continuous Deployment (or CI/CD). A mechanism for deploying changes immediately to a production environment.

Is it possible to adopt software development practices such as these to typeface design? Absolutely yes! In this post we’ll start by adopting a source control system before (hopefully) discussing other concepts in future posts.

Source control

The benefits of using Git as a source control system have been discussed numerous times elsewhere. So, instead of repeating all of that, I suggest you have a read of Git for Type Designers, which is a few years old now but still broadly relevant. I’ll be referring to this page at various points throughout this post.

I won’t go through the whole step-by-step process of creating a repository from scratch, as I’m sure you’re all busy people. Instead, I’ve already created an example repository for one of my old and cringeworthy open-source fonts from 2005 and will take you through some of the decisions I’ve made when setting up the structure of the repository. They may be incorrect though – I’m just trying to work this stuff out! Also your use cases may differ, in which case hopefully I’ve given you enough information for you to make your own decisions.

Firstly I’ve chosen GitHub to host a remote copy of this repository. Since Git for Type Designers was written, GitHub was acquired by Microsoft and now allows unlimited private repositories with up to three collaborators for free. So, GitHub it is.

The second thing to note is that using Git on the command line can be a little daunting and – developer confession! – I tend to use a GUI instead. My tool of choice is SourceTree from Atlassian, which is available on Windows and macOS. Other tools are available though.

File structure

Next: how should we structure our project – which folders do we need? Fortunately that decision has already (pretty much) been made for you. Unified Font Repository is a sample font project structure which lets you organise your files into areas for sources, fonts and associated documentation. It’s nice to have a convention for this sort of thing as it saves having to relearn different folder structures for different projects.

Others have extended the Unified Font Repository and it’s worth checking them out. If you’re thinking of releasing your font through Google Fonts then the Google Fonts version is the way to go. I’m not going to do that though, so instead I’ve plumped for this extended version from David Jonathan Ross. The README describes the folders nicely, so I recommend you go over there and have a look.

File format

The next decision: what source file format(s) should we be storing? Let’s once again turn to the Git for Type Designers page for advice. Here it recommends using the UFO file format. Which is a pretty good recommendation to be fair. However using this as your sole font format means you may lose font editor-specific data.

Why is this? I’m going to discuss FontLab here as that’s the editor I predominantly use, but this may be true of other editors. In the FontLab documentation on file formats:

FontLab offers two native file formats for saving: VFC (binary) and VFJ (JSON based). Both can keep all elements used in the font design process. Saving in any other format is actually an export and is likely to lose some elements such as glyph notes, pins, element references, etc. VFC is faster, but VFJ is human-readable.

An aside here: these two new font formats have been introduced since Git for Type Designers was written. FontLab’s .vfj font format is human-readable and is indeed capable of being ‘diffed’ (i.e. Git is capable of displaying what changes have been made to your file)

We could solely use FontLab’s .vfj file format. However I’m not going to. The .vfj file is large and it can be quite slow for source control tools to display the diffed results in a GUI.

So, my recommendation is to store fonts in both .ufo AND a native file format (.vfc, .glyphs). You get the twin benefits of:

  • easily navigating the changes to your font in the source control GUI of your choice by looking through the .ufo folder
  • not losing any font editor-specific data

The only downside is that, when saving your .vfc file in FontLab, you have to remember to export your source files as a UFO at the same time. It’s a pain, but a trade-off I’m willing to make at the moment. Maybe it’s possible to do this as a Python script – I haven’t really worked that bit out yet. Hey ho.

Saving your font in UFO format means that it is easy to navigate changes in a Git GUI tool such as SourceTree

Output fonts

Our source files are all stored nicely in our repository and we can easily see updates. But what about our final exported fonts? We need .otfs, .ttfs and web fonts too. We could just export all the file formats we need in our font editor and commit them along with our source files. But that’s a very laborious thing to do manually. Moreover, we’re just bulking up our repository with redundant information.We have all the info we need to generate our output fonts in our source files – so why bother committing them too? Here comes a potentially controversial decision – I’m not going to store output fonts directly in the repository. Instead we’re going to use Python scripts to build our fonts, and we’ll do that in Part 2, coming soon.