Chapter 1: Introduction to Version Control

Chapter Objectives

By the end of this chapter, you will be able to:

  • Define what a Version Control System (VCS) is and why it’s crucial in software development and other collaborative projects.
  • Identify and differentiate between the three main types of Version Control Systems: Local, Centralized, and Distributed.
  • Understand the historical context and the reasons behind Git’s creation.
  • Explain the core Git concepts: Repository, Working Directory, and Staging Area (also known as the Index).
  • Appreciate the benefits of using a VCS for tracking changes, collaboration, and project management.

Introduction

Welcome to the first chapter of your journey into mastering Git! Before we dive into the specific commands and workflows of Git, it’s essential to understand the fundamental problem that Git and other Version Control Systems (VCS) solve. Imagine working on a complex project, whether it’s writing code, a book, or designing a product. How do you keep track of changes over time? What if you introduce an error and need to revert to a previous, stable version? How do multiple people collaborate on the same project files without overwriting each other’s work?

These are the challenges that Version Control Systems are designed to address. This chapter introduces the concept of version control, explores its different models, provides a brief history of Git, and defines some foundational terms that you’ll encounter throughout this book. Understanding these core ideas is the first step towards effectively using Git for projects of any scale.

Theory

What is a Version Control System?

A Version Control System (VCS), also known as a Revision Control System (RCS) or Source Code Management (SCM) system, is a software tool that helps manage changes to a collection of files over time. It records modifications to files in a special kind of database called a repository. These changes can then be recalled later.

Think of it like an “undo” button for your entire project, but much more powerful. A VCS allows you to:

  • Revert files back to a previous state: If you make a mistake or an experiment doesn’t work out, you can easily go back to an earlier version.
  • Revert the entire project back to a previous state: Not just individual files, but the whole project can be rolled back.
  • Compare changes over time: See what has changed between different versions.
  • Understand who introduced an issue and when: Track who made specific changes and when they were made, which is invaluable for debugging.
  • Work concurrently: Allow multiple team members to work on the same project, and even the same files, simultaneously without stepping on each other’s toes.
  • Branch and Merge: Create isolated lines of development (branches) to work on new features or fixes without affecting the main project. Later, these changes can be merged back.

Using a VCS is a cornerstone of modern software development and is increasingly used in many other fields where digital documents are created and revised, such as technical writing, legal document drafting, and academic research.

Why is Version Control Important?

Without version control, managing projects, especially collaborative ones, can become chaotic. Common non-VCS methods include:

  • Saving multiple copies of files (e.g., report_v1.doc, report_v2.doc, report_final.doc, report_final_really_final.doc). This is prone to errors, confusion, and consumes a lot of disk space.
  • Manually merging changes from different collaborators, which is time-consuming and highly error-prone.

A VCS automates and streamlines this process, providing:

  • A single source of truth: The repository acts as the authoritative history of the project.
  • Traceability: Every change is logged with who made it, when, and (ideally) why.
  • Collaboration efficiency: Team members can work independently and integrate their changes systematically.
  • Reduced risk: The ability to revert to known good states minimizes the impact of errors.
  • Branching for experimentation: Safely explore new ideas without destabilizing the main project.

Types of Version Control Systems

There are three main categories of Version Control Systems:

Local Version Control Systems (LVCS)

  • These were some ofthe earliest VCS tools. They operate on a single computer.
  • The system maintains patch sets (i.e., the differences between file versions) in a database, also stored on the local disk.
  • Example: RCS (Revision Control System).
  • Pros: Simple, better than manually copying files.
  • Cons: Prone to disk failure (single point of failure), not suited for collaboration.
%%{
  init: {
    "theme": "base",
    "themeVariables": {
      "primaryColor": "#EDE9FE",
      "primaryTextColor": "#5B21B6",
      "primaryBorderColor": "#5B21B6",
      "lineColor": "#A78BFA",
      "textColor": "#1F2937",
      "fontSize": "14px",
      "fontFamily": "Open Sans"
    },
    "flowchart": {
      "nodeSpacing": 60,
      "rankSpacing": 60,
      "curve": "basis"
    }
  }
}%%
graph TD;
    subgraph User's Computer
        direction LR
        User[<b>User</b>];
        WorkDir["Working Directory<br>(Files V1, V2, V3)"];
        VCS_DB["VCS Database<br>(Patch Sets on Disk)"];
    end

    User -- "Edits Files" --> WorkDir;
    WorkDir -- "Saves Version / Check-in" --> VCS_DB;
    VCS_DB -- "Restores Version / Check-out" --> WorkDir;

    style User fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style WorkDir fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style VCS_DB fill:#EDE9FE,stroke:#5B21B6,stroke-width:2px,color:#5B21B6;

    classDef default fill:#transparent,stroke:#1F2937,stroke-width:1px,color:#1F2937,font-family:'Open Sans';

