Git is the most popular source
control system in wide usage today, hands down. It’s also the
unfriendliest source control system in use these days, hands down.
TFS and Azure DevOps have adopted Git as their default source control provider, and teams that previously had no experience with Git are now working with it, even though their previous default source control provider (TFVC or SVN) was a completely different animal.
Put those ingredients together, mix in a
little frustration and merge conflicts, and you have $20,000 lost in
productivity without realizing it, within in the first few months.
A cross-functional enterprise software team
recently moved to TFS 2018, and along with it Git as their source
control provider. The team was used to having long-lived individual
branches for feature work, and they continued this practice with git.
Within a few weeks, however, they started
to notice problems: changes that were previously in “master” (the
default name for the centralized branch in git) were being merged out.
As the team ramped up its feature delivery, this happened more and
more. At first, they would reach out to the affected developer and ask
them why their feature (that they thought was merged in) wasn’t in the
delivered software. This kept happening.
Finally, one of the newer developers that
it happened to asked other members of the team: What’s your branching
strategy? “We have our own named branches that we use and we use the
same branch for every feature” was the reply.
Ah ha! thought the new developer, that’s where the problem is. She proceeded to sit down with other members of the team and show them the problem. Git, you see, makes branches very lightweight — they’re effectively a post-it note at a certain point in the repository. Any new changes are also marked with this same post-it note, and when you’re ready, git will put all those changes right where that post-it note was, and then throw away the note.
TFVC can’t use post-it notes; it requires that you make physical copies of the files and make changes to those copies and then check each copy against its original and merge those changes together.
The problem — and the reason why the team was seeing conflicts merged out; is that it’s very easy and fast to move a post-it note to another point in the repository and tell git to start from there, but that’s not what was happening. The post-it note was staying at that very old place in the repository, and trying to check changes against that old starting point. If people didn’t move the post it note forward, git had a lot more work to do, and the potential for error increased.
The net effect was that every time the team had to stop and figure out how the heck those changes got merged out — if they even realized the problem was in source control in the first place — cost the team money. Delivery downstream impacts, developer time, cycle time as QA waited for new builds, all of that added up to — in some cases, a loss of $20000 per incident in productivity time.
The moral of the story isn’t to go out and buy git training (though it’s well worth it), it’s that the things that sap a team’s productivity and cost delivery teams money could be a mismatch between the process the team has and what the process should be for that team. In this case, the fix was a slight change in how develoeprs branched, an activity that took a sum total of a few seconds.