Imagine you carefully set up your recruitment process to hire an excellent developer capable of developing and maintaining your applications. One developer particular positively surprises your team with their knowledge on their domain of expertise. During the on boarding process, everything runs smoothly.
One day, you encounter an emergency situation: either fix a serious bug, or lose tens of thousands of dollars every hour. Unfortunately, you can only count on your new superstar to fix this bug, because everyone else is already at home.
Based on your expertise, you may suggest rolling back to a previous version. Your freshly hired developer, who seems like an all-star in all other regards, has no idea how to do that. He wastes an hour trying to deploy the previous version of your system, resulting in a net loss of $25.000. Fortunately, after the hour, the rollback is complete, so you go home feeling some relief.
Next week your Engineering Manager reports that the git tree is a mess due to the rollback, and it takes them days to retrieve the lost commits and take care of merges. Some commits got lost, others appeared for no reason, and some forced pushes made the whole source code buggy and inconsistent. Furthermore, the deployed source code is different than the latest commit on master.
If a story like this has ever happened to you, you know that common sense is not too common when it comes to knowing how to use git.
Some people have never learned git beyond following the process laid out by their company or team. Imagine this person following a step-by-step cheat sheet: they know nothing else besides what is written there.
When they join your team, they make a mess on a regular basis, and have trouble following your process. In an emergency situation, they tend to crash and burn.
Others are more advanced git users, but they refuse to follow your process. They have ego issues and use git their way, without any respect to their team members.
Your best developers may consider resigning, because they just cannot cope with the mess the newcomers cause on a constant basis. It feels like these newcomers need a personal assistant to cope with the challenges of everyday development.
If you have encountered any of these problems, you might be looking for some relief. I have good and bad news for you.
The bad news is, some people cannot be saved. All you can do is set your boundaries and try to help them improve their skills. They will either make an effort to change their habits, or they will get fired after a few warnings.
The good news is, you can make improvements during your hiring process. In this article, I will not only cover modifying the recruitment process, but also how to extend the on boarding process to create alignment both in the level of effort in learning to use git, and in the processes and workflows people need to execute.
I will conclude this article with anomalies worth solving in your company.
Your Recruitment Funnel May Be Wrong
In my book, The Developer’s Edge, I present three software developer profiles:
“A generalist can solve many simple problems, without diving deep into a certain domain. Imagine a generalist as a horizontal profile of knowing a lot of things on a basic level.
Unfortunately, when it comes to handling git, your specialist may also crash and burn.
You may ask, does this mean that you need to hire generalists and sacrifice the quality of your solutions? The answer is an obvious no. You want to merge the best of the two worlds. Quoting The Developer’s Edge:
“There is high demand for T-shaped professionals, having both a horizontal generalist profile, and a vertical specialist profile. T-shaped professionals can work on their level of expertise without needing many people to support them.”
In your recruitment process, you need to screen both horizontally and vertically, to avoid hiring people who are not functional without regular help. The smaller your company, the more horizontal screening you need, because people may have to step outside their job descriptions to help the company get off the ground. The larger the company, the less generalist knowledge you need to build a functional team. It can be embarrassing at times when a developer does not know the fundamentals, but large corporations expect this. They simply train their workforce and tolerate mistakes in the interim.
Once you decide how much generalist knowledge you need, you can calibrate your recruitment process. Let’s explore some steps to make sure developers you hire know the basics of git.
First of all, look for developers who have a GitHub profile and actively contribute to open source repositories. They will know how to submit a pull request, and how to cooperate with the processes of the repository. This is why I really admired the recruitment process of the German startup Wunderlist. Back in 2013, when they were called 6Wunderkinder, I noticed their job description stated that a necessary condition for applying was that you had to show that you contributed to at least one open source repository, and that your pull request was merged. No wunder, pun intended, that this company is still around.
Second, set up a homework assignment, where the developer is asked to contribute to a git repository of your choice by forking the repository and submitting a pull request. By doing this, you disclose your corporate workflow, and you can see if the candidate can follow it.
Third, you may ask your candidate to describe his favorite git workflow verbally. This screens for git knowledge, communication skills, and collaboration skills. I like these kinds of three-in-one questions: they save time, and give you a lot of information.
Asking git questions makes no sense in the on-site interview. Embedding some required git knowledge in the homework assignment, or screening by looking pull requests to open source repositories, helps you a lot more.
Once you finish hiring, your task is not done. You will have to onboard your developer.
A necessary condition for a successful on boarding process is that your developers can make a change in your codebase and deploy code on their own. In order to achieve this goal, they need to unlearn some things and learn others.
During the on boarding process, unlearning habits that conflict with your workflow is just as important as learning.
Some people always commit to master, because they work on their own. Tell them why this habit cannot work. Tell them how your teamwork will be compromised by them committing to master, while others follow their own workflow. Set clear expectations, and make sure all future violations are caught. It’s possible that even after your clear explanations, a few people won’t cooperate, but that’s fine. The probation period should reveal shortcomings of developers you cannot cooperate with.
Some developers have never submitted a pull request in their lives. (Note that if you follow my advice, you will only hire developers who have submitted a pull request before, either to your code base or to an open source repository.) If you have to onboard someone who has no experience with pull requests, and you need pull requests in your workflow, again, set your boundaries. The people you work with should be intelligent and cooperative enough to both learn your company's processes and contribute to your team.
Those people who do not cooperate after several warnings should be fired. In my article, Secrets of a Successful Tech Interview, I explain how to spot a professional developer and how to spot a troublemaker. Although the article is written from a developer’s perspective, the comparison is evident from the CTO’s point of view as well. As soon as you spot red flags in an interview or during the on boarding process, it’s time to draw boundaries. During the on boarding process, healthy boundaries mean that you communicate your expectations clearly upon each violation. Once mistakes are repeated, you may decide when to let someone go. This sounds a bit harsh at first, but think about it: you owe your best developers the opportunity to work in a professional team. If you focus on good people, you build a great team. If you focus on “saving” people who do not want to be saved, they will never be grateful for your effort. It takes a great leader to communicate expectations without creating fear.
Of course, exceptions apply. Sometimes a developer crashes and burns not because of lack of knowledge or cooperation, but because he has to unlearn using another system. Some people want to improve their git skills, but are lacking in experience. If they do their best, they will get better. Apply your best judgement and people skills to determine who to trust for second chances.
Do you remember the term pull request? Some people have no idea what it is. Why? Because they may be using GitLab for instance, which uses merge requests. Check out this comparison between pull requests and merge requests. While some people use GitHub, others use GitLab or BitBucket. It's important to understand the differences among these platforms.
You have to be prepared that some people may have no experience with your tool of choice. They will have to learn it based on your on boarding plan. I personally have worked with Microsoft VSS, CVS, GitHub, and GitLab. Learning a new method is not a big deal.
Assuming the choice of web interface is decided, developers still need command line git knowledge. Therefore, it is vital that you provide your developers with some resources in case they get stuck. The best tutorials are interactive, because developers can experiment without damaging your git tree. Some examples are:
- https://learngitbranching.js.org/: interactive tutorial
- https://git-scm.com/book: This is not the easiest read for beginners
- https://try.github.io/ and resources from this post
Last, but not least, if you want to teach git yourself, I highly recommend the resource https://recompilermag.com/issues/issue-1/how-to-teach-git/.
Your Workflow Should Make Sense
Different teams operate optimally using different workflows. If your development team consists of 1 person, 3 people, 10 people, or 50 people, you may need different workflows.
First of all, if you don’t have any workflows, and anyone can do anything they want, chances are, you are making a mistake. Don’t get me wrong, autonomy is a great thing. However, autonomy only makes sense if alignment is present too. Therefore, your team should establish and respect one process everyone follows.
This article highlights the advantages and disadvantages of different workflows. Compare and contrast it with Buddy blog's breakdown of it to get an idea of what workflows exist and when they should be used.
Some developers may be biased towards one specific workflow. They have to understand that your team or department may be using a different workflow, because the context is different.
In some cases, you need to put a lot of thought into why you select a specific workflow. My personal role model is this Toptal article. Although this article is opinionated, the statements of the author are backed and justified.
If you decide to build your workflow from the ground up, you might consider reading Benjamin Sandofsky's guide. You can get inspiration from it on topics like rebasing or merging, and the process of interactive rebasing.
The Eightfold Path to Workflow Enlightenment
Above all, make sure you apply common sense. Sometimes your existing developers are so used to old processes that they don’t bother changing. When a new wizard kid comes to your team and challenges the status quo, you need to apply judgement to determine whether the wizard kid has a point, or if he is just biased towards what he knows.
I have seen companies where the development process was the same while the team grew from 2 people to 15. Originally, two developers almost never clashed, therefore, they could afford to occasionally shout out when they would make a forced push, overwriting the other developer’s work if he committed anything in the last few hours. With 15 developers, this process becomes untenable. An outdated process is a big burden for your team. Therefore, educate and challenge the status quo if needed.
I will now cover eight common anomalies that are created due to lack of defining and enforcing a robust process.
- Define your gitignore file. If you are using Apple equipment, the most innocent file that could end up in your repository is the .DS_Store file. It does not belong in git. Make sure generated files and files created during the build process do not end up in git. They create unnecessary conflicts, and their presence simply does not matter because your build process will overwrite all these files anyways.
- Teach your developers how to resolve conflicts. Rebasing gives you conflicts in chronological order, but you may have to resolve the same conflict over and over again. Merging gives you all the conflicts at once, and you have to resolve them all at once. While rebasing makes the git tree more linear, merging makes it easier to track how different branches contribute to the result, and which commit belongs to which project. In my personal opinion, people obsessed with a flat git tree overlook the advantage of browsing the history of how different branches were created.
- Make sure you only use a forced push when it is absolutely necessary. In certain teams, never use a forced push. Just imagine two people working on a branch. Dan pulls from the branch. Sarah pushes a change half an hour later. Then Dan force pushes a change. Sarah’s work is lost even though she did nothing wrong.
- Don’t forget to annotate your git tree with information. For example, you can create tags that help you monitor your deployments.
- Make sure the terminals of all developers are set up such that they have sufficient information about what they are doing in git. The absolute minimum is that they see the currently active branch in git, they have a merge tool configured, and have color coding showing whether they have made changes to a branch or not.
- Make sure you define the granularity of your commits. If you don’t define your clear preference, it may lead to chaos. Some people use commits as a save button. Others flood you with two weeks of work at once, giving you a lot of unwanted surprises, conflicts, and headaches. There is a reason why a commit should be one semantic unit, making one atomic change. Of course in some cases, we tend to forget things. But hey, this is what interactive rebases are for. You can squash multiple commits into one on your own computer, before pushing. Then your change appears as one commit.
- Make sure you don’t send your developers on long refactoring missions while you ask them to work on the same pages on a regular basis. While you refactor things, all updates will lead to double implementation, because you need to deploy code to the old system while updating your refactored code with the same changes.
- Make sure your developers never commit sensitive data to the codebase. Especially because a commit is a prefix code that can be retrieved even if you delete it from the tree. It is also displayed on GitHub if your commit message links the commit to the issue. Committing passwords and private keys is often a horrible idea.
Sometimes you do need to remove some commits. Therefore, make sure your developers refer to this article if they need guidance.
If you are looking for some resources on common git mistakes and solutions, you may give some inspiration to your developers by occasionally sending them some articles to discuss. Examples:
- 10 Common Git Problems and How to Fix Them
- Why You Should Stop Using Git Rebase (opinionated article)
- Common Git Mistakes and How to Fix Them
Using git is not straightforward. Therefore, you need to make sure that your team has some expertise.
If you hire experts, make sure their profile is T-shaped and they are capable of working on their own. You can screen for git knowledge by checking if they have any open source contributions. Alternatively, you may ask them to contribute to your repository as a test.
During on boarding, your process should be clean and transparent. While patience is important, a high tolerance for repeated mistakes leads to continuous boundary violations. If you don’t set your boundaries, your best developers will leave you due to friction and frustration, and you will encounter an even bigger problem.
In some cases, new developers bring great ideas, while your current developers are too comfortable executing processes that have become outdated. In other cases, developers may be sticking to what they know, even though it’s not the best workflow for the situation. It is often a tough call when it is time to change your process. This article gave you eight tips that will help you spot some obvious mistakes with your workflow.
Good luck with setting up your workflow and guarding it from developers who do not cooperate with you. Your efforts will pay off in the long run.