Version Control with Git and GitHub/GitLab

Chapter 3
Essential Git Operations

Diploma in DevOps
Version Control with Git and GitHub/GitLab   •   Diploma

Essential Git Operations

Introduction

Git is a distributed version-control system used to record, compare, restore, and collaborate on changes to digital files. It is central to DevOps because reliable delivery depends on knowing what changed, who changed it, why it changed, and which version can be reproduced or deployed. GitHub and GitLab provide collaboration, hosting, review, automation, and security features, but the fundamental operations are performed by Git itself.

A Git repository is more than a folder containing a backup. It is a database of snapshots and relationships between snapshots. Git allows a developer to work locally, create explicit points in project history, compare alternatives, and share selected history with remote repositories. Understanding this local model is essential before using pull requests, CI/CD pipelines, branching strategies, or release automation.

This chapter develops the practical foundations required to install and configure Git, initialize and clone repositories, track and commit changes, inspect history and differences, restore files, and write useful commit messages.

Learning Objectives

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

  • install Git and verify its installation;
  • configure identity and useful global defaults;
  • explain the working tree, staging area, local repository, and remote repository;
  • initialize a repository and clone an existing repository;
  • inspect repository status, differences, and history;
  • stage and commit changes safely;
  • restore unstaged, staged, and committed content appropriately; and
  • apply clear, consistent commit-message conventions.

1. Git’s Four Important Locations

Git operations become easier when the locations involved are distinguished.

LocationPurposeTypical command interaction
Working treeThe checked-out files currently being editedEdit files, git status
Staging area (index)A proposed set of changes for the next commitgit add, git restore --staged
Local repositoryObjects, references, and commit history stored in the .git directorygit commit, git log
Remote repositoryA shared repository hosted on a service such as GitHub or GitLabgit clone, git fetch, git push

A commit records the staged state, not every change currently present in the working tree. This distinction is one of Git’s most important ideas. A developer may modify three files, stage only two, and commit only those two. The third file remains an uncommitted working-tree change.

Git areas and change flow Working treeedit files Staging areaselect changes Local repositorycommit history Remoteshare history git addgit commitgit push git restore --staged git restore
Flow from working tree through staging area to local and remote repositories
Figure: Flow from working tree through staging area to local and remote repositories

Figure: The normal flow of selected changes from the working tree into local and remote history.

The arrows are not irreversible. Changes can be removed from the staging area, and working-tree files can be restored. However, restoration can discard work, so commands should be used only after inspecting the relevant differences.

2. Installing and Configuring Git

Git is available for Windows, macOS, and Linux. Use the official Git distribution or the package manager supported by the operating system. After installation, verify it with:

git --version

The result should display an installed Git version. In a managed laboratory or enterprise environment, installation may be performed by an administrator, but each user still needs an identity configuration.

2.1 Identity configuration

Every commit normally records an author name and email address. Configure them globally for the user account:

git config --global user.name "Amina Patel"
git config --global user.email "[email protected]"

To inspect the configuration:

git config --global --list
git config user.name
git config user.email

The local repository configuration overrides the global configuration. This is useful when a person contributes to repositories requiring a different identity:

git config user.email "[email protected]"

An email address in a commit is not, by itself, proof of account ownership on GitHub or GitLab. Hosting platforms may associate commits with an account only when the commit email is verified or otherwise configured appropriately.

2.2 Practical defaults

Useful settings include:

git config --global init.defaultBranch main
git config --global core.editor "code --wait"
git config --global pull.rebase false

The last setting expresses a policy preference and should be agreed with the team; it is not universally correct. Git’s configuration is layered: system, global, local, and sometimes command-specific settings. When behaviour is unexpected, inspect the effective configuration rather than guessing.

Authentication to a remote host is separate from author configuration. Modern services commonly use SSH keys, credential managers, or access tokens rather than account passwords. Credentials must never be committed into a repository.

3. Creating and Obtaining Repositories

3.1 Initializing a repository

To begin tracking a new project:

mkdir inventory-service
cd inventory-service
git init

git init creates a hidden .git directory containing the repository database and configuration. It does not automatically add files or create a meaningful commit. A typical first commit is:

echo "# Inventory Service" > README.md
git add README.md
git commit -m "docs: add project README"

Do not place one Git repository inside another unintentionally. Nested repositories can be valid, but they require deliberate use of submodules or another dependency mechanism.

3.2 Cloning an existing repository

To obtain a complete working copy from a remote host:

git clone https://github.com/example/inventory-service.git
cd inventory-service

