Getting Started with Git and Version Control

Chapter 2
Git Architecture and Conceptual Model

Diploma in Data science
Getting Started with Git and Version Control   •   Diploma

Git Architecture and Conceptual Model

Introduction

Git is a distributed version control system designed to record changes to files, coordinate work among people, and preserve the history of a project. For data science students, Git is particularly important because projects often contain source code, notebooks, configuration files, documentation, data-processing pipelines, and model specifications. A clear understanding of Git’s architecture prevents common mistakes such as losing work, confusing staged changes with committed changes, or assuming that a branch is a separate copy of a project.

Git is best understood as a system for creating and connecting snapshots. A snapshot records the state of tracked files at a particular point in time. Git does not normally store a complete independent copy of every file for every commit. Instead, it stores content as objects and connects those objects through references and commit history.

Learning Objectives

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

  • distinguish a working tree, staging area, and repository;
  • explain repositories, commits, snapshots, and Git objects;
  • describe the role of hashes in identifying content;
  • explain branches, references, and HEAD;
  • interpret Git history as a directed acyclic graph;
  • trace the movement of changes from editing through committing;
  • apply these concepts when managing a small data science project;
  • identify limitations and professional practices associated with Git.

1. The Three Main Areas of a Git Project

A Git project can be understood as three related areas: the working tree, the staging area, and the repository.

1.1 Working tree

The working tree, also called the working directory, is the set of files and directories currently visible on the user’s computer. It is where a person edits a Python script, changes a notebook, creates a README file, or removes an obsolete configuration file.

The working tree may contain:

  • tracked files, which Git already knows about;
  • modified tracked files, whose contents differ from the latest staged version;
  • untracked files, which exist locally but have not yet been added to Git;
  • ignored files, which match rules in .gitignore and are intentionally excluded.

A working-tree change is not automatically part of project history. Editing a file changes the file on disk, but it does not create a commit.

1.2 Staging area

The staging area, also called the index, is a proposed next snapshot. It allows the user to select precisely which changes will enter the next commit.

For example, suppose a student modifies a data-cleaning function and also adds temporary debugging statements. The student can stage only the data-cleaning change, review it, and commit it without including the debugging statements.

The staging area is therefore not merely an administrative step. It is a boundary between informal local editing and an intentional historical record.

The command git add copies the selected version of a file’s content into the staging area. It does not mean “save permanently” and it does not create a commit. A subsequent edit to the same file changes the working tree but does not change the already staged version until git add is run again.

1.3 Repository

The repository is the data structure in which Git stores project history and related metadata. In a normal working project, the repository is held in the hidden .git directory at the project root.

The repository contains:

  • committed snapshots and the objects needed to reconstruct them;
  • references such as branches and tags;
  • the current HEAD position;
  • configuration and other metadata;
  • logs that help Git record movements of references.

A commit is created from the staging area, not directly from whatever happens to be visible in the working tree. This distinction explains why a file can be modified but not included in a commit.

1.4 The movement of a change

A typical change follows this sequence:

  1. A user edits a file in the working tree.
  2. git diff can show differences between the working tree and the staged state.
  3. git add file.py places the selected version in the staging area.
  4. git diff --staged shows what the next commit would contain.
  5. git commit creates a new commit from the staged snapshot.
  6. The branch reference and HEAD move to the new commit.

The command git status summarizes the relationships among these areas and should be used frequently.

2. Snapshots and Commits

2.1 A snapshot as a project state

A snapshot is a record of the paths and file contents that make up a project at a particular point. If a project contains analysis.py, README.md, and requirements.txt, a snapshot records the versions of those paths that belong to that state.

Git’s snapshot model differs from a simple list of line-by-line changes. A commit can be viewed as a complete project state, even though Git may optimize storage internally and may display differences relative to earlier commits.

This model is useful when restoring a project. Instead of asking Git to replay every historical editing action, a user can request the project state represented by a particular commit.

2.2 What a commit contains

A commit is an object that identifies a project snapshot and records metadata about it. Important commit information includes:

  • a reference to a tree object representing the top-level directory;
  • zero or more parent commit references;
  • the author identity and author time;
  • the committer identity and commit time;
  • the commit message.

The first commit in a repository has no parent. A normal subsequent commit has one parent. A merge commit generally has two or more parents.

A commit does not usually contain the complete text of every file directly. It points to a tree, and the tree points to blobs and other trees. This arrangement separates the description of a project’s directory structure from the contents of individual files.

2.3 Commits and changes