Centralized Version Control Systems (CVCS)

  • Slower operations for commits, branching, and merging compared to DVCS, as they often require communication with the central server.
  • CVCSs were developed to address the collaboration needs that LVCSs couldn’t meet.
  • They use a single central server that stores all the versioned files and the history.
  • Collaborators check out files from this central server to their local computers, work on them, and then commit their changes back to the central server.
  • Examples: Subversion (SVN), CVS (Concurrent Versions System), Perforce.
  • Pros: Easier collaboration than LVCS, administrators have fine-grained control over who can do what.
  • Cons:
    • Single point of failure: If the central server goes down, nobody can collaborate or save versioned changes.
    • Network dependency: Developers need to be connected to the network to commit changes or retrieve history.
%%{
  init: {
    "theme": "base",
    "themeVariables": {
      "primaryColor": "#EDE9FE",
      "primaryTextColor": "#5B21B6",
      "primaryBorderColor": "#5B21B6",
      "lineColor": "#A78BFA",
      "textColor": "#1F2937",
      "fontSize": "14px",
      "fontFamily": "Open Sans"
    },
    "flowchart": {
      "nodeSpacing": 70,
      "rankSpacing": 70,
      "curve": "basis"
    }
  }
}%%
graph TB;
    CentralServer["💾<br><b>Central VCS Server</b><br>(Main Repository & History)"];
    
    subgraph Developer A
        direction TB
        UserA[👩‍💻<br>Developer A];
        WorkCopyA["📂<br>Working Copy A"];
    end

    subgraph Developer B
        direction TB
        UserB[👨‍💻<br>Developer B];
        WorkCopyB["📂<br>Working Copy B"];
    end

    subgraph Developer C
        direction TB
        UserC[👩‍💻<br>Developer C];
        WorkCopyC["📂<br>Working Copy C"];
    end

    UserA -- "Edits" --> WorkCopyA;
    WorkCopyA -- "Commit / Push" --> CentralServer;
    CentralServer -- "Checkout / Pull" --> WorkCopyA;

    UserB -- "Edits" --> WorkCopyB;
    WorkCopyB -- "Commit / Push" --> CentralServer;
    CentralServer -- "Checkout / Pull" --> WorkCopyB;
    
    UserC -- "Edits" --> WorkCopyC;
    WorkCopyC -- "Commit / Push" --> CentralServer;
    CentralServer -- "Checkout / Pull" --> WorkCopyC;

    style CentralServer fill:#EDE9FE,stroke:#5B21B6,stroke-width:2px,color:#5B21B6;
    style UserA fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style WorkCopyA fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style UserB fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style WorkCopyB fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style UserC fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style WorkCopyC fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    
    classDef default fill:#transparent,stroke:#1F2937,stroke-width:1px,color:#1F2937,font-family:'Open Sans';

Distributed Version Control Systems (DVCS)

  • DVCSs are the most modern and flexible type of VCS. Git is a DVCS.
  • In a DVCS, every collaborator gets a full copy (a clone) of the entire repository, including its complete history. This means each user has their own local repository.
  • Operations like committing, viewing history, creating branches, and merging are typically much faster because they are performed locally.
  • Collaboration happens by pushing changes from one local repository to another, or to a shared remote repository, and pulling changes from others.
  • Examples: Git, Mercurial, Bazaar.
  • Pros:
    • Full local history: Most operations are local and fast.
    • Improved collaboration: Multiple workflows are possible (e.g., peer-to-peer, centralized-style with a “blessed” remote repository).
    • No single point of failure (for history): If a server dies and developers have local copies, the history is not lost. Any clone can be used to restore the central server.
    • Offline work: Developers can commit changes, browse history, and create branches even when offline.
  • Cons:
    • Can be slightly more complex to understand initially due to the distributed nature.
    • The initial clone can take longer for very large projects with extensive history, as the entire history is downloaded.
