Intro to Version Control and Git
Non-Azure Repos and Pipelines
The course is part of this learning path
This course explores how to implement version control on Azure repos. It begins with an overview of what source control is and the different types of source control available. It then looks at the key elements of branching, different branching strategies, and how they impact the development process. You'll move on to learn about pull requests and merging as repository functions, and the different merging scenarios available to you. Finally, you'll be guided through using third-party systems in conjunction with Azure DevOps. This course contains several guided demonstrations from inside the Azure portal to give you real-world exposure to the concepts covered throughout the course.
If you have any feedback relating to this course, please feel free to reach out to us at firstname.lastname@example.org with any questions or comments.
- Understand what version control and Git-based repositories are
- Learn about branching and the branching strategies
- Learn about pull requests and merging in Azure DevOps
- Set permissions on repositories and on TVFC in Azure DevOps
- Use Azure DevOps in conjunction with build pipelines set up on other platforms
This is an intermediate level course suited to developers, engineers, and project managers.
To get the most out of this course, you should have a basic understanding of the software development lifecycle. Knowing what's involved in deploying software to a production environment would also be helpful. If you want to follow along with the demonstrations in this course, you'll need to have an Azure DevOps account.
One of the criticisms of TFVC, a centralized repository system, is that branching is expensive. What does this actually mean? Well, the cost of branching can be viewed in two ways. There is the cost of performing the branching process and there is the cost of merging the branch back into the master trunk. Creating a branch in TFVC isn't as easy as with Git, and this is mainly due to the fact that TFVC creates a physical copy of the original branch as the starting point of the new branch, whereas Git uses the most recent commit from the parent branch. It's the difference between making a physical copy of a variable, as opposed to creating a new pointer to it. The other crucial difference is that TFVC branches are always created on the server, so you have to be connected and be cognizant of branch naming and potential naming conflicts. As Git is distributed, a developer can create branches at will on their own repository and only have to be concerned when merging back to the remote branch.
Merging brings us to the second cost of branching, which significantly outweighs the first. Everyone involved in software development will have their own horror story of branch merging, which typically revolves around sorting out code differences between two or more versions of the same file, or files. Sure, there are tools that can help with this, but it is essentially a manual process similar to untangling string. The process is how long and how many pieces of string are there? This leads to the often quoted refrain "Branch less, merge more," and is the main underlying conundrum of branching strategies.
Having said that, let's look at some generic branching scenarios starting with Main Only, which is essentially a branchless strategy, that is just the master trunk. This means all work is committed back to the main trunk or branch. The Main Only strategy has limited application. It is not suited to maintaining multiple versions and would be very difficult to manage with many developers working on multiple features. Labels can be used to mark development and release events. The irony is that Trunk-based branching, that we'll look at later, is closely related to Main Only and is gaining substantial traction as a strategy.
Development isolation is one of the strategies most people think of when talking about branching. The central tenet of branching is to maintain a stable and pristine main branch, and development isolation does this by explicitly separating all development into its own dev branch. You end up with two branches running in parallel. When a feature in the dev branch is complete, it is merged back into the main branch. When a bug is discovered in production code, it is fixed in the main branch and merged into the dev branch. It seems like a good strategy, but you've essentially ended up with two versions of the software truth, and quite some effort is required to maintain concurrency. It's definitely not unheard of for bug fixes in the main branch not to be merged into dev and then for the bug to reappear after a new dev feature is merged into main.
Feature isolation is a variant or evolution of development isolation. Basically, its short-lived development branches that are dedicated to one feature. This addresses a couple of issues. Firstly, "The branch only exists, "or should only exist for a short time "before it's merged back into its parent." A feature can be branched off a development branch. Secondly, there can be multiple feature branches running concurrently. When it comes to bug fixes in production, there is still the same issue of fixing them in the master and merging them into the feature branch so they aren't lost when merging features back.
Release isolation is geared towards creating multiple production versions of your software as each release branch is a snapshot of the code when the branch is created. Release branches can coexist with development or feature branches. When you want to release a new version of your software because the required features have been completed, tested and merged back into master, you create a release branch. The release branch is read-only, with one exception. If a bug is found in production code, it is fixed in the release branch and merged back into the main branch. This is a simplistic depiction, as there can be multiple concurrent releases in existence and being supported. In terms of applying hotfixes to past releases, it really boils down to how long you want to support old versions before retiring them. This is probably a good place to remind ourselves of how different software platforms have different requirements. In the world of web or mobile apps, it's very rare to have more than one version of your software in the wild. Everyone runs the latest version. This is certainly not the case for desktop or server-based applications and will definitely influence your branching strategy choice.
Hallam is a software architect with over 20 years experience across a wide range of industries. He began his software career as a Delphi/Interbase disciple but changed his allegiance to Microsoft with its deep and broad ecosystem. While Hallam has designed and crafted custom software utilizing web, mobile and desktop technologies, good quality reliable data is the key to a successful solution. The challenge of quickly turning data into useful information for digestion by humans and machines has led Hallam to specialize in database design and process automation. Showing customers how leverage new technology to change and improve their business processes is one of the key drivers keeping Hallam coming back to the keyboard.