A commit is often described informally as “a change,” but technically it is a snapshot plus metadata. The change shown by git show or git diff is calculated by comparing snapshots. This distinction matters because the same final snapshot can be reached through different sequences of edits, while the commit history records how the project developed.

Good commits are coherent: they represent one understandable purpose, such as “validate missing age values” or “document model evaluation.” Coherent commits are easier to review, revert, test, and explain.

3. Git Objects

Git stores information using four principal object types.

ObjectPurpose
BlobStores the content of a file, without its filename
TreeRepresents a directory and maps names to blobs or subtrees
CommitIdentifies a snapshot, its parent commits, and metadata
TagStores a named, generally permanent annotation referring to an object

A filename is associated with a blob by a tree. Consequently, two different filenames can point to identical blob content, and renaming a file does not require the content itself to be stored again.

A tree can contain entries for files and subdirectories. Subdirectories are represented by other tree objects, producing a hierarchical structure. A commit points to the root tree for the project.

Annotated tags are objects with their own metadata and can point to commits or other Git objects. Lightweight tags are simply references to an object and do not have a separate tag object.

4. Hashes and Content Identity

Git identifies objects using a cryptographic hash of their content and relevant metadata. Historically, Git used SHA-1 object identifiers; modern Git also supports SHA-256 repositories. The exact identifier length and repository format depend on the hash algorithm in use.

A hash behaves as a compact identifier: a small change in the input normally produces a very different output. If an object’s content changes, its object identifier changes. This property supports integrity checking and makes Git objects effectively immutable: Git does not edit an existing commit into a new meaning; it creates a new object.

Hash identifiers are not encryption. A hash does not provide secrecy, and knowing an object identifier does not make the content confidential. Security also depends on repository access controls, transport protection, and careful handling of sensitive information.

Git may display an abbreviated object identifier when the abbreviation is unambiguous in the repository. A shortened identifier should not be treated as universally unique outside that context.

5. References, Branches, Tags, and HEAD

Objects are identified by hashes, but remembering hashes directly would be inconvenient. Git therefore provides references, or refs: human-readable names that point, directly or indirectly, to objects.

5.1 Branches

A branch is commonly a reference that points to a commit. In everyday use, a branch name identifies a line of development. Creating a branch does not duplicate every file in the project. It creates another name pointing to a commit.

When a new commit is made while a branch is checked out, the branch reference normally advances to that new commit. Other branches remain where they were. Thus, branches are lightweight movable labels rather than complete independent copies.

5.2 Tags

A tag gives a meaningful name to an important point, such as v1.0 or submission-2025. Tags are usually intended to remain stable, whereas branches move as development continues. Annotated tags can include a message, tagger identity, and date.

5.3 HEAD

HEAD identifies the currently checked-out position. Usually, HEAD is a symbolic reference to the current branch, and that branch points to the current commit.

For example:

HEAD → main → C3

means that HEAD refers to branch main, and main points to commit C3.

A detached HEAD occurs when HEAD points directly to a commit rather than to a branch reference. This is useful for examining or testing an historical state. New commits made in detached mode are not automatically retained by a named branch, so the user should create a branch if the work needs to continue.

6. The Directed Acyclic Graph Model

Git history is naturally represented as a directed acyclic graph, or DAG. Each commit is a node. A parent relationship is a directed edge from a child commit to its parent. “Acyclic” means that following parent links backward cannot eventually return to the same commit; a commit cannot be its own ancestor.

A linear history might be represented as:

C1 ← C2 ← C3

Here, C2 has parent C1, and C3 has parent C2. The arrows point from newer commits toward their parents.

Branching creates multiple descendants:

C1 ← C2 ← C3

             ↖ C4

More precisely, both C3 and C4 may have parent C2. A merge commit can join development lines by having both C3 and C4 as parents. The result is not a simple list but a graph.

The DAG explains several Git operations:

  • ancestor: a commit reachable by repeatedly following parent links;
  • descendant: a commit that can reach another commit through parent links;
  • fast-forward: moving a branch reference forward when no merge commit is needed;
  • merge: creating a commit with multiple parents when histories diverge;
  • rebase: creating new commits whose changes are reapplied onto a different base, thereby changing commit identities.

Because commit identifiers include parent information, changing a parent changes the identity of the resulting commit and all later descendants based on it. This is why rewriting published history can disrupt collaborators.

7. A Worked Conceptual Example

Consider a student project named sales-model.

  1. The student initializes Git and commits README.md. This creates commit A.
  2. The student adds clean.py and commits it. Branch main moves from A to B.
  3. The student creates branch experiment at B.
  4. On main, the student improves input validation and creates C.
  5. On experiment, the student tests a new feature and creates D.
  6. The student merges experiment into main, creating merge commit E with parents C and D.