SSH is another common form:

git clone [email protected]:example/inventory-service.git

Cloning normally creates a directory, downloads repository history, checks out the default branch, and records the source repository under the remote name origin. Inspect remotes with:

git remote -v
git branch --show-current

A clone is not merely a download of the latest files. It contains local history, enabling offline inspection and commits. Sharing local commits requires a later push, subject to permissions and branch policies.

4. Tracking Changes and Creating Commits

The basic professional cycle is inspect, select, inspect again, commit, and verify.

4.1 Inspecting status

git status

Status identifies untracked files, modified files, staged changes, and the current branch. It is the safest starting point before most operations.

An untracked file is present in the working tree but is not yet part of Git’s tracked set. A modified tracked file differs from the version recorded in the current commit. A staged file has content selected for the next commit.

4.2 Ignoring unsuitable files

A .gitignore file specifies patterns for files Git should not normally report as untracked. For example:

# Python-generated files
__pycache__/
*.pyc

# Local secrets and environment files
.env

# Build output
build/
dist/

.gitignore does not remove a file already tracked by Git. If a previously tracked generated file must stop being tracked while remaining locally present, use:

git rm --cached path/to/file

Secrets require special care. Ignoring .env prevents accidental addition in ordinary cases, but it does not protect secrets already committed. Exposed credentials must be revoked and rotated; deleting a later copy does not erase them from existing history.

4.3 Staging changes

Stage a particular file:

git add src/app.py

Stage all changes under the current directory:

git add .

Interactive staging allows a developer to choose parts of a file:

git add -p

Interactive staging is valuable when one working-tree session contains unrelated changes. A commit should represent one coherent, reviewable unit rather than an accidental mixture of formatting, debugging, and functional changes.

Always inspect the staged content before committing:

git diff --cached

4.4 Committing

git commit -m "fix: validate empty inventory identifiers"

A commit stores a snapshot of the staged files, metadata, and a reference to its parent commit or parents. It does not automatically include later edits that were not staged. After committing, use:

git status
git log --oneline --decorate --graph -n 5

A commit is local until it is pushed. This separation permits local experimentation and review before sharing.

5. Comparing Files and History

Git provides several complementary forms of inspection.

CommandMain question answered
git diffWhat unstaged changes exist?
git diff --cachedWhat is staged for the next commit?
git diff HEADWhat differs from the current commit, staged and unstaged?
git diff COMMIT1 COMMIT2How do two snapshots differ?
git logWhat commits form the history?
git show COMMITWhat did one commit contain?
git blame FILEWhich commit last changed each line?

A diff is interpreted as an instruction for transforming one version into another. Lines beginning with - are removed from the old version; lines beginning with + are added to the new version. Context lines are shown to locate the change.

Useful history commands include:

git log --oneline --decorate --graph --all
git log --author="Amina"
git log --since="2 weeks ago"
git show --stat HEAD

git blame can help locate the origin of a line, but it should not be used to assign personal fault. Refactoring can move lines, and the author of a line is not necessarily responsible for a defect. History tools are most effective when used to understand design decisions and locate relevant changes.

6. Restoring and Correcting Work

Restoration has different meanings depending on where the unwanted change exists.

6.1 Discarding unstaged working-tree changes

To restore a file to the version in the index or current commit when it is not staged:

git restore path/to/file

This overwrites the working-tree version. If the work may be valuable, copy it elsewhere or use a safer recovery approach first.

6.2 Unstaging a change

To remove a file from the staging area while retaining its working-tree edits:

git restore --staged path/to/file

This is useful when a file was added accidentally or when a commit needs to be narrowed.

6.3 Reverting a published commit

If a commit has been shared, the generally safe corrective operation is:

git revert COMMIT_ID

git revert creates a new commit that reverses the selected commit. It preserves public history and is therefore suitable for collaborative branches.

6.4 Resetting local history

git reset moves the current branch reference and has several modes. A soft reset preserves changes staged; a mixed reset, the default, preserves file content but unstages it; a hard reset changes the working tree and can permanently discard uncommitted work:

git reset --soft HEAD~1
git reset HEAD~1
git reset --hard HEAD~1

These commands are appropriate only when their effects are understood. Rewriting history that other people have already based work on can cause serious coordination problems. Do not use reset --hard as a routine cleanup command.

7. Commit-Message Conventions

A commit message is a communication and maintenance artifact. It should allow a reviewer or future maintainer to understand the purpose of a change without reconstructing the author’s intentions from code alone.

A useful structure is:

