Source Control Management

Code repositories allow developers to write code confidently. More developers are using source control than ever before. The most obvious benefits of the code repository can be seen when multiple developers are collaborating on code. Many hands in the pot means there's a greater need to manage and understand revisions. Code doesn't exist unless it's committed into source control. Source control is the fundamental enabler of Continuous DeliveryIf you ever have to make an argument to support source control, ask the following have you ever questions: 

  • Made changes to the code, realized the mistake, and wanted to revert back? 
  • Lost some code or had a backup that was too outdated? 
  • Had to maintain version histories of a product? 
  • Wanted to see the difference between two (or more) versions of your code? 
  • Wanted to prove that a particular change broke or fixed a piece of code? 
  • Wanted to review the version history of some code? 
  • Wanted to deploy changes to someone else's code?
  • Wanted to share your code, or let other people access your code? 
  • Wanted to see the progress on work being done, and where, when and by whom? 
  • Wanted to experiment with new features without tampering with working code? 

Managing code is an essential part of managing the application life cycle, which spans indiscriminately across programming languages and frameworks. Source-control systems can broadly be distinguished as centralized or distributedWe'll cover the differences between the two, but before that, take a look at this trend chart for SVN versus Git, which was created using Google search data. SVN is a centralized version control system. You'll notice that SVN as a search keyword was very popular during the time of waterfall-based project deliveries. It started losing its popularity to Git (a distributed version control system) during early 2010 when Agile became mainstream. The popularity of Git grew exponentially with the adoption of Open Source Software (OSS):

Let's look at both of the version-control systems to understand how they work. A Centralized Version-Control System (CVCS) maintains a single central copy of your source code on a server repository. When working with a CVCS, the developer downloads the code from the server to a local workspace. Once changes to the code have been made locally, they are pushed to the centralized copy. Since each of the files in the local workspace is connected to the server, the server is aware that they are being modified, which can be useful if you intend to block someone else from making the changes while you are editing the files. Any functions against the repository (such as branching, merging, and shelving) also take place on the server, and require a connection to the server.  Foundation Version Control (TFVC) is a centralized version-control system. When working with TFVC using Visual Studio or Eclipse, the IDE is in frequent communication with the server. Basic operations, such as getting the latest code or seeing the full list of history changes, cannot be done without an active connection to the server.

Distributed Version Control System (DVCS) does not necessarily rely on a central server to store all the versions of a project's files. Instead, every developer clones a copy of a repository and has the full history of the project on their own hard drive. This copy (clone) contains all of the data in the repository  all of the branches and all of the commit history. Git is a distributed version control system. Most operations (except pushing and pulling) can be performed without an active connection to the server. 

Both centralized and distributed version control systems have their pros and cons. Consider the strengths of the source control system to determine the viability of using it in your project. CVCS is best suited for very large codebases, where you need granular access control, and especially if you need to audit usage. Consider using CVCS on codebases that are hard to merge:

DVCS, on the other hand, is suited for highly distributed teams working across platforms. It provides portable history, and works best with greenfield codebases where the codebase is structured in small modules:

Every business is a technology business, and software is seen as the propeller for innovation. Being able to innovate quickly and cheaply, testing ideas and products with the consumers, refining them, and releasing them on a regular basis has become a competitive advantage. Your speed to convert ideas into working products can sometimes be the difference between success and failure in this very competitive marketplace. Development teams are constantly under pressure to deliver better-quality software faster. The speed is usually a byproduct of a good quality codebase, backed by unit tests. A good source control system can significantly contribute to the quality of the software, but it requires much more than just a good source-control system to drive quality. No code standards, a lack of unit tests, too many tactical implementations, and not addressing underlying architecture issues are major contributors to Technical Debt. Technical debt doesn't hit you overnight—it's a slow and gradual process. Unlike financial debt, technical debt is very hard to recognize. Technical debt slows your ability to deliver value.

In this chapter, we will cover the following recipes:

  • Migrating from TFVC to Git keeping with code history  
  • Accessing Azure DevOps Server Git repositories using SSH
  • Importing a Git repository from GitHub into Azure DevOps Server
  • Basic Git operations using Visual Studio Code 
  • Setting up Git branches for continuous delivery
  • Pull request for code review using branch policies
  • Using Git hooks with Azure DevOps Server
  • Managing and storing large files in Git
  • Git branching model for Continuous Delivery  
  • Configuring code search as a search engine
  • Using Git forks and sync changes with upstream PR