Turning every repo into a playground with global .gitignore
The main motivation for this blog post was to share an interesting way that I often use to play with code. Often times I want to write a few simple scripts/programs to help figure out how a certain function or library works, but these files shouldn't end up in my pull requests or commit.
For example, when dealing with implementing container networking in Go, I want to test and play with various functions outside of actually running the full project. Ideally, this could be done with unit tests, but some things are easier to test with unit tests than others (and creating custom network configuration is not easily testible -- at least not without a bigger investment into test infrastructure than I'm willing to make!).
Go is famously a compiled language with no real REPL, so my solution is to
create files in an ignored
.untracked directory (which is added to
~/.gitignore). For example, I might have
as a simple wrapper "script" that calls the function with various arguments.
Some things go beyond one-off scripts as well! In my
$DAYJOB, I work on a
Python codebase. Python does have a REPL, which is really great for poking
around! But I also don't want to have to run the same sets of imports and setup
code at the start of every REPL session. Instead, I add all those imports and
setup code to a
.untracked/repl.py file and run from the command line with
python3 -i .untracked/repl.py (the
-i option says to execute the script then
start an interactive session).
For example, my
$DAYJOB script looks something like this:
# repl.py # Import main first since Flask requires weird things with circular imports # that break if main isn't the first thing imported import main from models imports * from app import db, mylib, ... db = db.connect("postgres://...") me = User.load(db, id=1) widget = Widget.load(db, id=123)
It's pretty easy to use at the command line and saves me a lot of typing.
# python3 -i .untracked/repl.py mylib.do_something(user=me, widget=widget)
There's two steps!
First, create your
~/.gitignore file (you can copy mine from below!).
Second, tell Git to use this file:
git config --global core.excludesfile ~/.gitignore
This will add a section to your Git configuration file at
[core] excludesfile = ~/.gitignore
What about your .gitignore, Travis?
Here it is!
.DS_Store .idea/ .vscode/ .venv *.swp .envrc untracked/ .untracked/
Nothing terribly interesting there, but a few notes:
- I exclude many IDE files (such as
.vscode) so that I don't have to deal with manually excluding them or adding them to each individual repository's
- I use direnv to manage environment variables across projects (e.g., determining the Kubernetes context depending on which project I'm currently in or automatically activating a Python virtual environment). It's super cool and more people should check it out.
.venvdirectory is where I initialize project-specific virtual environments for Python projects if I need to (+ direnv to auto-activate them!).
untrackeddirectories. I prefer to use
.untrackedbut some things don't work with hidden directories (such as Python imports).