Welcome to Chapter 2 of our DevOps journey! In the previous chapter, you built a solid foundation with Linux fundamentals, mastering the command line, understanding file systems, and managing permissions. These skills are crucial because, in the world of DevOps, much of our work happens on Linux systems, and we interact with tools primarily through the terminal.

Now, we’re ready to tackle a cornerstone of modern software development and DevOps: Version Control. Specifically, we’ll dive deep into Git and GitHub. Imagine trying to build a complex project with a team without a way to track everyone’s changes, collaborate efficiently, or revert to a previous working state if something goes wrong. It would be chaos! Version control solves these very problems, making it indispensable for individual developers and large teams alike.

By the end of this chapter, you’ll not only understand what Git and GitHub are but also why they are essential for collaboration and code management. You’ll gain hands-on experience with core Git commands, learn how to manage your code locally, push it to a remote repository on GitHub, and collaborate effectively with others. Get ready to transform how you manage your code!


2.1 What is Version Control, and Why Do We Need It?

Before we jump into Git, let’s understand the fundamental problem version control solves.

Imagine you’re working on a document, say, a resume. You save “resume_v1.docx”, then “resume_v2_final.docx”, then “resume_v3_final_final_really.docx”, and so on. This quickly becomes messy, and if you accidentally delete something important in “v3”, getting it back from “v1” is a manual, error-prone copy-paste nightmare.

Now, scale that to a team of developers building an application with thousands of lines of code.

  • How do multiple people work on the same files without overwriting each other’s changes?
  • How do you keep a history of every change made, by whom, and when?
  • What if a new feature breaks the existing application? How do you quickly revert to a stable version?
  • How do you experiment with new ideas without affecting the main project?

Version Control Systems (VCS), like Git, are tools that manage changes to files over time. They keep a complete history of every modification, allowing you to:

  • Track Changes: See who changed what, when, and why.
  • Collaborate: Enable multiple people to work on the same project simultaneously without conflicts.
  • Revert: Easily go back to any previous version of your code.
  • Branch: Create independent lines of development for new features or bug fixes, isolating changes until they are ready.
  • Merge: Combine changes from different branches back into the main project.

In a DevOps pipeline, version control is the very first step. It’s where all code lives, where changes are proposed, reviewed, and approved, before they even think about deployment. It’s the single source of truth for your entire application’s codebase.

2.2 Git vs. GitHub: Understanding the Difference

Often, people use “Git” and “GitHub” interchangeably, but they are distinct entities. Let’s clarify:

2.2.1 Git: The Version Control System

Git is a distributed version control system (DVCS). It’s a powerful tool that runs locally on your computer. When you initialize a Git repository in a project folder, Git starts tracking all changes to your files right there, on your machine.

What does “distributed” mean? Unlike older, centralized VCS (where there’s one central server and clients check out files), Git gives every developer a full copy of the entire repository history on their local machine. This means you can commit changes, view history, and even create branches completely offline. When you’re ready, you then synchronize your changes with others. This distributed nature makes Git incredibly robust, fast, and resilient.

2.2.2 GitHub: The Hosting Platform

GitHub is a popular web-based platform that provides hosting for Git repositories. Think of it as a social network for code. While Git is the engine, GitHub provides the garage, the showroom, and the mechanics’ lounge.

GitHub (and similar platforms like GitLab, Bitbucket) offers:

  • Remote Storage: A central place to store your Git repositories online. This is where teams share their code.
  • Collaboration Tools: Features like Pull Requests (or Merge Requests), issue tracking, code review tools, and wikis that facilitate teamwork.
  • Access Control: Manage who can see or contribute to your repositories.
  • Integrations: Connects with countless other tools, including Continuous Integration/Continuous Deployment (CI/CD) systems, which we’ll explore later.

So, you use Git on your local machine to manage your code’s history, and you use GitHub to share that code with the world (or your team) and collaborate.

2.3 Core Git Concepts in Action

Let’s demystify some essential Git terminology with a visual and practical approach.

2.3.1 The Git Workflow: A Mental Model