<type>: <imperative summary>

<optional explanation of context, reason, and consequences>

Common types include feat for a user-facing capability, fix for a defect correction, docs for documentation, refactor for internal restructuring without intended behaviour change, test for test changes, build for build or dependency changes, and chore for maintenance. Teams may adopt Conventional Commits or a related standard, but consistency within the repository is more important than an arbitrary vocabulary.

Effective messages:

  • begin with a concise imperative verb, such as “Add”, “Fix”, or “Remove”;
  • describe one coherent change;
  • explain why when the reason is not obvious;
  • avoid issue-closing claims unless the repository workflow supports them; and
  • do not include secrets, credentials, or misleading information.

Weak: changes

Stronger: fix: reject duplicate SKU values during import

The subject should be short enough to scan in a log. The body should explain context and trade-offs, not repeat the diff line by line. Commit messages do not replace documentation, tests, or a pull-request description, but they make all three easier to understand.

8. Applied Case: Correcting a Configuration Defect

The following is an illustrative case based on a typical diploma-level DevOps workflow.

Background

A student team maintains an inventory service in a GitLab repository. A developer adds input validation and updates a README in the same working session. Before committing, the developer runs git status and sees both files modified.

Problem

The validation code is ready for review, but the README contains incomplete notes. Committing both changes would create an unclear review unit.

Analysis and approach

The developer first examines both files:

git diff

They stage only the implementation and its tests:

git add src/validator.py tests/test_validator.py
git diff --cached

After verifying that the staged diff contains no debugging output or credentials, they commit:

git commit -m "fix: reject duplicate SKU values during import"

The README remains modified but unstaged. The developer then completes it separately and creates a documentation commit. The team reviews the first commit through a merge request, where automated tests confirm that duplicate identifiers are rejected.

Outcome

The history contains two focused commits. Reviewers can assess the defect correction without unrelated documentation changes, and the README can be revised independently if requirements change.

Learning points

The staging area is a design tool, not a compulsory intermediate nuisance. git diff and git diff --cached answer different questions and should both be used. Focused commits improve review, rollback, release-note generation, and fault isolation.

9. Professional Practice, Governance, and Limitations

Git records content and metadata, but it does not automatically establish that content is correct, secure, licensed, or approved. Teams therefore combine Git with code review, protected branches, automated tests, dependency scanning, secret detection, and access control.

Important governance practices include:

  • protect the default branch from direct unreviewed pushes;
  • require appropriate approvals for production-impacting changes;
  • use least-privilege permissions and short-lived credentials where possible;
  • scan commits and build artifacts for secrets and vulnerable dependencies;
  • define retention and audit requirements for repositories; and
  • document rules for force-pushing and history rewriting.

Git is also not a backup strategy by itself. A repository can be deleted, corrupted, or exposed. Important repositories require controlled remote backups and tested restoration procedures. A public repository may expose personal data, proprietary code, or copyrighted material. Repository visibility and licensing decisions must be deliberate.

Modern hosting platforms use Git events to trigger continuous integration and deployment. A commit may initiate tests, security analysis, packaging, or deployment. This makes commit quality operationally important: a vague or oversized commit complicates diagnosis when a pipeline fails. Automation should not be trusted merely because it is triggered by Git; pipeline permissions and untrusted input must be reviewed to avoid credential exposure or unsafe execution.

Best-Practice Workflow

A disciplined everyday sequence is:

git status
git diff
# edit and test files
git add <intentional-files>
git diff --cached
git commit -m "type: concise imperative purpose"
git status
git log --oneline -n 3

Before pushing, confirm the branch, inspect the commits to be shared, and verify that no credentials or generated artifacts are included. When an operation may destroy work, stop and create a safe copy or inspect with a non-destructive command first.

Chapter Summary

Git models development as a sequence of recorded snapshots. The working tree contains current edits, the staging area selects the next snapshot, the local repository stores commits, and a remote repository enables collaboration. Installation and identity configuration establish the local environment, while git init and git clone create or obtain repositories.

git status, git diff, git diff --cached, git log, and git show provide the primary inspection tools. git add selects changes and git commit records them locally. git restore handles carefully chosen local restoration, while git revert safely reverses a shared commit and git reset should be reserved for understood, usually local, history correction. Clear commit messages and focused commits improve reviewability, traceability, automation, and recovery. Git must be combined with security controls, testing, review, backup, and governance to support dependable DevOps practice.

Key Terms

Git: A distributed version-control system.

Repository: A Git database containing objects, references, and project history.

