In software, simplicity is the key to good design. Users don’t need to struggle with complexity; they want tools that help them work, not get in the way. But tools like dbt Cloud, which should make data transformation easier, do the opposite. Instead of a simple process, they wrap users in layers of Git integration, adding confusion where there should be none.
Git as a Misstep
The problem comes from relying too much on Git. What should be a straightforward task—managing data transformations—becomes a maze of branches, commits, and merges. It’s like needing to fill out paperwork to make a note:
What it should be like.
What it is instead…
git checkout -b update-transform
# Change some files...
git add .
git commit -m "Saving changes to my SQL transform"
git push origin update-transform
For data analysts, this makes no sense. They don’t need to know Git to do their work. Yes, they might need versioning
of some form, but they don’t need Git. This added step makes a simple task needlessly difficult.
Power at a Price
Advocates of Git say it adds control. But is that control worth it? Do data analysts really need to rebase or cherry-pick when they’re transforming data?
Here’s a comparison of rolling back changes:
What it should be like.
What it is instead…
git checkout prev_commit_hash
git rebase -i HEAD~2
This adds complexity without any real benefit. It’s like saving a google doc by creating a new branch every time—no one would call that an improvement.
Git as a Database: A Bigger Problem
This overuse of Git doesn’t stop with version control. It’s a symptom of a deeper issue: using Git as a database. Instead of using a real database like Postgres, some tools misuse Git to store and track changes. For example, a database can easily track schema changes with a proper data model that makes it as easy as:
UPDATE schema_versions SET current_version = 'v1.2.3' WHERE table = 'data_transform';
However tools like dbt Cloud choose Git, making it harder than it needs to be. Then they recruit their users to suffer
with them through the pain of git double-dutch, all so that the server admins don’t have to maintain a runtime
database. This creates unnecessary steps for users who just want to manage data, not version control systems. Advocates
always proclaim how it’s so wonderful that users can use Git to revert bad changes, yet I challenge you to look back
at the lengthy commit history of any of these repos–good luck finding a single revert commit. What do users do when
they make a change that causes a regression? They just make another change that fixes the regression. In these systems
that predictably abuse Git in this way, the changes are always linear. It is no different from a user making some accidental clicks
in a UI and then making a few more clicks to fix the damage. Well it is different in that it’s a huge time sink.
Spinnaker: Another Example
Spinnaker, a continuous delivery tool, falls into the same trap. It uses Git to manage deployment pipelines, forcing users to navigate the same version control complexities. What should be a simple pipeline update becomes a Git workflow nightmare. When you go to the Getting Started page, the sections, in order, are as follows:
- Intro
- Background
- Prerequisites
- Save Your Resource In Your Git Repository.
(🤯 I’m not kidding, this is the actual title of the 4th section of the getting started page)
The section then starts off with an example of the file you need to commit that I could only guess would
be named why.yml…
name: a-manifest-name
application: yourapp
artifacts: []
environments:
- name: testing
constraints: []
notifications: []
resources: # you can add more resources here, this is a list
- apiVersion: ec2.spinnaker.netflix.com/v1
kind: security-group
# ... the other info here from the security group you just exported
Why does managing deployment pipelines require the hassle of Git? A simpler, state-based system would work better without forcing
users to wade through Git commands. Spinnaker is an awesome and powerful continuous delivery platform. However, like
dbt Cloud, Spinnaker forces users to deal with problems that don’t need to exist.
Clunky, Git-Backed UIs
All of this leads to the same result: clunky UIs. These tools, which should help users work faster, slow them down. Every click, every action is tied to a version control system that adds nothing of value unless you value frustration.
Instead of focusing on the task at hand, users must think about branches, commits, and merges. The UI isn’t there to help them do their job—it’s just a pretty wrapper over Git. Users aren’t dealing with their actual task; they’re wrestling with a version control tool they don’t need.
The Case for Simplicity
The solution is simple: go back to basics. This isn’t a new idea—it’s a return to what works. The traditional architecture of a service, a database, and a UI has been the foundation of good software for many years. It’s reliable, effective, and does the job without needless complexity.
We should have more confidence than ever in this traditional approach. Technologies like Git, built for version control of software, should remain in their lane. They can be useful additions to a project, but they shouldn’t replace the core pieces of architecture.
In rare cases, adding new technologies makes sense—but only as enhancements. Git-backed UIs that replace traditional components with Git for the sake of complexity do more harm than good. They create a maze of unnecessary steps and block users from focusing on their work.
Good design is about simplicity. Stick to the fundamentals: a service, a database, and a UI. Git-backed UIs are a lesson in what happens when we forget that. I have a feeling that the radical transformation of software design that we all sense is arriving will be an extension of these core principles, not a replacement of them.
So the next time you see this guy trying to convince you to use Git as your application database…
…maybe you should send him this post.
-Sam