Imagine your project directory. Git sees it in a few distinct states:

  • Working Directory: This is where you actually edit, add, or delete files. These are the changes you’re currently making.
  • Staging Area (or Index): This is a temporary area where you prepare changes before committing them. You select which specific changes you want to include in your next “snapshot.”
  • Local Repository: This is where Git permanently stores your project’s history as a series of “commits.” Each commit is a snapshot of your project at a specific point in time.
  • Remote Repository: This is typically on a platform like GitHub, where your local repository can be synchronized with others.

Here’s a simple flowchart to visualize this:

flowchart LR A["Working Directory"] -->|"Modify Files"| A A -->|"git add"| B["Staging Area"] B -->|"git commit"| C["Local Repository"] C -->|"git push"| D["Remote Repository"] D -->|"git pull"| C C -->|"git checkout"| A

Explanation of the diagram:

  • You start by making changes in your Working Directory.
  • When you’re happy with a set of changes, you git add them to the Staging Area. This is like putting selected items into a shopping cart before checking out.
  • Then, you git commit these staged changes. This creates a permanent snapshot in your Local Repository.
  • To share your changes with the team, you git push them from your Local Repository to the Remote Repository on GitHub.
  • To get updates from others, you git pull from the Remote Repository to your Local Repository.
  • You can also move between different versions or branches in your Local Repository using git checkout, which updates your Working Directory.

2.3.2 Essential Git Terminology

Let’s break down the key terms you’ll encounter:

  • Repository (Repo): A project directory that Git tracks. It contains all your project files and the complete history of changes.
  • Commit: A “snapshot” of your repository at a specific point in time. Each commit has a unique ID, an author, a timestamp, and a commit message explaining the changes.
  • Branch: An independent line of development. The main (or master) branch is typically the primary stable version. You create new branches to work on features or fixes without affecting main.
  • Head: A pointer to the tip of the current branch you are working on.
  • Merge: The process of combining changes from one branch into another.
  • Clone: To create a local copy of a remote repository.
  • Push: To send your committed changes from your local repository to a remote repository.
  • Pull: To fetch changes from a remote repository and integrate them into your local repository.
  • Fetch: To download changes from a remote repository without integrating them into your current working branch.

2.4 Step-by-Step Implementation: Your First Git & GitHub Project

Let’s get hands-on! We’ll start by installing Git, configuring it, creating a local repository, making changes, committing them, and finally pushing them to GitHub.

2.4.1 Step 1: Install Git

First, ensure Git is installed on your Linux system. As of January 2026, the latest stable Git version is likely to be around 2.45.0 or newer. We’ll install a recent stable version.

  1. Update your package list:

    sudo apt update
    

    Explanation: This command refreshes the list of available packages and their versions from the repositories.

  2. Install Git:

    sudo apt install git -y
    

    Explanation: This command installs the git package. The -y flag automatically answers “yes” to any prompts, making the installation non-interactive.

  3. Verify installation:

    git --version
    

    Explanation: After installation, always verify the version to ensure it was successful. You should see output similar to git version 2.45.0 (or whatever the latest stable version is at the time).

2.4.2 Step 2: Configure Git with Your Identity

Git needs to know who you are so that your commits are correctly attributed. This information is embedded in every commit you make.

  1. Set your username:

    git config --global user.name "Your Name"
    

    Explanation: Replace "Your Name" with your actual name. The --global flag means this configuration will apply to all your Git repositories on this machine.

  2. Set your email address:

    git config --global user.email "[email protected]"
    

    Explanation: Replace "[email protected]" with the email address you use for GitHub. This also uses --global.

  3. Verify your configuration:

    git config --list
    

    Explanation: This command lists all your Git configurations. You should see user.name and user.email among them.

2.4.3 Step 3: Create a Local Git Repository