%%{
  init: {
    "theme": "base",
    "themeVariables": {
      "primaryColor": "#EDE9FE",
      "primaryTextColor": "#5B21B6",
      "primaryBorderColor": "#5B21B6",
      "lineColor": "#A78BFA",
      "textColor": "#1F2937",
      "fontSize": "14px",
      "fontFamily": "Open Sans"
    },
    "flowchart": {
      "nodeSpacing": 60,
      "rankSpacing": 60,
      "curve": "basis"
    }
  }
}%%
graph TD;
    RemoteServer["☁️<br><b>Optional Remote Server</b><br>(Shared Repository)"];

    subgraph Developer A's Computer
        direction TB
        UserA[👩‍💻<br>Developer A];
        LocalRepoA["🗄️<br>Local Repository A<br>(Full History)"];
        WorkDirA["📂<br>Working Dir A"];
        UserA -- "Edits" --> WorkDirA;
        WorkDirA -- "Commit" --> LocalRepoA;
        LocalRepoA -- "Checkout" --> WorkDirA;
    end
    
    subgraph Developer B's Computer
        direction TB
        UserB[👨‍💻<br>Developer B];
        LocalRepoB["🗄️<br>Local Repository B<br>(Full History)"];
        WorkDirB["📂<br>Working Dir B"];
        UserB -- "Edits" --> WorkDirB;
        WorkDirB -- "Commit" --> LocalRepoB;
        LocalRepoB -- "Checkout" --> WorkDirB;
    end

    LocalRepoA -- "Push / Pull (Clone)" --> RemoteServer;
    RemoteServer -- "Push / Pull (Clone)" --> LocalRepoA;
    LocalRepoB -- "Push / Pull (Clone)" --> RemoteServer;
    RemoteServer -- "Push / Pull (Clone)" --> LocalRepoB;
    LocalRepoA -. "Push / Pull (Peer-to-Peer)" .-> LocalRepoB;


    style RemoteServer fill:#EDE9FE,stroke:#5B21B6,stroke-width:2px,color:#5B21B6;
    style UserA fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style LocalRepoA fill:#EDE9FE,stroke:#5B21B6,stroke-width:1px,color:#5B21B6;
    style WorkDirA fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style UserB fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    style LocalRepoB fill:#EDE9FE,stroke:#5B21B6,stroke-width:1px,color:#5B21B6;
    style WorkDirB fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;

    classDef default fill:#transparent,stroke:#1F2937,stroke-width:1px,color:#1F2937,font-family:'Open Sans';
Feature Local VCS (LVCS) Centralized VCS (CVCS) Distributed VCS (DVCS)
Repository Location Local machine only Single central server Full copy on each collaborator’s machine
Collaboration Very difficult; not designed for it Relies on connection to central server Flexible; peer-to-peer or via remote(s)
Offline Work Possible for local history Limited; need server for most operations (commit, branch, history) Fully capable; commit, branch, merge, view history offline
Speed Fast (local operations) Slower for server-dependent operations Very fast for most operations (local)
Single Point of Failure Local disk failure loses everything Central server is a single point of failure No single point of failure for history (if multiple clones exist)
Branching/Merging Rudimentary or non-existent Can be complex and slow Generally fast, efficient, and a core feature
Examples RCS Subversion (SVN), CVS, Perforce Git, Mercurial, Bazaar
Typical Use Case Individual developer, simple projects (historical) Teams needing central control, legacy systems Modern software development, open-source projects, complex workflows

A Brief History of Git

Git was created by Linus Torvalds, the creator of the Linux kernel, in 2005. The Linux kernel project is massive, with thousands of contributors. For many years, the kernel development community used a proprietary DVCS called BitKeeper. However, in 2005, the relationship between the community and the company that developed BitKeeper broke down, and the tool’s free-of-charge status was revoked.

This prompted Linus Torvalds to develop his own VCS with the following goals in mind:

  • Speed: Git is designed to be extremely fast.
  • Simple design: Though the internals can be complex, the conceptual model is relatively straightforward.
  • Strong support for non-linear development (thousands of parallel branches): Essential for a large project like the Linux kernel.
  • Fully distributed: Allowing for flexible workflows.
  • Able to handle large projects like the Linux kernel efficiently (speed and data size).

Git was born out of necessity and quickly gained popularity not just for the Linux kernel but across the entire software development world due to its speed, flexibility, and powerful branching capabilities.

Core Git Concepts

Before you start using Git commands, it’s crucial to understand three fundamental areas or states that your files can reside in when working with a Git project:

