Examination Preparation Materials - Chapter 06

Getting Prepared in DevOps

What is version control ?

Version control is a system that tracks changes to a set of files over time. It's essentially a way to record the history of your files, allowing you to see who made what changes, when they were made, and revert back to previous versions if needed. Version control is particularly important in software development, where multiple people might be working on the same codebase, but it can be useful for any kind of project that involves managing revisions of documents, design files, or other digital assets.

There are two main types of version control systems (VCS) with distinct characteristics:

Centralized Version Control Systems (CVCS)

  1. Centralized Repository: CVCS stores all versions of the files in a single central server. This server acts as the one source of truth for the project.

  2. Checkout & Check-in: Developers need to "check out" files from the central server to make changes locally. Once edits are complete, they "check in" the modified files back to the server. This ensures only one person can edit a file at a time, preventing conflicts.

  3. Examples: Subversion (SVN) is a popular example of a CVCS.

Distributed Version Control Systems (DVCS)

  1. Distributed Repositories: DVCS doesn't rely on a single central server. Each developer has a complete copy of the entire version history on their local machine. This local copy is called a "clone" of the main repository, which can be hosted remotely for collaboration.

  2. Offline Work: Since developers have a complete history locally, they can work on changes even without an internet connection. This allows for greater flexibility and offline development.

  3. Branching & Merging: DVCS excels at branching, where developers can create isolated copies of the codebase to work on features or bug fixes independently. These branches can then be merged back into the main codebase when ready. This facilitates collaboration and experimentation.

  4. Examples: Git is the most popular DVCS used today. Mercurial is another example.

Here's a table summarizing the key differences:

FeatureCentralized Version Control (CVCS)Distributed Version Control (DVCS)
Repository LocationCentral ServerDistributed (Local Machine & Remote)
Offline WorkLimitedPossible
Checkout/Check-inRequiredNot Applicable
BranchingLess FlexibleHighly Flexible
CollaborationRequires Central Server AccessEnables Offline Collaboration
Popular ExamplesSubversion (SVN)Git, Mercurial

Choosing between CVCS and DVCS depends on your project needs. CVCS can be simpler for small teams with a stable development environment. However, for most modern software development projects, the flexibility and offline capabilities of DVCS like Git make them the preferred choice.

Git Basics

Git is a popular distributed version control system (DVCS) used for tracking changes in computer files. It's particularly helpful for software development projects where multiple people collaborate on the codebase.

Learn more about git from

  1. Official Site - https://git-scm.com/

  2. Github.com - https://docs.github.com/en/get-started/start-your-journey/git-and-github-learning-resources

  3. Learn git branching - https://learngitbranching.js.org/

Git Pull, Git Fetch, Git merge, Git Rebase

All of these are git workflow commands with specific usecases.

  • Git Fetch: This command downloads the latest changes from a remote repository but doesn't automatically merge them into your local branch. The fetched changes are stored locally for you to review and then decide how to integrate them (often using git merge later).

  • Git Merge: This command manually integrates changes from another branch (local or remote) into your current branch. If there are conflicts (overlapping changes in the same file), you'll need to resolve them manually before completing the merge.

  • Git Pull: This command combines two actions: git fetch and git merge. It retrieves the latest changes from a remote repository (usually the one you push your commits to) and attempts to automatically merge them into your local branch. It's a convenient shortcut for updating your local branch with the latest upstream changes.

  • Git Rebase: This command rewrites your local commit history. It takes your current branch and replays your commits on top of the latest remote branch head. This can result in a cleaner linear commit history, but it can also be risky if you've already shared your local branch with others as it rewrites history.

Explanation by example

Imagine you're working on a feature branch for a project called "add_search" that adds a search bar functionality. You have two commits in your branch:

  • Commit 1: Added basic search functionality to the code.

  • Commit 2: Improved the search bar UI.

In the meantime, the main branch (often called "master") has received bug fixes from another developer (Commit X).

Here's how rebase, squash, and merge would handle integrating your "add_search" branch with the updated main branch:

Rebase:

  1. You use git fetch to download the latest changes from the remote repository (including Commit X on main branch).

  2. You run git rebase main. This replays your commits (Commit 1 and Commit 2) on top of the latest main branch (which now includes Commit X).

Result: Your local "add_search" branch now has a linear history with three commits: Commit X (from main branch), your Commit 1 (modified to reflect the rebased position), and your Commit 2 (also rebased).

Squash:

  1. You use git fetch to download the latest changes.

  2. You run git merge main to initiate a merge with the main branch.

  3. Git identifies a merge conflict (since both branches might have modified the same files). You resolve the conflict manually.

  4. Instead of creating a regular merge commit, you use the --squash option with git commit to combine your two commits from the "add_search" branch into a single commit with a new message summarizing the changes.

Result: Your local "add_search" branch has a single commit that integrates the search functionality and UI improvements, along with the bug fix from the main branch (Commit X) reflected as the parent commit.

Merge:

  1. You use git fetch to download the latest changes.

  2. You run git merge main to integrate the main branch into your "add_search" branch.

  3. Git might identify a merge conflict that you need to resolve manually.

  4. Git creates a new merge commit that points to your "add_search" branch head and the main branch head (including Commit X).

Result: Your local "add_search" branch maintains its two commits but has a new merge commit on top that signifies the integration with the main branch (including Commit X). The commit history becomes slightly more complex with a merge point.

Semantic Versioning

Semantic Versioning (aka - SemVer) is a versioning scheme used for software to communicate the nature and impact of changes in a project. It helps developers and users understand the compatibility and potential risks associated with upgrading to a new version. Here's a breakdown of the key aspects of SemVer:

  • Version format: SemVer uses a three-part version number format: Major.Minor.Patch (e.g., 2.1.4).

    • Major: Incremented for breaking changes (changes that cause existing code to stop working).

    • Minor: Incremented for new features that maintain backward compatibility (existing code should still work).

    • Patch: Incremented for bug fixes that maintain backward compatibility.

  • Public API: SemVer assumes there's a well-defined public API (application programming interface) for your software. This API defines how users interact with your software.

  • Backward Compatibility: A core principle of SemVer is maintaining backward compatibility. This means that in most cases, users should be able to upgrade to a new version without having to modify their existing code.

Here's a table summarizing the impact of changes on each version component:

Version ComponentIncrement WhenImpact on Users
MajorBackwards-incompatible changesUsers might need to modify their code
MinorNew features with backwards compatibilityUsers can upgrade seamlessly
PatchBug fixes with backwards compatibilityUsers can upgrade seamlessly

Benefits of using Semantic Versioning:

  • Clear Communication: Provides a clear and concise way to communicate the nature and impact of changes in a version number.

  • Backward Compatibility: Helps maintain backward compatibility, making it easier for users to upgrade without breaking their applications.

  • Reduced Risk: Allows users to make informed decisions about upgrades based on version numbers and potential breaking changes.

  • Version Dependency Management: Simplifies dependency management for projects that rely on other software components with their own versions.

Overall, Semantic Versioning promotes a consistent and predictable approach to software versioning, fostering better communication and collaboration between developers and users.