Let’s create a new project directory and initialize it as a Git repository.

  1. Create a new directory for your project:

    mkdir my-devops-project
    

    Explanation: We’re using the mkdir command from Chapter 1 to create a new folder.

  2. Navigate into your new directory:

    cd my-devops-project
    

    Explanation: Change your current working directory to your new project folder.

  3. Initialize Git in this directory:

    git init
    

    Explanation: This is the magic command! git init creates a hidden .git directory inside my-devops-project. This directory contains all the necessary files for Git to track your project’s history. You should see output like Initialized empty Git repository in /home/youruser/my-devops-project/.git/.

    Observation: If you try ls -a (list all files, including hidden ones), you’ll see the .git directory.

2.4.4 Step 4: Make Your First Commit

Now that Git is initialized, let’s create a file, stage it, and commit it.

  1. Create a simple file:

    echo "Hello, DevOps World!" > README.md
    

    Explanation: We’re creating a file named README.md (a common practice for project descriptions) and adding some initial text to it using echo and output redirection.

  2. Check the status of your repository:

    git status
    

    Explanation: This command tells you the current state of your repository. You should see README.md listed under “Untracked files”. This means Git sees the file, but it’s not yet part of the version control.

  3. Add the file to the staging area:

    git add README.md
    

    Explanation: This command moves README.md from the “Working Directory” to the “Staging Area”. Git is now aware that you intend to include this file in your next commit.

  4. Check the status again:

    git status
    

    Explanation: Now, README.md should be listed under “Changes to be committed”. It’s ready for a snapshot!

  5. Commit your changes:

    git commit -m "Initial commit: Add README.md file"
    

    Explanation: The git commit command takes everything from the staging area and permanently records it as a new snapshot (commit) in your local repository. The -m flag allows you to provide a concise commit message directly on the command line. A good commit message explains what changes were made and why.

    You should see output indicating the commit was successful, including its unique ID (a long hexadecimal string).

  6. View your commit history:

    git log
    

    Explanation: This command displays the commit history for your current branch. You’ll see your commit, its author, date, and message. Press q to exit the log view.

2.4.5 Step 5: Connect to GitHub and Push Your Code

Now that your code is safely committed locally, let’s share it with GitHub.

  1. Create a new repository on GitHub:

    • Go to GitHub.com and log in or sign up.
    • Click the + icon in the top right corner and select “New repository.”
    • For Repository name, type my-devops-project (it’s good practice to match your local folder name).
    • Keep it Public for now (or Private if you prefer, but public is fine for learning).
    • DO NOT check “Add a README file,” “Add .gitignore,” or “Choose a license,” as we’ve already created our README.md locally.
    • Click “Create repository.”
  2. Add the remote repository to your local Git configuration: After creating the repository on GitHub, you’ll see instructions. Look for the section “…or push an existing repository from the command line.” It will give you commands like these (replace your-username with your actual GitHub username):

    git remote add origin https://github.com/your-username/my-devops-project.git
    

    Explanation: git remote add tells your local Git repository about a “remote” repository. origin is the conventional name for the primary remote. The URL points to your new GitHub repository.

  3. Push your local commits to GitHub:

    git push -u origin main
    

    Explanation:

    • git push sends your committed changes.
    • -u origin main (or master if your Git version defaults to that, though main is the modern standard) sets the upstream branch. This means that from now on, git push and git pull will automatically know to interact with the main branch on the origin remote without you specifying it.
    • You’ll be prompted for your GitHub username and Personal Access Token (PAT).

    Important: GitHub Personal Access Tokens (PATs) As of 2026, GitHub no longer supports password authentication for Git operations over HTTPS. You must use a Personal Access Token (PAT).

    • How to create a PAT:
      1. Go to GitHub.com.
      2. Click your profile picture (top right) -> Settings.
      3. Scroll down the left sidebar -> Developer settings.
      4. Select Personal access tokens -> Tokens (classic).
      5. Click Generate new token -> Generate new token (classic).
      6. Give it a descriptive name (e.g., “DevOps Learning Token”).
      7. Set an expiration (e.g., 90 days or 1 year).
      8. For scopes, select at least repo (full control of private repositories) for general use. For learning, this is sufficient.
      9. Click Generate token.
      10. CRITICAL: Copy the generated token immediately! You will not be able to see it again. Treat it like a password.

    When prompted for a password during git push, paste your PAT.

    After a successful push, refresh your GitHub repository page in your browser. You should now see your README.md file!

