Build Docker Images in a Git Repo but Only Committed Changes

Git worktrees are an excellent feature for doing this in a way without needing to stash your changes.
Here’s the scenario:
- You have code in a git repo somewhere
- You want to build a Docker image, potentially to deploy
- You don’t want to include uncommitted or untracked files
I had this use case come up recently where a client was building and pushing releases from his machine to a container registry but he only wanted to deploy the latest committed code.
You could technically do git stash or even git stash --all if you want to
include everything (tracked, untracked, ignored) but stashing always makes me
uneasy since you can accidentally overwrite it if you’ve forgotten about it.
Instead we can take advantage of a git feature called worktrees.
Here’s a couple of commands putting everything together that you can apply to your set up:
# Create the new worktree for this build. Your git tree will be copied to this directory.
# We're using --detach because the new directory won't be associated with any branch.
git worktree add --detach /tmp/yay
# Ignored files such as .env files won't be included so let's add it.
cp .env /tmp/yay
# Instead of cd'ing into /tmp/yay we can just run docker compose by passing in
# the worktree path we chose before. You can run anything you want here, but
# this is a popular example for building Docker images!
docker compose --file /tmp/yay/compose.yaml --project-directory /tmp/yay build
# When we're done, we can delete the worktree path.
git worktree remove --force /tmp/yay
It’s beneficial to use git worktree remove instead of rm -rf /tmp/yay
because the worktree remove command will remove the entry from .git/worktrees
too since that gets created when you add worktrees.
The video below demos doing everything.
# Demo Video
Timestamps
- 0:34 – Using git stash
- 1:54 – Stash makes me uneasy sometimes
- 2:15 – Creating a git worktree instead
- 3:40 – Copy over an ignored .env file
- 4:06 – Build an image from a different directory
- 4:55 – Confirming only the latest commit was built
- 5:17 – Deleting the worktree we created
When was the last time you used git worktrees? Let me know below.