Repository (Repo)

The repository is the heart of Git. It’s a database where Git stores all the changes, history, and metadata for your project. The repository is typically contained in a hidden subdirectory named .git at the root of your project directory. This .git directory contains all the information about your project’s history, branches, tags, and configuration. You generally don’t interact with the files inside .git directly; Git commands manage it for you. When you clone a project from a remote server, you are downloading this .git directory along with the project files.

Working Directory (or Working Tree)

The working directory is your local checkout of a specific version of the project. It’s the actual directory on your filesystem where your project files reside and where you do your work (edit, create, delete files). These files are pulled out of the compressed database in the .git directory and placed on disk for you to use or modify. It is essentially your sandbox. Any changes you make here are not automatically part of the project’s history until you explicitly tell Git to record them.

Staging Area (or Index)

The staging area is an intermediate area that holds information about what will go into your next commit. It’s a file, generally contained in your Git directory (.git/index), that stores information about what will go into your next commit. Think of it as a draft space for your next commit. You use the staging area to selectively choose which changes in your working directory you want to include in the next snapshot of the project’s history. You add changes from your working directory to the staging area. Then, you commit the staged changes, which permanently records them in the repository’s history.

The basic Git workflow involves these three areas:

  1. You modify files in your working directory.
  2. You selectively stage the changes you want to be part of the next commit by adding them to the staging area.
  3. You perform a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git repository (.git directory).
%%{
  init: {
    "theme": "base",
    "themeVariables": {
      "primaryColor": "#DBEAFE",
      "primaryTextColor": "#1E40AF",
      "primaryBorderColor": "#2563EB",
      "lineColor": "#A78BFA",      
      "textColor": "#1F2937",
      "fontSize": "14px",
      "fontFamily": "Open Sans",
      "git0": "#EDE9FE", "gitBranch": "#5B21B6", "gitFontColor": "#5B21B6",
      "git1": "#D1FAE5", "gitCommit": "#059669",
      "git2": "#FEF3C7", "gitTag": "#D97706",
      "git3": "#DBEAFE",
      "git4": "#FEE2E2"
    },
    "flowchart": {
      "nodeSpacing": 50,
      "rankSpacing": 70,
      "curve": "basis"
    }
  }
}%%
graph LR;
    WD["📄<br><b>Working Directory</b><br>(Your project files,<br>make edits here)"];
    SA["📋<br><b>Staging Area (Index)</b><br>(Tracked changes<br>ready for commit)"];
    REPO["📦<br><b>Repository (.git)</b><br>(Project history,<br>commits, branches)"];
    WD -- "1 Modify files" --> WD;
    WD -- "2 <code style='font-family:monospace; background:#E0E7FF; padding:2px 4px; border-radius:3px; color:#3730A3;'>git add <files></code><br>(Stage changes)" --> SA;
    SA -- "3 <code style='font-family:monospace; background:#E0E7FF; padding:2px 4px; border-radius:3px; color:#3730A3;'>git commit</code><br>(Record snapshot)" --> REPO;
    REPO -- "<code style='font-family:monospace; background:#E0E7FF; padding:2px 4px; border-radius:3px; color:#3730A3;'>git checkout <branch/commit></code><br>(Switch versions, restore files)" --> WD;
    
    style WD fill:#DBEAFE,stroke:#2563EB,stroke-width:2px,color:#1E40AF;
    style SA fill:#FEF3C7,stroke:#D97706,stroke-width:2px,color:#92400E;
    style REPO fill:#EDE9FE,stroke:#5B21B6,stroke-width:2px,color:#5B21B6;
    classDef default fill:#transparent,stroke:#1F2937,stroke-width:1px,color:#1F2937,font-family:'Open Sans';

Practical Examples

While this chapter is primarily theoretical, let’s perform a couple of simple actions to see these concepts in a very basic form. We assume you have Git installed. If not, Chapter 2 will cover installation.

Checking Your Git Version

First, let’s verify that Git is installed and see which version you have. Open your command-line interface (Terminal on macOS/Linux, Git Bash or PowerShell with Git on Windows).

Bash
git --version

Expected Output (will vary depending on your Git version):

Bash
git version 2.43.0

Explanation of Output:

This command simply prints the installed version of Git. It’s a good first step to ensure Git is accessible from your command line.

Initializing a New Repository

Let’s create a new directory for a sample project and initialize a Git repository within it.

  1. Create a new directory and navigate into it:mkdir my-first-git-project cd my-first-git-project
  2. Initialize a Git repository:git init