2.4.6 Step 6: Branching and Merging

Working on the main branch directly is generally discouraged for new features. Instead, we create branches.

  1. Create a new branch:

    git branch feature/add-new-content
    

    Explanation: This command creates a new branch named feature/add-new-content. It’s a good practice to use descriptive names for branches, often prefixed with feature/, bugfix/, or hotfix/.

  2. Switch to the new branch:

    git checkout feature/add-new-content
    

    Explanation: git checkout switches your “Head” (and thus your Working Directory) to the specified branch. You’ll see output like Switched to branch 'feature/add-new-content'.

  3. Make changes on the new branch:

    echo "This is new content for the feature branch." >> new-feature.txt
    echo "Another line of content." >> new-feature.txt
    

    Explanation: We’re creating a new file new-feature.txt and adding some content.

  4. Stage and commit these changes:

    git add new-feature.txt
    git commit -m "Feature: Add new-feature.txt with sample content"
    

    Explanation: Just like before, we stage and commit our changes, but this time, the commit is recorded only on the feature/add-new-content branch.

  5. Push the new branch to GitHub:

    git push -u origin feature/add-new-content
    

    Explanation: We push this new branch to the remote. Now, if you check GitHub, you’ll see 2 branches and an option to compare and create a Pull Request for your new branch.

  6. Switch back to the main branch:

    git checkout main
    

    Explanation: Your Working Directory will revert to the state of the main branch. If you ls, you won’t see new-feature.txt.

  7. Merge the feature branch into main:

    git merge feature/add-new-content
    

    Explanation: This command integrates the changes from feature/add-new-content into your current branch (main). Git will automatically combine the changes. You should now see new-feature.txt in your Working Directory again.

  8. Push the merged changes to GitHub:

    git push origin main
    

    Explanation: Now that main has the new changes locally, you push main to the remote.

  9. Delete the feature branch (optional, but good practice): Once a feature branch is merged and no longer needed, you can delete it locally and remotely.

    git branch -d feature/add-new-content      # Delete local branch
    git push origin --delete feature/add-new-content # Delete remote branch
    

    Explanation: -d is for “delete” a local branch. --delete is for deleting a remote branch.

2.4.7 Step 7: Pulling Changes from Remote

What if a teammate makes changes and pushes them to GitHub? You need to pull those changes to your local repository.

  1. Simulate a change on GitHub:

    • Go to your my-devops-project repository on GitHub.
    • Click on README.md.
    • Click the “pencil” icon to edit the file directly in the browser.
    • Add a new line: This README was updated directly on GitHub.
    • Scroll down and click “Commit changes.”
  2. Pull changes to your local machine: Back in your terminal (ensure you are on the main branch: git checkout main):

    git pull origin main
    

    Explanation: git pull fetches changes from the origin remote’s main branch and automatically merges them into your current local main branch. You should see output indicating that README.md was updated.

  3. Verify the update:

    cat README.md
    

    Explanation: Use cat to display the content of README.md. You should see the new line you added on GitHub.


2.5 Mini-Challenge: Collaborative Feature Development

Let’s put your new skills to the test with a slightly more complex scenario.

Challenge:

  1. On your local machine, create a new branch named challenge/add-project-plan.
  2. Switch to this new branch.
  3. Create a new file named project-plan.md.
  4. Add at least three lines of text to project-plan.md describing a simple plan for a DevOps project (e.g., “Define project scope,” “Set up version control,” “Automate deployments”).
  5. Commit these changes with a meaningful message.
  6. Push your challenge/add-project-plan branch to GitHub.
  7. Go to GitHub, navigate to your repository, and create a Pull Request from your challenge/add-project-plan branch into the main branch.
    • Hint: GitHub will usually show a banner prompting you to create a Pull Request after you push a new branch.
  8. Review your own Pull Request (pretend you’re a teammate).
  9. Merge the Pull Request on GitHub.
  10. Back on your local machine, switch to your main branch and git pull the changes from GitHub.
  11. Verify that project-plan.md now exists on your local main branch.

