Testing Git Outside Source – Thank You Temp Directories!

  • infoFull Post Details
    info_outlineClick for Full Post Details
    Date Posted:
    Aug. 19, 2020
    Last Updated:
    Aug. 19, 2020
  • classTags
    classClick for Tags

The Problem

I use Git on a daily basis, as my default version control system and integration with Github. I also am acquainted with writing tests, and how to integrate those with Git – e.g., which test files should be gitignore’d vs tracked. However, I just encountered a new wrinkle, which is how to deal with tests that rely on Git itself, or rather, the absence of Git. This pretty much only comes up when building tools for the developer toolchain / devops, but that is exactly what I’m doing at the moment.

I’ve actually previously created a Git based tool and test suites for it; however, those tests used the easy trick of nested git repositories. If you have project which is a git project, and you create project/git-test and then run git init inside git-test, you end up with a separate git repository inside your actual source code’s one, complete with separate tracking (there are issues however, if you forget to gitignore the child repository).

The complication is when you need to test your tool against a directory that is not part of a git-initialized repository. For example, if your test makes sure that your code throws the appropriate error when ran against a non-git project, where git log will fail with fatal: not a git repository, you need such a directory to exist to test against. Where do you create that test directory?

  • If you create it inside your source code, like src/__tests__/tmp, it will inherit the git tracking of src.
  • If you try to go up a level from your source code (e.g. src/../tmp) and create it there, you can’t be sure that won’t lead to a directory collision, or that your code hasn’t ended up nested in another git repository.
  • Creating it at the highest level (e.g. /) seems like a bad idea, and one might argue it doesn’t respect the User’s filesystem

The Solution: OS Designated Temporary Paths

I found the solution to this issue in two places, at roughly the same time. The first place was in checking out how an existing tool, gitchangelog, creates temporary directories with Python, and the second place was in the NodeJS fs docs, when I was trying to look up some methods.

If you are more seasoned with {{devops, IT sysadmin, etc.}} than I am, you might have already identified the solution long ago; OS temporary directories.

Essentially, over time a standard practice has emerged for operating systems to expose a temporary directory, which is periodically cleaned, and guaranteed to exist on boot.

Standard Library Wrappers and Implementations

Using temporary directories is such a common practice that many “standard libraries” have methods built-in to get the OS temp dir path, as well as create temporary folders directly.

Here are some examples:

  • NodeJS
  • Python – tempfile (docs)
  • QT5
    • QDir::tempPath() to get system temp dir (docs)
    • QTemporaryDir to make temporary directory (docs)

Note that using temporary directories goes beyond just finding the right directory; the sub-directories that you create also need to have unique names that won’t collide – many of the methods above automatically do this for you.

Usage Considerations

Using temporary directories comes with some important caveats, the most important being that your data is unlikely to be persisted for very long. Some OSes will periodically clear temporary storage, or do so on events like reboots, or users might even choose to manually clear their own temporary folder when their HDD is nearing capacity.

For my use-case, creating a non-git-initialized directory with a few files for testing, this is perfect. In fact, best practice would be to clear / remove this test directory after each run, so the fact that it might not be persisted past a reboot is a moot concern anyways.

Leave a Reply

Your email address will not be published. Required fields are marked *