Expected Output:

Bash
Initialized empty Git repository in /path/to/your/my-first-git-project/.git/

(The path will reflect your actual directory structure.)

Explanation of Output:

The git init command creates a new Git repository. It does this by creating a new subdirectory named .git that contains all of your necessary repository files – a Git repository skeleton. At this point, your project is being tracked, but you haven’t committed any versions of your files yet.

If you list the contents of your my-first-git-project directory, including hidden files (e.g., ls -a on Linux/macOS, dir /a in Windows Command Prompt, or Get-ChildItem -Force in PowerShell), you will see the .git directory.

Bash
ls -a

Expected Output (on Linux/macOS):

Bash
. .. .git

This .git directory is your local repository. Your my-first-git-project directory is currently your working directory. Since we haven’t created any files or told Git to track any files, the staging area is empty.

Checking the Status

Let’s see what Git thinks about the state of our new repository.

Bash
git status

Expected Output:

Bash
On branch master # Or 'main' depending on your Git version/configuration

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Explanation of Output:

  • On branch master (or main): This tells you the current branch Git is on. We’ll cover branches in detail later.
  • No commits yet: Confirms that no snapshots have been saved to the repository’s history.
  • nothing to commit...: Indicates that the working directory is clean (no modified tracked files) and the staging area is empty. It also hints at the next steps: create files and use git add to stage them.

Let’s create a file and see how git status changes.

  1. Create a simple file:# On Linux/macOS touch README.md # On Windows (PowerShell) New-Item README.md # Or using a text editor, create README.md with some text
  2. Check the status again:git status

Expected Output:

Bash
On branch master # Or 'main'

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        README.md

nothing added to commit but untracked files present (use "git add" to track)

Explanation of Output:

Now, Git sees a new file (README.md) in your working directory. It’s listed under “Untracked files” because Git hasn’t been told to track changes to this file yet. The message “use git add <file>… to include in what will be committed” is Git’s way of telling you how to move this file to the staging area.

These simple examples give you a first glimpse of the repository, working directory, and the concept of staging changes. We will build extensively on these in the upcoming chapters.

Command Description When to Use (in Chapter 1 context)
git –version Checks the installed version of Git. To verify Git installation and its accessibility from the command line.
git init Initializes a new Git repository in the current directory. To start tracking a new project with Git. Creates the .git subdirectory.
git status Shows the current state of the working directory and staging area. To see which files are modified, staged, or untracked. Essential for understanding what Git is aware of.
git add <file> Adds file contents from the working directory to the staging area (index). To prepare changes for the next commit. Use this after creating new files or modifying existing ones you want to save.
git commit -m “message” Records a snapshot of the staged changes to the repository’s history. The -m flag allows for an inline commit message. To save your staged changes permanently. (Note: Commits are introduced conceptually in Ch1, detailed usage comes later).

OS-Specific Notes

Git is fundamentally cross-platform, and its core commands behave identically across Windows, macOS, and Linux. However, there are a few minor points to be aware of:

  • Command-Line Interface:
    • Windows: You’ll typically use Git Bash (which provides a Unix-like environment), PowerShell, or the Command Prompt. Git Bash is often recommended as it provides better compatibility with commands and scripts written for Linux/macOS.
    • macOS: The built-in Terminal application (using Zsh or Bash) is standard.
    • Linux: Various terminal emulators are available (GNOME Terminal, Konsole, xterm, etc.), typically using Bash or Zsh.
  • Path Separators:
    • Windows uses backslashes (\) as path separators (e.g., C:\Users\YourName\Project).
    • macOS and Linux use forward slashes (/) (e.g., /home/yourname/project).
    • Tip: Git is generally smart enough to handle path separators correctly, especially if you use forward slashes within Git commands, even on Windows. Git Bash on Windows uses forward slashes.
  • Line Endings:
    • A common source of cross-platform issues is line endings. Windows uses a carriage return and a line feed (CRLF) to mark the end of a line, while macOS and Linux use only a line feed (LF).
    • Git has a configuration option (core.autocrlf) to handle this automatically.
      • On Windows, it’s often recommended to configure Git to convert LF endings to CRLF when checking out files, and CRLF to LF when committing files (git config --global core.autocrlf true).
      • On macOS/Linux, it’s often recommended to configure Git to convert CRLF to LF on commit (git config --global core.autocrlf input).
    • We will discuss Git configuration in more detail in a later chapter. For now, be aware that default settings during Git installation usually handle this reasonably well.
  • Case Sensitivity:
    • Filesystems on Linux are typically case-sensitive (File.txt and file.txt are different files).
    • Filesystems on macOS (by default APFS/HFS+) and Windows (NTFS) are typically case-insensitive but case-preserving (File.txt and file.txt are the same file, but the original capitalization is stored).
    • This can lead to issues if developers on different OSs use different casings for filenames. Git has a configuration option (core.ignorecase) which is usually set appropriately for the OS during installation. It’s best practice to be consistent with filename casing.