The references after the merge are conceptually:

  • main → E;
  • experiment → D;
  • HEAD → main → E.

The repository contains objects for the commits, trees, and file contents. The working tree reflects E after a successful merge. If the student edits clean.py afterward, the working tree changes, but neither main nor E changes until a new commit is made.

This example shows that a branch is a moving name, a commit is an immutable historical object, and the working tree is the current editable state.

8. Applied Case: Reproducible Data Science Coursework

Background

This illustrative case concerns a three-person diploma data science team analysing customer churn. The project contains Python code, Jupyter notebooks, a data dictionary, and model-evaluation reports.

Problem

The team initially stores files in a shared folder. One member overwrites a preprocessing function, another submits a notebook using a different version of the dataset, and no one can confidently identify which code produced the reported accuracy.

Analysis

The central problem is not merely the absence of backups. The team lacks identifiable project states and a record of how those states were produced. Large raw datasets also create storage and privacy concerns.

Approach

The team creates a Git repository and adopts the following structure:

  • src/ for reusable processing and modelling code;
  • notebooks/ for exploratory work;
  • reports/ for generated summaries;
  • README.md for setup and workflow instructions;
  • .gitignore for virtual environments, secrets, caches, and generated files.

Each member works on a branch. Before committing, members inspect git diff and git diff --staged. Commits state one purpose and refer to an issue or task. The team records dataset versions and stores only permitted, suitably small sample data in the repository. Credentials and personally identifiable information are excluded.

Outcome

The team can identify the commit containing a model, compare preprocessing changes, review contributions, and restore an earlier project state. The repository does not by itself guarantee scientific reproducibility: environment versions, random seeds, data provenance, and execution instructions must also be documented.

Learning points

  1. Version control records code and project metadata, not automatically every condition needed for reproducibility.
  2. Staging enables deliberate commits rather than indiscriminate saving.
  3. Branches support parallel work without duplicating the entire repository.
  4. Sensitive data must not be committed merely because Git can store it.
  5. A commit should provide a meaningful, reviewable project state.

9. Practical Inspection Commands

The following commands expose the conceptual model:

CommandMain purpose
git statusSummarizes branch position and working/staged changes
git diffCompares working-tree content with the staged state
git diff --stagedShows changes proposed for the next commit
git log --oneline --graph --decorateDisplays compact commit history and references
git show <commit>Inspects a commit and its associated difference
git branchLists or manages local branch references
git switch <branch>Changes the checked-out branch
git rev-parse HEADDisplays the object identifier currently named by HEAD
git ls-tree <commit>Inspects a commit’s tree entries

Command output should be interpreted rather than memorised. For example, “modified but not staged” means the working tree differs from the index; “changes to be committed” means the index differs from the current commit.

10. Limitations, Governance, and Best Practice

Git is powerful but not a complete data-management or governance system. Important limitations include:

  • repositories can become large when binary files or repeated datasets are committed;
  • removing a secret from the latest commit does not necessarily remove it from all historical objects;
  • Git does not automatically validate scientific correctness;
  • merge conflicts require human interpretation;
  • a local repository is not a substitute for a secure backup or remote collaboration service;
  • access controls and retention policies depend partly on the hosting environment.

For data science work, use .gitignore, environment or dependency files, documented dataset provenance, code review, meaningful commit messages, and protected branches where appropriate. Use specialized systems such as Git Large File Storage or data-versioning tools when project requirements justify them. Never commit passwords, API keys, private records, or regulated data. If a secret is committed, revoke or rotate it and treat the history as potentially exposed.

A professional workflow separates exploratory changes from stable deliverables, tests important code before committing, and records enough context for another person to understand the snapshot. Automated tests and continuous integration can inspect commits, but they supplement rather than replace human review.

Chapter Summary

Git represents project history through immutable objects connected by references. A blob stores file content, a tree represents directory structure, and a commit identifies a snapshot together with its parents and metadata. Hashes identify objects and support integrity, but they are not encryption. Branches and tags are human-readable references; branches normally move, while tags usually identify stable milestones. HEAD identifies the current checked-out position and may refer to a branch or directly to a commit.

The working tree is where files are edited, the staging area is the proposed next snapshot, and the repository stores durable history and metadata. Commits form a directed acyclic graph, allowing linear development, branching, merging, and historical inspection. In data science, Git improves traceability and collaboration, but reproducibility also requires documented environments, data provenance, and responsible treatment of sensitive information.

