Unravelling the Code Tapestry: Before Running the Build

  • Friday, Mar 15, 2024
An open Macbook Pro sits on a mahogany desk alongside a white coffee cup, an iPhone, a notepad and pen. The screens for both the Macbook and iPhone are off. The notepad has some, out of focus, writing on it.

The cover image for this post is by Andrew Neel

This is part five in our series of blog posts detailing our system for genius when working safely with legacy code. The other parts of this series include:

  1. UA Series On Safely Navigating Software’s Timeless Artifacts
  2. Preparing To Tame Legacy Code With User-Led Odysseys
  3. Conversations with Code Custodians
  4. Why Documentation is Key to Legacy Code Success


Working with legacy code can be a challenging experience, but by following a structured approach, developers can effectively contribute to the repository while ensuring compatibility with existing practices and promoting efficient collaboration among team members. This extended blog post will provide an in-depth guide on navigating legacy code, focusing on key areas such as branching strategies, deployment environments, documentation, and collaboration.

Gaining Access to the Repository

When working with a legacy codebase, it is crucial to ensure that you have both read and write access to the repository. This will enable you to view existing source code files, make modifications, and push changes back into the repository. Without write access, contributing to the project will be challenging, as it will not be possible to share your work with other team members or integrate it into the codebase.

To gain access, contact an administrator or a team member responsible for managing the repository. Request read and write permissions, ensuring that you do not have permissions to write directly to the main branch (also known as master in some older repositories). This is important because maintaining a stable, well-tested version of the codebase in the main branch ensures minimal disruption to live environments when deploying updates.

Once granted access, familiarize yourself with your repository’s structure and any existing documentation related to its use (covered in part four of this series). Understanding how the repository is organized, how different branches interact, and how they correspond to deployment environments will help you work more efficiently within the codebase and reduce the risk of conflicts or errors when making contributions.

Cloning the Repository to Your Computer

After gaining access to the repository, it is essential to clone the codebase to your local computer. The cloning process involves copying all the necessary source files and repository metadata from a remote server onto your local machine. This enables you to view, modify, and contribute to the project without needing constant internet connectivity or reliance on remote resources.

You can choose to clone the code using various methods such as command-line applications like git, graphical user interface (GUI) applications, or through your Integrated Development Environment (IDE). The preferred cloning location should be a simple file path in your computer’s file system, as this will ease access and facilitate smooth management of your project files.

On Windows systems, consider cloning the code to a straightforward path, such as c:\code, c:\source, or c:\repos—older versions of Windows had problems with long filepaths, but this isn’t a problem as of Windows 10. For Unix-based operating systems (e.g., macOS or Linux distributions), use a more appropriate path like ~/code, ~/source, or ~/path/to/your/projects.

Creating a Local Branch for Spelunking

Before beginning any work within the cloned repository, it is highly recommended to create a local branch specifically for your exploration and development tasks. This local branch will act as a sandbox where you can experiment, investigate, and make changes without impacting the main branch or live environments.

To do this, use the git command-line tool or your IDE’s built-in branch management functionality to create a new branch from the origin/main (or origin/master in some older repositories). A recommended naming convention for this branch is development/spelunking or development/initial-experiments, as it clearly indicates your purpose and helps maintain organizational consistency.

Working on a separate local branch protects you from accidentally committing and/or pushing unwanted changes directly to the main branch. It also reduces the risk of conflicts that may arise from altering, creating, or deleting files within the codebase. Later, when you are working on the code base proper, you can merge your changes back into the main branch, ensuring a seamless integration process with the rest of the team’s work.

Understanding Branch Protection Policies

Regardless of the repository, team, or company, it is essential to understand the branch protection policies in place. These policies dictate how changes can be made to the main or master branch and whether they must go through pull requests (PRs). Knowing these rules will help you avoid accidentally committing unwanted changes directly to the main branch.

Some teams may have strict protections in place, requiring all modifications to be submitted through PRs for review before being merged into the main branch. In this case, it is critical to follow established processes and contribute code through pull requests instead of pushing directly to main or master.

Conversely, some organizations may allow direct pushes to the main branch with specific guidelines in place for emergency fixes or patches. It is important to be aware of these expectations and work accordingly to ensure a smooth collaboration experience within the team.

Understanding the branch protection policies in place will help you navigate the codebase effectively and contribute to the project without causing unintended consequences or disruptions to your fellow developers' workflow.

Identifying Branch Permissions In Place

To guarantee that branch access is appropriately configured on the source control repository, push your local development branch to the remote server. This step ensures that you can create and manage remote branches without relying on administrators or other team members for setup.

Inform the lead developer or maintainer about this initial action, as well as your intention to request that the branch be deleted shortly afterward (remember, this is our spelunking branch). This transparency helps maintain a strong collaborative relationship while ensuring a smooth workflow.

Understanding Branching The Strategies Used

Each team, and sometimes project, will have their own branching strategies. As such you need to learn the preferred branching strategy for the project you’re working on. Return to the main branch (using git checkout main) to familiarize yourself with existing branches and their purposes, using git commands like git branch -a to list all available branches.

Discuss with your team members about the project’s branching conventions, paying particular attention to naming structures and how they relate to specific workflows or development tasks. For example, if a development branch exists, consider switching to it and creating a child branch with an appropriate friendly identifier, such as development/jt or development/jamie-dev (both based on my name, and easily identifiable by the rest of the team) or based on a ticket identifier (e.g. development/1538-implement-login-redirect), for future work.

Identifying the Live Branch

Determining which branch represents the live or production version of the application will be crucial, as the development branches may not look and act like live. Ask your team members about the deployment process and whether there are separate development environments for testing purposes.

In some cases, these environments may be represented by different branches within the repository or may consist of earlier builds based on the main branch. Identifying the live branch allows you to adapt your workflow accordingly and contribute effectively while understanding the project’s current state. This knowledge will prove invaluable as you navigate through the codebase and collaborate with other team members in a well-informed manner.

Documenting Your Findings

As you explore the legacy codebase, document each step of your journey for future reference. This will prove beneficial as it allows you to share your knowledge with the current team, those who come after you, and even “future you” when revisiting the project at a later time. By meticulously noting your discoveries, you can compare your findings against existing documentation and contribute valuable insights that will aid collaboration and overall project success. This is the subject of the next blog post in this series.

In Conclusion

In this post, we explored various aspects of working with legacy codebases, including creating local branches for exploration, understanding branch protection policies, ensuring correct permissions, learning the team’s preferred strategies, and the importance of noting your findings throughout the process. These steps ensure that you can effectively contribute to a project while maintaining optimal collaboration and communication, ultimately resulting in a more efficient workflow and a higher-quality product. By following these best practices, you’ll be set up for success even before opening the code in your integrated development environment (IDE).

Stay tuned for the upcoming chapters as we delve further into the art of deciphering legacy code and navigating the intricacies of software archaeology.

If you’d like us to help you work through the challenges involved with working safely with a legacy codebase, either in a hands-on capacity or as a consultant, get in touch with the form below

We'll never share your name with anyone else.
We'll never share your email with anyone else.
Providing a subject can help us deal with your request sooner.
Please be as specific as possible; it will help us to provide a more specific response.
Un-checking this box will ensure that your data is deleted (in line with our privacy policy after we have dealt with your request. Leaving this box checked will auto enrol you into our email communications, which are used for marketing purposes only.