Tip: While GUI tools like Sourcetree, GitKraken, or the integrated Git support in VS Code exist and are popular, understanding the CLI is fundamental. GUI tools are essentially providing a visual interface to these same underlying Git commands.

Common Mistakes & Troubleshooting Tips

Git Issue / Error Symptom(s) Troubleshooting / Solution
Forgetting to Initialize Running commands like git add or git commit results in:
fatal: not a git repository (or any of the parent directories): .git
Solution: Navigate to your project’s root directory and run git init to create the .git sub-directory.
Confusing Working Directory, Staging Area, and Repository Saving a file in your editor doesn’t mean it’s in the next commit or part of Git’s history. Changes don’t appear in git log. Solution: Remember the two-step process:
  1. Use git add <filename> to stage changes.
  2. Use git commit -m “message” to save staged changes to the repository.
Use git status frequently to check.
Typing Git commands outside a Git repository Similar to forgetting to initialize:
fatal: not a git repository… when trying to run project-specific commands.
Solution: Ensure your command line is in the correct project directory (the one containing .git). Use pwd (or cd on Windows) to check/change directory.
Unexpected Behavior Due to Line Endings (Cross-Platform) git diff shows entire files changed. More frequent merge conflicts between Windows, macOS, and Linux users. Solution: Configure core.autocrlf appropriately.
  • Windows: git config –global core.autocrlf true
  • macOS/Linux: git config –global core.autocrlf input
(Covered more in Git configuration).
New files not being committed You created a new file, ran git commit -m “message” (perhaps with -a), but the new file isn’t in the commit. Solution: New files must be explicitly added to the staging area using git add <new_file_name> before they can be committed. git commit -a only stages and commits modified *tracked* files.

Exercises

  1. Your First Repository:
    1. Create a new directory on your computer named learning-git.
    2. Navigate into this learning-git directory using your command-line interface.
    3. Initialize a new Git repository here.
    4. Verify that the repository was created by listing the directory contents (including hidden files/folders).
    5. Create a new file named hello.txt inside learning-git using a text editor or a command-line tool. Add the text “My first version controlled file!” to it.
    6. Use git status to see how Git perceives this new file. What does Git tell you about hello.txt?
  2. Understanding States:
    1. Continuing from Exercise 1, in the learning-git directory, add the hello.txt file to the staging area.
    2. Run git status again. How has the output changed? What does Git now tell you about hello.txt?
    3. (Optional Challenge – we haven’t formally covered commits yet) If you’re feeling adventurous, try to commit the staged file with the message “Initial commit”. Then run git status one more time. What does it say now?

Summary

In this chapter, we’ve laid the essential groundwork for understanding version control and Git:

  • Version Control Systems (VCS) are tools that track and manage changes to files over time, enabling easy rollbacks, collaboration, and history tracking.
  • There are three main types of VCS:
    • Local VCS: Operates on a single machine.
    • Centralized VCS (CVCS): Uses a central server to store history; collaborators check out and commit to this server.
    • Distributed VCS (DVCS): Each collaborator has a full local copy of the repository and its history. Git is a DVCS.
  • Git was created by Linus Torvalds for Linux kernel development, emphasizing speed, distributed nature, and strong branching capabilities.
  • Key Git concepts include:
    • Repository (.git directory): The database storing all project history and metadata.
    • Working Directory: The user’s local checkout of project files where modifications are made.
    • Staging Area (Index): An intermediate area where changes are prepared before being committed to the repository.
  • The basic workflow is: Modify files (Working Directory) -> Stage changes (git add) -> Commit changes (git commit).
  • Git commands are generally consistent across OSs, but be mindful of terminal differences, path separators, and line endings.

Further Reading

This foundational knowledge will serve you well as we delve into more practical Git commands and workflows in the subsequent chapters.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top