Working tree: The checked-out files available for editing.

Staging area: The index containing content selected for the next commit.

Commit: A recorded snapshot with metadata and parent relationship(s).

Remote: A named reference to another repository, commonly hosted online.

Clone: The operation that creates a local repository from an existing repository.

Initialize: The operation that creates a new local repository with git init.

Untracked file: A file present in the working tree but not tracked by Git.

.gitignore: A pattern file defining files Git should normally ignore as untracked.

Diff: A representation of differences between two states.

HEAD: The symbolic reference identifying the currently checked-out commit or branch position.

Branch: A movable reference to a line of commit history.

Staging: Selecting content for inclusion in the next commit.

Revert: Creating a new commit that reverses an earlier commit.

Reset: Moving a reference and, depending on mode, changing staging or working-tree state.

Fast-forward: Advancing a reference without creating a new merge commit when no divergent commit exists.

Commit convention: A shared rule for structuring commit subjects and bodies.

Protected branch: A branch governed by rules such as review or status-check requirements.

Credential: Information used to authenticate to a service; it must not be committed.

Review Questions

Short Answer Questions

  1. What is the difference between the working tree and the staging area?
  2. What information does git status provide?
  3. Why does a .gitignore file not remove an already tracked file?
  4. What is the purpose of git diff --cached?
  5. Why is git revert generally safer than rewriting a shared commit?

Long Answer Questions

  1. Explain the complete workflow from editing a file to pushing a reviewed commit to a remote repository.
  2. Compare git restore, git revert, and git reset, including an appropriate use case for each.
  3. Explain how focused commits improve code review, troubleshooting, and release management.
  4. Describe the role of identity configuration, authentication, and repository permissions, and explain why they must be treated as separate concerns.
  5. Discuss the security and governance risks associated with committing secrets or force-pushing shared history.

Analytical / Application Questions

  1. A developer stages a configuration file containing a password and then notices the mistake before committing. What commands and security actions should be considered, and why?
  2. A working tree contains a bug fix, formatting changes, and an unfinished README update. Design a staging and commit sequence that produces a clear history.
  3. A public branch contains a defective commit that has already been pulled by several colleagues. Compare reverting the commit with resetting and force-pushing, and recommend an approach with justification.

Multiple Choice Questions with Answers

Question 1

Which Git area contains changes selected for the next commit?

A. Working tree

B. Staging area

C. Remote repository only

D. Operating-system cache

Correct Answer: B. Staging area

Question 2

Which command shows changes that have been staged but not committed?

A. git diff --cached

B. git log --all

C. git remote -v

D. git branch --show-current

Correct Answer: A. git diff --cached

Question 3

What does git init do?

A. Uploads a project to GitHub

B. Deletes existing project history

C. Creates a new local Git repository

D. Stages every file automatically

Correct Answer: C. Creates a new local Git repository

Question 4

Which command normally creates a new commit that reverses an earlier shared commit?

A. git restore

B. git revert

C. git clone

D. git status

Correct Answer: B. git revert

Question 5

Which statement about .gitignore is correct?

A. It encrypts ignored files

B. It removes all matching files from past commits

C. It prevents Git from normally reporting matching untracked files

D. It prevents tracked files from ever changing

Correct Answer: C. It prevents Git from normally reporting matching untracked files

Question 6

Which command is used to inspect recent history in a compact form?

A. git log --oneline

B. git add --compact

C. git history --short

D. git show --remote-only

Correct Answer: A. git log --oneline

Question 7

A file has been staged accidentally, but its working-tree edits should be retained. Which command is appropriate?

A. git restore --staged file.txt

B. git restore file.txt

C. git reset --hard file.txt

D. git rm file.txt

Correct Answer: A. git restore --staged file.txt

Question 8

Which commit message best follows the conventions described in the chapter?

A. stuff

B. changes made to many files

C. fix: reject duplicate SKU values during import

D. FINAL!!!

Correct Answer: C. fix: reject duplicate SKU values during import

Question 9

What does git clone normally provide?

A. Only an empty directory

B. A local repository and working copy based on an existing repository

C. A deployment to production

D. A new Git hosting account

Correct Answer: B. A local repository and working copy based on an existing repository

Question 10

Why should git diff --cached be inspected before committing?

A. To verify the selected snapshot contains the intended changes

B. To change the remote URL automatically

C. To install Git hooks from the internet

D. To delete all unstaged files

Correct Answer: A. To verify the selected snapshot contains the intended changes

Version Control with Git and GitHub/GitLab
Chapter 3 of 14