Key Terms

Repository: The Git-managed database containing objects, references, and metadata.

Working tree: The editable files and directories checked out on a computer.

Staging area: The index holding the proposed contents of the next commit.

Commit: An object identifying a project snapshot, metadata, and parent commits.

Snapshot: The state of tracked project paths at a particular point in history.

Object: A Git-stored unit such as a blob, tree, commit, or tag.

Blob: An object containing file content without its filename.

Tree: An object describing directory contents and paths.

Hash: A computed identifier for Git object content and related information.

Reference: A human-readable name that points to a Git object, usually a commit.

Branch: A movable reference commonly used to identify a line of development.

Tag: A name identifying a significant project state or object.

HEAD: The symbolic name for the currently checked-out position.

Detached HEAD: A state in which HEAD points directly to a commit rather than a branch.

Parent commit: An earlier commit linked from a later commit.

Merge commit: A commit with multiple parents that joins histories.

Directed acyclic graph: A graph with directed relationships and no cycles; Git uses it to represent commit history.

Index: Another name for Git’s staging area.

Working-tree modification: A change on disk that has not necessarily been staged or committed.

Reproducibility: The ability to recreate a result using identified code, data, and environment conditions.

Review Questions

Short Answer Questions

  1. What is the difference between the working tree and the staging area?
  2. What information does a commit contain?
  3. Why are branches described as movable references?
  4. What does HEAD identify?
  5. Name the four principal Git object types.

Long Answer Questions

  1. Explain the complete path of a change from editing a file to creating a commit.
  2. Describe how blobs, trees, and commits combine to represent a project snapshot.
  3. Explain Git’s directed acyclic graph and how branching and merging affect it.
  4. Compare branches and tags, including their typical professional uses.
  5. Discuss why Git alone does not guarantee reproducibility in a data science project.

Analytical / Application Questions

  1. A student stages a notebook, edits it again, and commits without staging the second edit. Which version enters the commit, and why?
  2. A team discovers an API key in an old commit. Analyse the security risk and propose an appropriate response.
  3. Two team members create commits from the same parent on separate branches. Explain the resulting graph and identify when a merge commit may be required.

Multiple Choice Questions with Answers

Question 1

Which Git area contains files as they are currently being edited?

A. The object database

B. The working tree

C. The tag namespace

D. The commit graph

Correct Answer: B. The working tree

Question 2

What does the staging area represent?

A. A backup copy stored on a remote server

B. The complete history of all branches

C. The proposed contents of the next commit

D. Only untracked files

Correct Answer: C. The proposed contents of the next commit

Question 3

Which Git object stores the content of a file without its filename?

A. Blob

B. Tree

C. Commit

D. Reference

Correct Answer: A. Blob

Question 4

What does a commit primarily identify?

A. Only the most recent line changed in a file

B. A project snapshot, metadata, and parent commits

C. A user’s password for the repository

D. A remote server location

Correct Answer: B. A project snapshot, metadata, and parent commits

Question 5

A branch in ordinary Git usage is best described as which of the following?

A. A complete physical copy of every repository file

B. A movable reference to a commit

C. A special type of blob

D. A list of untracked files

Correct Answer: B. A movable reference to a commit

Question 6

What does HEAD normally identify?

A. The oldest commit in the repository

B. The currently checked-out position

C. The largest file in the working tree

D. The default remote server

Correct Answer: B. The currently checked-out position

Question 7

Why is Git commit history called a directed acyclic graph?

A. Files are stored in alphabetical order

B. Commits have directed parent links and cannot be their own ancestors

C. Every branch must contain exactly one commit

D. Git removes all duplicated files automatically

Correct Answer: B. Commits have directed parent links and cannot be their own ancestors

Question 8

Which command shows changes already placed in the staging area?

A. git diff --staged

B. git status --ignored

C. git branch --all

D. git init --bare

Correct Answer: A. git diff --staged

Question 9

If a user edits a file after running git add, what is true?

A. The new edit is automatically committed

B. The staged version remains unchanged until the file is staged again

C. The branch reference moves immediately

D. The repository is deleted

Correct Answer: B. The staged version remains unchanged until the file is staged again

Question 10

Which statement about Git hashes is correct?

A. They encrypt files so that nobody can read them

B. They identify objects and change when the relevant object content changes

C. They are branch names that always move forward

D. They contain only the filename

Correct Answer: B. They identify objects and change when the relevant object content changes

Getting Started with Git and Version Control
Chapter 2 of 14