What to observe/learn:

  • You’ve just simulated a basic collaborative workflow: developing on a separate branch, proposing changes via a Pull Request, and integrating them into the main codebase after review (even if you reviewed yourself!). This is a core loop in DevOps teams.

2.6 Common Pitfalls & Troubleshooting

Even experienced developers encounter Git issues. Here are a few common ones and how to approach them:

  1. Merge Conflicts:

    • Scenario: Two people (or you on two different branches) modify the same lines in the same file, and Git can’t automatically decide which change to keep during a merge.
    • Symptom: CONFLICT (content): Merge conflict in <filename>. Git will add special markers (<<<<<<<, =======, >>>>>>>) to the conflicted file.
    • Solution:
      1. Open the conflicted file in a text editor.
      2. Manually edit the file to resolve the conflict, choosing which changes to keep or combining them.
      3. Delete the <<<<<<<, =======, >>>>>>> markers.
      4. git add <filename> (to stage the resolved file).
      5. git commit -m "Resolved merge conflict in <filename>".
  2. Forgetting git add:

    • Scenario: You make changes, run git commit, and then realize your changes weren’t included.
    • Symptom: nothing to commit, working tree clean or no changes added to commit.
    • Solution: Always run git status to see what’s happening. If files are under “Changes not staged for commit,” you need git add <filename> (or git add . for all changes in the current directory and subdirectories) before committing.
  3. Authentication Issues with GitHub (PATs):

    • Scenario: git push fails with Authentication failed for 'https://github.com/...' or remote: Support for password authentication was removed....
    • Symptom: You’re trying to use your GitHub password instead of a Personal Access Token (PAT).
    • Solution: Ensure you’ve generated a PAT on GitHub with the correct repo scope. When prompted for your password during git push, paste the PAT. For convenience, consider using a Git credential helper to store your PAT securely, so you don’t have to enter it every time.
      git config --global credential.helper store
      # The next push will ask for username/PAT, then store it.
      
      Warning: store saves your PAT in plain text. For better security, especially in production environments, consider cache (which stores for a limited time) or platform-specific credential managers.
  4. Incorrect Remote URL:

    • Scenario: You get an error like fatal: remote origin already exists. or fatal: repository 'https://github.com/...' not found.
    • Symptom: You might have mistyped the URL when adding the remote, or the remote already exists from a previous attempt.
    • Solution:
      • To check existing remotes: git remote -v.
      • To remove an existing remote: git remote remove origin.
      • Then, add the correct remote again: git remote add origin <correct-url>.
      • Ensure the GitHub repository exists and the URL is correct (e.g., https://github.com/your-username/your-repo.git).

2.7 Summary

Congratulations! You’ve successfully navigated the foundational concepts and practical applications of Git and GitHub. You now understand:

  • What Version Control is and why it’s critical for tracking changes and collaboration.
  • The distinction between Git (the local version control tool) and GitHub (the remote hosting platform).
  • The core Git workflow involving the Working Directory, Staging Area, Local Repository, and Remote Repository.
  • Essential Git commands: git init, git status, git add, git commit, git log, git remote add, git push, git pull, git branch, git checkout, and git merge.
  • How to set up Git, configure your identity, and interact with a remote repository on GitHub using Personal Access Tokens (PATs) for secure authentication.
  • The importance of branching and merging for isolated development and integrating changes.
  • Common troubleshooting techniques for merge conflicts and authentication issues.

Version control is the bedrock of modern software development and a non-negotiable skill for any DevOps professional. With these skills, you’re well-equipped to manage your code effectively and collaborate seamlessly within a team.

What’s Next? In our next chapter, we’ll build upon this foundation by exploring Continuous Integration and Continuous Delivery (CI/CD). You’ll learn how to automate the process of building, testing, and deploying your code every time you push changes to your Git repository, taking your DevOps journey to the next level!


References


This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.