After retiring 15 years ago from professional software development, I had a clear picture of what source control should provide for a commercial development team:
- Prevention of simultaneous edits – avoiding the chaos when two developers unknowingly work on identical code
- Real-time visibility into who’s currently working on what files
- Version metadata embedded in code files – a lifesaver when you find a piece of code and need to know what version it is
- A comprehensive audit trail showing who modified which files and when
- Automatic version incrementing for every modification
- A single authoritative codebase representing the current production state
- The ability to roll back to any previous version
When a business opportunity pulled me out of retirement and back into managing a development team, I naturally asked about source control. The universal response? “We use Git.”
The Git Philosophy Problem
I spent time studying Git, and what I discovered surprised me. Git is technically capable – it has excellent audit trails, tracks who changed what, maintains complete history, and handles rollbacks beautifully. The problem isn’t what Git can do – it’s what Git’s design philosophy encourages you to do.
Git is built on a distributed, merge-first workflow. Every developer has their own complete repository. Nothing prevents multiple people from simultaneously modifying the same file – in fact, the system expects this. You only discover conflicts when someone pushes their changes, sometimes days or weeks after starting work. Git’s response? Attempt to automatically merge the conflicting versions, or flag them for manual resolution.
This is fundamentally different from a lock-based workflow where conflicts are prevented upfront rather than resolved after the fact.
The Merge Problem
Here’s where I’m genuinely skeptical: Git’s automatic merging works fine when two developers change different lines in the same file. Git detects overlapping line changes and forces manual resolution. So far, so good.
But what happens when two developers independently address the same problem in different ways?
In a badly run project (and let’s be honest, not every project is well-managed), nothing stops Developer A and Developer B from both implementing the same feature or fixing the same bug. They work in different files, or different sections of the same files. Git happily merges everything because there are no line-level conflicts.
The code compiles. The merge succeeds. But now you have two different solutions to the same problem sitting in your codebase, possibly contradicting each other in subtle ways. The code might work – or it might fail in ways that won’t become apparent until production.
SVN’s locking model, when properly used, surfaces this problem immediately: “Why is Sarah working on the authentication module when you’re working on authentication?” It forces the conversation upfront rather than leaving you to discover the problem in code review – if you catch it at all.
Version Metadata: The Missing Piece
Here’s something Git fundamentally doesn’t do well: embedding version information directly in your source files.
With SVN, you can add keywords like $Revision$, $Author$, or $Date$ as comments in your code. SVN automatically expands these when files are committed. When you’re debugging a production issue and looking at a piece of code, you can immediately see: “This is revision 2847, modified by John Smith on March 15th.”
This is invaluable when you find code in production and need to know what version it is without checking the repository. It’s especially crucial when debugging issues where someone asks, “Is this the latest version of this module?” and you can answer immediately by looking at the file itself.
Git deliberately doesn’t support this. The Git philosophy is that files should be identical across repositories, and embedding version metadata would make them different. That’s philosophically pure but practically problematic.
Why This Happened
Git was designed for the Linux kernel – a massive open-source project with hundreds of contributors scattered globally. For that use case, the distributed model makes perfect sense. You don’t want a developer in Mongolia inadvertently blocking progress because they locked a file and went offline for days.
But that design rationale doesn’t translate to typical commercial projects: co-located teams of 5-50 developers, working regular hours, under active project management.
Yet Git became “industry standard” – not because it fits most teams’ needs, but because it’s what the Linux kernel uses and what GitHub popularized. I’ve watched this pattern before: a tool designed for one specialized context becomes trendy and gets adopted universally, creating unnecessary complexity for teams who’d be better served with something simpler.
The Case for SVN
Subversion represents decades of evolution in centralized version control. Its workflow is simpler for managed teams:
Prevention over resolution: With file locking, you prevent conflicts before they happen. Developers can see at checkout if someone’s already working on a file. More importantly, it forces communication: “Why are we both working on authentication?”
Single source of truth: The central repository is the authoritative version. No confusion about which developer’s fork has the “real” current state.
Version metadata in files: Using keyword expansion, every file can carry its own version information as comments, making debugging and verification straightforward.
Straightforward workflows: Check out, edit, commit. No need to understand distributed repositories, rebasing, or complex merge strategies.
Better visibility: Project managers can see who’s working on what in real-time, not just what’s been pushed.
I’m not arguing Git is technically inferior – it’s clearly powerful. I’m arguing it’s operationally overcomplicated for most teams, and its “clever” merging can mask problems that should be caught through communication rather than code review.
What About Git’s Advantages?
Git advocates will point to legitimate strengths:
- Better branching and merging capabilities
- Complete offline work capability
- Superior performance on huge repositories
- Better support for complex open-source workflows
These matter for certain projects. If you’re coordinating thousands of contributors across time zones, or if network connectivity is unreliable, Git’s distributed nature is invaluable.
But for a typical business software project? A team of 10-30 developers, working in the same building or time zone, with reliable network access and active project management? SVN’s simpler, centralized model is often the better fit.
The Bottom Line
Git isn’t wrong – it’s overused. The software industry adopted it because it’s what the cool kids use, not because every project is the Linux kernel.
If you’re managing the Linux kernel or coordinating thousands of open-source contributors, Git makes sense.
But for conventional business software projects with dedicated teams working under coordinated management? SVN remains the more sensible choice. It matches your workflow, it’s simpler to understand, it embeds version information where you need it, and it prevents problems rather than asking you to resolve them later.
Sometimes “old-fashioned” isn’t a criticism – it’s a description of something that’s been refined over decades to work well for the majority of real-world situations.
Choose your tools based on your actual needs and team structure, not on industry fashion.
Leave a comment