BSCS students taking a Software Engineering or Version Control elective course — or anyone who simply needs to learn Git properly — can read the complete textbook “Pro Git” by Scott Chacon and Ben Straub, free from its official source. It’s a 10-chapter, example-driven guide that takes readers from installing Git and making their first commit all the way through branching, distributed workflows, GitHub, advanced tools, and Git’s own internal object model.
This edition is published directly on git-scm.com, the official website of the Git project itself, and covers everything from Git basics and branching (Chapters 1–3) through running a Git server and distributed collaboration workflows (Chapters 4–5), GitHub specifically (Chapter 6), advanced tools and customization (Chapters 7–8), interoperating with other version control systems (Chapter 9), and a deep dive into Git internals (Chapter 10) — making it both a gentle introduction for beginners and a lasting reference for advanced use.
Book Overview
| Course | Software Engineering / Version Control |
| Degree Programs | BSCS and any program’s Software Engineering or Version Control elective course, and a general-purpose reference for any course requiring Git |
| Level | University — beginner-friendly start, building to advanced internals |
| Edition | 2nd Edition (2014, continuously updated on the official site, git-scm.com/book) |
| Author | Scott Chacon and Ben Straub |
| Structure | 10 chapters — from Git basics and branching through server setup, distributed workflows, GitHub, advanced tools, customization, interoperability with other version control systems, and Git’s internals (three backmatter appendices are reference material, not counted as chapters) |
| Exercises | No formal end-of-chapter exercise sets; the book is example-driven throughout, with commands demonstrated on realistic scenarios readers can follow along with in their own repository |
| Language | English |
| License | CC BY-NC-SA 3.0 (Creative Commons Attribution-NonCommercial-ShareAlike) — Model: Link-only |
| Format | Free, complete official HTML/PDF/EPUB editions (also available as a paid print edition from Apress) |
Chapter List
Chapter 1: Getting Started
Difficulty: Beginner · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: what version control is, a short history of Git, Git basics and its three states, installing and first-time configuration
This opening chapter explains what version control is and why Git in particular is built the way it is: Git stores snapshots of the whole project rather than file-by-file deltas, almost every operation is local, and Git’s data has integrity guaranteed by SHA-1 hashing of every change. It walks through Git’s three states (modified, staged, committed) and the three main sections of a Git project (working tree, staging area, .git directory), then covers installing Git on different platforms and first-time setup with git config.
Key Points:
- Git tracks snapshots of the entire project at each commit rather than storing file-by-file differences the way older version control systems do.
- Nearly all Git operations are local, since almost the entire history is available on disk, which is why Git is fast and mostly usable offline.
- Every file and commit in Git is checksummed with a SHA-1 hash before it is stored, and Git refers to data by that hash, making silent corruption effectively impossible.
- Git generally only adds data; most actions add new data to the repository rather than deleting or overwriting anything, which makes it hard to lose committed work.
- A file in a Git project is in one of three states: modified, staged, or committed, corresponding to the working tree, the staging area (index), and the .git directory.
Memory Tip: Run git config –global user.name and user.email exactly once per machine right after installing Git — nearly every later confusing error about commit authorship traces back to skipping this one-time setup step.
Common Mistake: Treating Git like a traditional delta-based version control system and assuming it stores differences between file versions — Git actually stores a full snapshot of every tracked file at each commit (deduplicating unchanged files internally), which is part of why the three-states model behaves differently from other tools.
Important Questions:
- Q1. How does Git’s approach to storing project history differ from most other version control systems? Most version control systems store information as a list of file-based changes (deltas) over time. Git instead thinks of its data as a series of snapshots of the whole project’s file tree at each commit; if a file hasn’t changed, Git just stores a reference to the previous identical file rather than storing it again, so Git behaves more like a mini filesystem of snapshots than a delta-based changelog.
- Q2. What are Git’s three main states a file can be in, and what do they correspond to? A file is modified, staged, or committed. Modified means the file has been changed but not yet saved to the database; staged means a modified file has been marked, in its current version, to go into the next commit snapshot (via the staging area/index); committed means the data is safely stored in the local .git database as part of a commit.
Chapter 2: Git Basics
Difficulty: Beginner · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: creating and cloning repositories, recording changes, viewing history, undoing things, remotes, tagging, aliases
This chapter covers the everyday Git commands needed to work productively: initializing a repository or cloning an existing one, checking status and staging changes, committing, viewing history with git log, undoing mistakes (amending commits, unstaging, discarding local changes), working with remote repositories (adding, fetching, pulling, pushing), tagging releases, and setting up Git aliases for frequently used commands.
Key Points:
- git init creates a new repository in an existing directory, while git clone copies an existing repository, including its full history, from elsewhere.
- git status shows the state of the working directory and staging area; git add stages changes, and git commit records the staged snapshot permanently.
- git log displays commit history and accepts many options (-p for patches, –stat for a diffstat, –oneline, –graph) to control how history is shown.
- Undoing changes has different tools for different stages: git commit –amend for the last commit, git restore –staged to unstage, and git restore/checkout to discard working-directory changes.
- Remote repositories are managed with git remote (add/show/rename/remove), and synchronized with git fetch (download only), git pull (fetch plus merge), and git push (upload local commits).
- Git supports lightweight tags (a simple pointer to a commit) and annotated tags (a full object with tagger, date, and message), created with git tag.
Practice Tip: Get in the habit of running git status before and after nearly every other Git command while learning — it explains exactly what state the working directory and staging area are in and even suggests the next command to run, which makes the three-states model concrete instead of abstract.
Common Mistake: Using git add . carelessly and staging files that were never meant to be tracked (build artifacts, secrets, editor files) — a .gitignore file should be set up early in a project so untracked files that should stay untracked are excluded automatically instead of relying on manual care every time.
Important Questions:
- Q1. What is the difference between git fetch and git pull? git fetch downloads new commits and branches from a remote repository into the local repository’s remote-tracking branches, but does not merge or change any of the local working branches. git pull does the same fetch and then immediately runs a merge (or, depending on configuration, a rebase) to integrate the fetched changes into the current local branch, so pull is essentially fetch plus an automatic integration step.
- Q2. What is the difference between a lightweight tag and an annotated tag in Git? A lightweight tag is just a pointer to a specific commit, essentially a branch that never moves. An annotated tag is a full object stored in the Git database, including the tagger’s name and email, the date, a tagging message, and optionally a GPG signature; annotated tags are generally recommended for anything meant to mark an actual release, since they carry this extra metadata.
Chapter 3: Git Branching
Difficulty: Intermediate · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: what a branch is, basic branching and merging, branch management, branching workflows, remote branches, rebasing
This chapter covers Git’s branching model, often considered its standout feature: a branch is simply a lightweight movable pointer to a commit, so creating and switching branches is cheap and fast. It works through creating, merging, and deleting branches; resolving merge conflicts; managing and inspecting branches; common branching workflows (long-running branches, topic branches); how remote-tracking branches work; and rebasing as an alternative to merging for integrating changes, including the trade-offs and the rule of never rebasing commits already pushed to a shared remote.
Key Points:
- A Git branch is just a lightweight, movable pointer to a specific commit, which is why creating a new branch in Git is a fast, cheap operation compared to some other version control systems.
- git merge combines the work of two branches, either with a simple fast-forward pointer move or by creating a new merge commit with two parents when the branch histories have diverged.
- A merge conflict occurs when the same part of a file was changed differently on both branches being merged; Git marks the conflicting regions in the file for the user to resolve manually before completing the merge.
- Remote-tracking branches (like origin/main) are local references that represent the state of branches on a remote repository as of the last time it was communicated with, and only update on fetch/pull/push.
- git rebase replays a branch’s commits on top of another base commit one at a time, producing a linear history, but should never be used on commits that have already been pushed to a repository others are using.
Memory Tip: Picture a branch as a sticky note on one specific commit, not as a container holding a set of commits — the sticky note just moves forward automatically each time a new commit is made while that branch is checked out, which is the whole mechanism behind Git’s branching.
Common Mistake: Rebasing commits that have already been pushed to a shared remote branch — rebasing rewrites commit history by creating new commits with new hashes, so anyone else who has already pulled the original commits will run into a confusing, diverged history; the golden rule is to only rebase commits that exist solely in a local, not-yet-shared branch.
Important Questions:
- Q1. Why is creating a branch in Git considered a cheap, fast operation? Because a branch in Git is nothing more than a small file containing a 40-character (or newer, 64-character) commit hash — creating one just writes a new pointer file rather than copying any project files, unlike some other version control systems where branching can involve copying the entire codebase into a new directory.
- Q2. What is the key practical difference between merging and rebasing when integrating one branch’s changes into another? Merging creates a new merge commit that ties the two branches’ histories together, preserving exactly what happened and when, including both branches’ original commits. Rebasing instead replays the branch’s commits one by one on top of the new base, producing new commits with new hashes and a clean, linear history, but it rewrites history in the process, which is why it is unsafe to do on commits already shared with others.
Chapter 4: Git on the Server
Difficulty: Intermediate · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: the protocols (Local, HTTP, SSH, Git), getting Git on a server, generating SSH public keys, setting up the server, Git daemon, Smart HTTP, GitWeb, GitLab, hosted options
This chapter covers how to run Git as a server so remote repositories can actually be shared, starting with the four available transport protocols (Local, HTTP, Secure Shell, and the Git protocol) and their respective trade-offs around ease of setup, security, and speed. It walks through setting up a bare repository on a server, generating and managing SSH keys for authentication, running the anonymous Git daemon, Smart HTTP for combined read/write access over HTTP, self-hosted web interfaces like GitWeb and GitLab, and a note that most users choose a hosted third-party option instead of self-hosting.
Key Points:
- Git supports four main transport protocols for talking to a remote repository: Local (a shared filesystem), HTTP (Dumb and Smart), the Git protocol (fast but with no authentication), and SSH (authenticated and widely used).
- A bare repository (created with git init –bare) has no working directory and is meant purely to be pushed to and pulled from, which is the standard shape for a repository hosted on a server.
- SSH access is the most common authenticated transport for Git servers, relying on public/private key pairs rather than passwords for each user who needs push/pull access.
- Smart HTTP allows both read and write access over standard HTTP(S), can be firewall-friendly and can layer standard HTTP authentication and encryption (HTTPS) on top of it, unlike the older Dumb HTTP protocol.
- Rather than self-hosting a Git server, most individuals and teams use a hosted service (the book uses GitHub as its running example) to avoid the maintenance overhead of running their own server infrastructure.
Practice Tip: Before setting up any self-hosted Git server, generate an SSH key pair (ssh-keygen) and test a plain ssh login to the target server first — most Git-over-SSH setup problems are actually general SSH configuration problems, and it’s much faster to debug that layer separately.
Common Mistake: Confusing a normal working repository with a bare repository when setting one up on a server — pushing to a non-bare repository’s currently checked-out branch can silently fail to update the working directory or be refused outright, which is why server-side repositories are conventionally created with git init –bare instead.
Important Questions:
- Q1. What is the key difference between Dumb HTTP and Smart HTTP as Git transport protocols? Dumb HTTP requires no Git-specific logic on the server at all (it just serves the bare repository’s files as static content) but supports read-only access and is slow, since the client has to individually reconstruct history. Smart HTTP uses a Git-aware process on the server to negotiate the transfer efficiently the same way SSH does, supports both push and pull, and can use standard HTTP authentication and HTTPS encryption, which is why nearly all modern Git hosting uses it.
- Q2. Why does the book recommend a bare repository (git init –bare) for a server-side Git repository? A bare repository has no working directory, just the .git contents, since a server-side repository is meant only to be pushed to and fetched from, not directly edited in place. Pushing to a non-bare repository’s checked-out branch is fragile (Git won’t let you push to the currently checked-out branch by default, to avoid overwriting a user’s uncommitted work), so bare repositories avoid this problem entirely.
Chapter 5: Distributed Git
Difficulty: Intermediate · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: distributed workflows, contributing to a project, maintaining a project
This chapter covers how Git’s distributed nature enables collaboration workflows that a purely centralized version control system can’t easily support: centralized workflows, integration-manager workflows (fork-and-pull, as popularized by GitHub), and dictator-and-lieutenants workflows used by very large projects like the Linux kernel. It then works through the practical mechanics from both sides of a contribution: how a contributor commits, formats, and submits changes (including via email patches or pull requests), and how a project maintainer applies, reviews, and integrates incoming work.
Key Points:
- Because every clone of a Git repository has the complete history, Git supports many collaboration topologies (centralized, integration-manager, dictator-and-lieutenants) rather than forcing one fixed workflow.
- The integration-manager workflow, where a contributor forks a repository, pushes to their own copy, and opens a pull request, is the dominant pattern on hosted platforms like GitHub.
- Commit message quality matters for collaboration: a good commit message has a short summary line, a blank line, and a more detailed explanatory body describing why a change was made, not just what changed.
- git format-patch and git am let changes be shared and applied as email-based patches, still used by projects (such as the Linux kernel) that prefer a mailing-list-based contribution workflow over pull requests.
- A project maintainer typically works from a stable main branch plus integration branches for testing incoming contributions before merging them into the branch that gets released.
Memory Tip: Write every commit message as if explaining the change to a future maintainer with zero context: a short imperative summary line, then a blank line, then the reasoning — “what” is visible in the diff already, so the message’s real job is explaining “why.”
Common Mistake: Submitting one giant commit (or pull request) that bundles several unrelated changes together — this makes review, bisecting, and reverting much harder; the book recommends keeping commits small and topically focused, one logical change per commit.
Important Questions:
- Q1. What is the integration-manager workflow, and why is it common on platforms like GitHub? In the integration-manager workflow, a contributor forks the main project into their own copy, makes changes and pushes them there, then requests that the maintainer of the original (‘blessed’) repository pull those changes in, typically via a pull request. It’s common on hosted platforms because it lets any number of contributors work independently without needing direct push access to the main repository, while still giving the maintainer full control over what gets merged.
- Q2. What does the book recommend about commit message structure, and why? A good commit message starts with a short (usually under about 50 characters) summary line written in the imperative mood, followed by a blank line, followed by a more detailed body explaining the motivation and context for the change. This matters because tools like git log –oneline and GitHub’s interface show only the summary line by default, and the diff itself already shows what changed, so the message’s real value is explaining why the change was needed.
Chapter 6: GitHub
Difficulty: Beginner · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: account setup, contributing to a project, maintaining a project on GitHub, managing an organization, scripting GitHub
This chapter is a practical, platform-specific tour of GitHub built on top of the general Git concepts from earlier chapters: setting up an account and SSH keys, contributing to someone else’s project through the fork-and-pull-request flow, and maintaining a project of your own on GitHub, including issues, pull-request review tools, and notifications. It also covers managing GitHub organizations for teams, and using GitHub’s API and hub/gh command-line tools to script common GitHub actions.
Key Points:
- GitHub adds a hosted layer of collaboration tooling (issues, pull requests, code review comments, notifications) on top of plain Git, rather than changing how Git itself works underneath.
- The standard contribution flow on GitHub is: fork the target repository, clone your fork locally, make and commit changes on a branch, push to your fork, then open a pull request against the original repository.
- Pull requests support inline code review comments, suggested changes, required status checks, and review approvals before a maintainer merges, giving structure to the integration-manager workflow from the previous chapter.
- GitHub organizations let multiple people collaborate under a shared account with configurable team-based permissions, distinct from a single personal account owning a repository.
- GitHub exposes a REST (and GraphQL) API, and command-line tools built on it, so routine GitHub actions like opening issues or pull requests can be scripted instead of done manually through the web UI.
Practice Tip: Practice the full fork → clone → branch → commit → push → pull-request cycle on a small throwaway repository before doing it for real on a project that matters — the mechanics are simple once done once, but easy to fumble the first time under pressure.
Common Mistake: Committing directly on the fork’s default branch (often main/master) instead of a dedicated topic branch before opening a pull request — this makes it awkward to keep contributing further unrelated changes cleanly and to keep the fork in sync with the upstream project later.
Important Questions:
- Q1. What is the standard sequence of steps for contributing to someone else’s project on GitHub? Fork the target repository into your own GitHub account, clone that fork to your local machine, create a new branch for the change, commit the work on that branch, push the branch to your fork on GitHub, and then open a pull request from that branch against the original (‘upstream’) repository, so its maintainer can review and merge it.
- Q2. What does a GitHub organization add compared to a single personal GitHub account owning a repository? A GitHub organization is a shared account multiple people can belong to, with configurable team-based permissions controlling who can read, write, or administer which repositories. This lets a company or open-source project manage access for many contributors in a structured way, rather than every repository being tied to and administered by one individual’s personal account.
Chapter 7: Git Tools
Difficulty: Advanced · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: revision selection, interactive staging, stashing and cleaning, signing work, searching, rewriting history, reset demystified, advanced merging, rerere, debugging, submodules, bundling, replace, credential storage
This long, reference-style chapter covers Git features beyond everyday basics that become useful as a project or workflow grows more advanced: precise ways to specify commits and ranges (revision selection), interactively staging only parts of a file’s changes, stashing and cleaning the working directory, cryptographically signing tags and commits, searching history and code, rewriting history with interactive rebase and filter-repo, a detailed explanation of exactly what git reset does at each of its three levels, advanced merge strategies and options, rerere for reusing recorded conflict resolutions, debugging with git bisect and blame, submodules for embedding one repository inside another, and Git’s credential storage helpers.
Key Points:
- Revision selection syntax (like HEAD~3, branch..other, or a partial SHA-1) lets a specific commit, range of commits, or set of commits be referenced precisely on the command line.
- git add -p (interactive/patch staging) lets part of a modified file’s changes be staged while leaving the rest unstaged, useful for splitting one messy set of edits into several focused commits.
- git stash temporarily shelves uncommitted changes so the working directory can be cleaned up (for example, to switch branches) without committing unfinished work, and the stash can later be reapplied.
- git reset operates at three levels — –soft (moves HEAD only), –mixed (also resets the staging area, the default), and –hard (also resets the working directory) — each undoing progressively more.
- git bisect performs a binary search through commit history, automatically narrowing down which exact commit introduced a bug given a known-good and a known-bad commit.
- A submodule embeds one Git repository as a subdirectory of another, pinned to a specific commit, letting a project depend on an exact version of another repository’s history.
Memory Tip: Remember reset’s three levels as increasing blast radius: –soft touches only where HEAD points, –mixed (the default) also unstages, and –hard also throws away working-directory changes — always double-check which level is being used before running reset on anything with uncommitted work.
Common Mistake: Running git reset –hard without being certain no important uncommitted work exists in the working directory — unlike git stash, a hard reset discards uncommitted changes without saving them anywhere first, so there is no straightforward way to recover them afterward.
Important Questions:
- Q1. What does git bisect automate, and how does it work? git bisect automates finding the exact commit that introduced a regression by performing a binary search over the commit history between a known-good and a known-bad commit. At each step Git checks out a commit roughly halfway between the two, the developer marks it good or bad, and Git narrows the range accordingly, repeating until the exact offending commit is identified — far faster than checking commits one at a time in order.
- Q2. What is a Git submodule, and what problem does it solve? A submodule is a reference, stored inside a parent repository, that embeds another Git repository as a subdirectory pinned to one specific commit. It solves the problem of depending on an external project’s exact code at a known point in its history — rather than copying that code in directly, the parent repository just records which commit of the submodule’s repository to use, and that pinned code can be checked out with git submodule update.
Chapter 8: Customizing Git
Difficulty: Advanced · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: Git configuration, attributes, hooks, an example Git-enforced policy
This chapter covers how to tailor Git’s behavior for a project or environment: the layered configuration system (system, global, and local config files, and how they override each other), gitattributes for controlling how Git treats specific paths (keyword expansion, merge strategies, diff drivers, line-ending normalization), Git hooks (client-side and server-side scripts that run automatically at points in the Git workflow, such as before a commit or after a push), and a worked example of using server-side hooks to enforce a project-specific policy on incoming commits.
Key Points:
- Git configuration is layered across three scopes — system (all users on a machine), global (–global, per user), and local (per repository) — with local settings overriding global, and global overriding system.
- .gitattributes files let specific paths be given special handling, such as normalizing line endings, marking a file as binary, or specifying a custom diff/merge driver for that file type.
- Client-side hooks (like pre-commit, commit-msg, pre-push) run on a developer’s own machine at specific points in their local Git workflow, and are not copied when a repository is cloned.
- Server-side hooks (like pre-receive, update, post-receive) run on the server when commits are pushed, and can be used to enforce policy (such as rejecting non-compliant commit messages) since they can’t be bypassed by the client.
- A common Git-enforced policy pattern is to reject a push at the server using a pre-receive or update hook if incoming commits fail some check, such as an issue-tracker reference or a coding-style rule.
Practice Tip: Write and test a hook script locally as a plain executable shell script in .git/hooks first, before trying to enforce anything server-side — the hook mechanism itself (naming, executability, exit-code semantics) is easier to debug in a throwaway local repository than on a shared server.
Common Mistake: Assuming a client-side hook (like pre-commit) can be used to reliably enforce a policy across a whole team — client-side hooks are not copied when a repository is cloned and can be bypassed or deleted by any individual developer, so real policy enforcement has to happen with server-side hooks instead.
Important Questions:
- Q1. Why can’t a client-side hook like pre-commit be relied on to enforce a policy across an entire team? Client-side hooks live in the local .git/hooks directory of each individual clone, are not part of the tracked repository content, and are therefore never transferred when someone clones or pulls the repository. Any team member can also simply delete, disable, or bypass (with –no-verify) their own local hook, so client-side hooks are useful for personal workflow automation but cannot enforce policy on everyone.
- Q2. What is the difference in scope between –global and local Git configuration, and which one wins if they conflict? –global configuration (stored in ~/.gitconfig) applies to every repository a given user works in on that machine, while local configuration (stored in a repository’s own .git/config) applies only to that one repository. When both set the same setting, the local (repository-specific) value takes precedence over the global one, which itself takes precedence over the system-wide configuration.
Chapter 9: Git and Other Systems
Difficulty: Intermediate · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: Git as a client for other version control systems, migrating to Git
This chapter covers Git’s interoperability with other version control systems: using Git itself as a client to interact with a Subversion server (via git svn) when a team hasn’t fully migrated, and importing history from other systems (Subversion, Mercurial, Perforce, and generic custom importers) into a proper native Git repository. It’s aimed at teams and individuals in the process of adopting Git alongside or in place of an existing version control system, rather than starting a project in Git from scratch.
Key Points:
- git svn lets a developer work against a Subversion repository using familiar Git commands locally, useful during a gradual migration where the canonical repository is still Subversion.
- Importing history from another system into Git is generally preferable to starting fresh, since it preserves the full record of who changed what and why across the project’s lifetime.
- Different source systems need different import approaches: Subversion has fairly mature tooling (git svn) due to its similar centralized-commit model, while systems like Perforce need more custom scripting.
- A generic custom importer can be built using Git’s fast-import mechanism, which accepts a simple, scriptable stream format describing commits, letting essentially any source history format be converted.
- The chapter frames these tools as a bridge during migration, not a long-term way to permanently run Git as a thin client on top of a different underlying system.
Memory Tip: Think of this chapter’s tools as one-way or transitional bridges, not permanent integrations — the end goal in every case described here is a project living natively in Git, with the other system’s tooling used only long enough to get the history across cleanly.
Common Mistake: Treating git svn as a permanent, fully bidirectional replacement for a team’s Subversion workflow rather than a migration aid — it has real limitations and rough edges (such as handling merges) that make it a better fit for a transition period than an indefinite dual-system setup.
Important Questions:
- Q1. What does git svn let a developer do, and in what situation is it useful? git svn lets a developer interact with a Subversion repository using Git commands locally — cloning it into a local Git repository, committing locally, and pushing changes back out as Subversion commits. It’s useful when a team’s canonical, shared repository is still hosted on Subversion but individual developers want to use Git’s local branching, staging, and history tools while that migration is still in progress.
- Q2. Why does the chapter recommend importing existing history when migrating a project to Git, rather than starting a new Git repository with just the current state of the code? Importing preserves the complete record of the project’s development — who made each change, when, and why, across its whole prior history in the old system. Starting fresh with only the current snapshot would permanently lose that historical context, including the ability to bisect, blame, or reference old commits, which is valuable enough that the chapter treats proper history import as the default approach.
Chapter 10: Git Internals
Difficulty: Advanced · BSCS — Software Engineering / Version Control elective, and general-purpose reference for any course requiring Git · Key topics: plumbing and porcelain, Git objects, Git references, packfiles, the refspec, transfer protocols, maintenance and data recovery, environment variables
This capstone chapter goes under the hood of everything covered in the rest of the book: the distinction between Git’s low-level “plumbing” commands and the higher-level “porcelain” commands most users actually run, the three core object types (blob, tree, commit — plus the tag object) that make up Git’s content-addressable object database, how references (branches, tags, HEAD) are just files pointing at object hashes, how packfiles compress the object database for efficient storage and transfer, the refspec syntax controlling what gets pushed/fetched where, an overview of the transfer protocols, and how Git performs maintenance (garbage collection) and can recover data that looks lost.
Key Points:
- Git’s plumbing commands are low-level building blocks (like git hash-object, git cat-file) that operate directly on the object database; porcelain commands (like git commit, git merge) are the higher-level, user-facing commands built on top of them.
- Git’s object database has three core content types — blobs (file contents), trees (directory listings mapping names to blobs/trees), and commits (a pointer to a tree plus metadata and parent commit(s)) — plus annotated tag objects.
- Every object is stored and addressed by the SHA-1 (or newer SHA-256) hash of its content, which is what makes Git’s object database content-addressable and gives it built-in integrity checking.
- References are simply small files (under .git/refs) containing a commit hash; a branch is a reference that moves forward automatically with each new commit, while HEAD is a special reference to the current branch (or commit, in detached HEAD state).
- Git periodically repacks loose objects into compressed packfiles (via git gc) using delta compression between similar objects, which is how a large repository’s full history stays reasonably small on disk.
- Because Git rarely deletes data outright, commits that appear to be lost (for example after a hard reset) are frequently still recoverable from the object database using tools like git reflog or git fsck until garbage collection eventually removes genuinely unreachable objects.
Memory Tip: Everything in Git ultimately reduces to three simple object types linked by hashes — commits point to a tree, trees point to blobs and other trees, and refs point to commits — once that mental model clicks, most of Git’s higher-level behavior stops feeling mysterious.
Common Mistake: Assuming a commit is truly, immediately gone after something like a hard reset or a deleted branch — because Git mostly only adds data and defers actual deletion to periodic garbage collection, the commit object usually still exists in the database and can often be found again via git reflog before gc eventually cleans up unreachable objects.
Important Questions:
- Q1. What are Git’s three core object types, and how do they relate to each other? A blob stores the raw content of a single file. A tree stores a directory listing, mapping file and subdirectory names to blob and tree object hashes respectively, capturing the exact state of a directory structure. A commit points to one tree (the project’s full state at that commit) plus metadata such as the author, message, and the hash of its parent commit(s), which is how the chain of commit history is actually built out of these lower-level objects.
- Q2. Why can a commit often be recovered even after it seems to have been lost, for example by a hard reset? Git objects are rarely deleted outright the moment they become unreachable from any branch or tag — they simply become “dangling” and remain in the object database until an explicit garbage collection (git gc) eventually prunes objects that are both unreachable and old enough. Tools like git reflog (which records where HEAD and branches have recently pointed) or git fsck –unreachable can locate such a commit’s hash, letting it be recovered with a plain git checkout or git branch before it is actually garbage collected.
Read or Download Pro Git for Free
This book is free from its official source — Pro Git is published in full online at git-scm.com, the official Git project site, with free HTML, PDF, EPUB, and mobi editions all available directly from the publisher. A paid print edition also exists from Apress, but the legitimate free way to read or download the complete book is the official page below.
→ Read OnlineHow to Study This Book
Chapters 1–3 (Getting Started, Git Basics, Git Branching) are the essential core — work through them hands-on in an actual repository rather than only reading, since Git’s three-states model and its branching behavior are much easier to internalize by typing the commands than by reading about them.
Chapters 4–6 (Git on the Server, Distributed Git, GitHub) can be read more selectively depending on whether a course focuses on self-hosting Git or on using a hosted platform like GitHub — most students will get the most immediate value from Chapter 6.
Chapter 7 (Git Tools) is intentionally reference-style and long — it is not meant to be read start to finish in one sitting, but returned to whenever a specific advanced need (interactive staging, bisecting a bug, submodules) comes up in practice.
Chapter 10 (Git Internals) rewards revisiting after the earlier chapters are comfortable — concepts like commits, branches, and resets stop feeling like memorized commands once the underlying object model and refs are understood.
Used In These Programs
This book is used as a Software Engineering or Version Control elective text, and as general reference material, in: BSCS and Programming coursework. Browse all Computer Science category books.
Who Should Read This
Pro Git is written for anyone who wants a thorough understanding of Git, from complete beginners who have never used version control to experienced developers who want to understand what’s really happening under the hood of everyday commands. It suits BSCS students taking a Software Engineering or Version Control elective, and is equally useful as a standing reference for any programming course or personal project that requires using Git and, often, GitHub.
Applicable Universities
This book is useful for students at Pakistani universities offering BSCS programs with a Software Engineering or Version Control elective course, including Punjab University, Virtual University, COMSATS, FAST, UET, NUST, GIKI, LUMS, and other HEC-recognized institutions, and for self-learners who want a free, official, comprehensive guide to Git.
FAQs
Is Pro Git free?
Yes. The complete book is free from its official source, published in full at git-scm.com — the official Git project website — in HTML, PDF, EPUB, and mobi formats. A paid print edition also exists from Apress for readers who want a physical copy.
Who wrote Pro Git, and is it an official Git resource?
It was written by Scott Chacon and Ben Straub, and its complete text is hosted directly on git-scm.com, the official website of the Git project itself, making it one of the most authoritative and widely recommended introductions to Git available.
How many chapters does Pro Git have, and how is it organized?
10 chapters, moving from Getting Started and Git Basics (Chapters 1–2) through Git Branching (Chapter 3), running Git on a server and distributed workflows (Chapters 4–5), GitHub (Chapter 6), advanced Git Tools and Customizing Git (Chapters 7–8), interoperating with other version control systems (Chapter 9), and Git Internals (Chapter 10). Three backmatter appendices covering other environments, embedding Git in applications, and a command reference are excluded from this chapter count as reference material rather than chapter content.
Do I need prior version control experience before reading this book?
No. Pro Git is written to be approachable for someone who has never used any version control system, starting from first principles in Chapter 1, while still going deep enough in later chapters (Git Tools, Git Internals) to be genuinely useful for experienced developers who want a deeper understanding of Git.
Does Pro Git cover GitHub specifically, or only Git itself?
Both. Most of the book (Chapters 1–5 and 7–10) covers Git itself, which works the same way regardless of hosting provider, but Chapter 6 is dedicated specifically to GitHub — covering account setup, the fork-and-pull-request contribution flow, maintaining a project, organizations, and scripting GitHub’s API.
What is covered in the Git Internals chapter, and why does it matter?
Chapter 10 explains what Git is actually doing under the hood: its plumbing versus porcelain commands, the blob/tree/commit object model that stores all project history, how references and packfiles work, and how seemingly lost commits can often be recovered. Understanding this makes many of the earlier chapters’ commands (like reset, rebase, and branching) feel like logical consequences of a simple model rather than commands to memorize by rote.
Related Books
- Think Java – Downey & Mayfield (a complementary introductory programming text for students building their first version-controlled projects)
- Operating Systems: Three Easy Pieces – Arpaci-Dusseau (systems-level background useful alongside the command-line and internals-focused parts of Pro Git)
- Database Management System – IT Series (another foundational tool-focused BSCS text, useful alongside Pro Git for a well-rounded software engineering toolkit)
Pro Git is the free, official guide to Git — from first commits and branching through distributed workflows, GitHub, advanced tools, and Git’s own internals, published directly by the Git project itself. Browse more Computer Science books for the rest of your semester.
Pro Git, by Scott Chacon and Ben Straub. Free to read online from its official source, published by the Git project. Licensed under CC BY-NC-SA 3.0. Access for free at https://git-scm.com/book/en/v2
© Copyright Policy
Freebooks.pk is an educational resource for students in Pakistan. Textbooks and other books belong to their respective boards, authors and publishers, and all rights remain with them. If you are the copyright holder of any material on this page and want it changed or removed, please contact us or file a request under our DMCA policy. We review every request and remove reported content promptly.