Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Managing Repository Setup and Configuration Changes with Git

Hello. In the previous lesson, you developed a recovery workflow for failed APT and dpkg transactions: identify the actual cause, avoid racing package-manager locks, finish pending configuration, repair dependencies deliberately, and verify the final package state.

This lesson begins the Git portion of the Essential Commands domain. Git gives you a local, queryable history of administrative configuration changes. You will learn the two ways to obtain a repository, then use the core operational cycle:

  1. inspect the current state;
  2. stage only the intended configuration change;
  3. commit a descriptive local snapshot;
  4. confirm the working tree is clean.

By the end, you will be able to initialize a safe local repository or clone an existing one, and record a controlled administrative configuration change with git status, git add, and git commit.


Why Git matters for system administration

A configuration change can be technically correct and still become difficult to operate if nobody can answer basic questions later:

  • What changed?
  • When did it change?
  • Which related files changed together?
  • What was the intended purpose?
  • What did the configuration look like before the change?

Git records commits: named snapshots of selected file contents. A commit is local by default. Creating one does not modify a live service, contact a server, upload files, or provide a backup by itself. It simply creates durable history in the repository on the machine where you run it.

There are two normal ways to obtain a Git repository:

  • Initialize an unversioned local directory with git init.
  • Clone an existing repository with git clone.

Use git init when you are deliberately starting tracking for a configuration directory. Use git clone when a repository already exists elsewhere, such as an organization’s configuration repository.

For administration, repository scope is a security decision. Avoid casually running git init /etc and then adding everything: /etc can contain credentials, host keys, certificates, service secrets, and machine-specific data that should not enter version control. Likewise, do not run Git with sudo merely because a configuration file is normally owned by root; it can leave a repository owned by root and complicate normal use.

Instead, use a purpose-built configuration tree, or a carefully chosen lab directory, and stage exact paths rather than indiscriminately staging every file.


The three local areas Git tracks

Git’s everyday workflow involves three related areas:

Area What it contains Administrative meaning
Working tree The ordinary files you edit on disk Your current configuration draft
Staging area (the index) The exact content selected for the next commit Your reviewed change set
Local repository The committed history stored under .git The recorded configuration history
Git’s file-status lifecycle: a file may be untracked, unmodified, modified, or staged; editing, staging, committing, and removing a file move it between these states.

The image is a useful simplification, but the key operational fact is this: git add stages the content as it exists at the moment you run it. It does not merely mark a filename for later inclusion.

Suppose you edit sshd_config.lab, run git add sshd_config.lab, and then edit it again. The first version is staged; the second edit remains only in the working tree. A commit would record the staged version, not automatically the most recent edit. Run git status before committing, and run git add again after any intended post-staging edit.

The status labels have precise meanings:

  • Untracked: Git sees a new file but will not include it in a commit unless you explicitly add it.
  • Modified, not staged: Git already tracks the file, but the working-tree content differs from the staged version.
  • Changes to be committed: the staging area contains content that differs from the latest commit.
  • Clean working tree: the working tree and staging area agree with the latest commit.

git status is therefore the command to run before and after every meaningful Git action. It is not merely a troubleshooting command; it is your change-control dashboard.


Watch the core workflow

The following excerpts from “Git Essentials” by Learn Linux TV demonstrate the workflow in a Linux terminal. The first two excerpts establish a repository and record a commit; the final excerpt shows the alternate cloning path.

Git Essentials

Watch “Git Essentials” from Learn Linux TV for a concise Linux-oriented demonstration of repository creation, staging, committing, and cloning.

Watch initialization to see git init create the hidden .git directory that holds repository metadata and history. Then watch status and commit for the practical sequence of creating a file, checking status, staging it, setting an identity, and committing it. Finally, watch cloning for the alternative of copying an existing remote repository locally. Focus on the distinction between local commits and any later upload to a remote.

Git terminology sometimes causes confusion:

  • Git is the version-control tool running locally.
  • A remote repository is another copy of Git history, often hosted on an internal server or a service such as GitHub or GitLab.
  • A commit records a local snapshot.
  • A push sends commits to a remote. It is intentionally outside this lesson.

In particular, do not equate a local commit with a deployed configuration change. Git records your decision; a separate deployment or file-installation procedure changes a running system.

For a short official reference on initialization and the first commit sequence, use the relevant section of the Pro Git book.

2.1 Git Basics - Getting a Git Repository

Read the Pro Git book’s initialization walkthrough to reinforce what git init creates and how selected files become the first commit.

In the subsection “Initializing a Repository in an Existing Directory,” begin at the sentence “If you have a project directory that is currently not under version control.” Read the initialization workflow. Notice that git init creates repository metadata but does not automatically start tracking the directory’s existing files.


Initialize a controlled configuration repository

The following lab uses a directory under your home directory and a harmless configuration copy. It does not alter the real SSH daemon or any live file under /etc.

First, confirm Git is installed and create an isolated lab directory:

git --version

mkdir -p ~/lfcs-git-lab/ssh
cd ~/lfcs-git-lab
git init
git status

After git init, Git creates a hidden .git directory inside ~/lfcs-git-lab. This directory is the repository database: it stores commits, configuration, and staging information. Do not manually edit or delete it.

On a new repository, git status may report that there are “No commits yet.” The initial branch may be named main, master, or another name set by local Git policy. The branch name is not important for this lesson.

Git also needs an author identity when you create a commit. For this lab, configure it locally, inside this repository only:

git config user.name "Your Name"
git config user.email "you@example.invalid"

git config --get user.name
git config --get user.email

Replace the example values with the identity appropriate for your training environment. The commands above omit --global, so they write repository-specific values. This avoids silently changing the identity used by every Git repository on the host.

Now create a baseline configuration file:

printf '%s\n' \
  'Port 22' \
  'LogLevel INFO' \
  > ssh/sshd_config.lab

git status

At this point, ssh/sshd_config.lab should appear under Untracked files. The file exists in the working tree, but Git has not been told to include it in history.

Stage that one file:

git add -- ssh/sshd_config.lab
git status

The -- separates Git options from paths. It is a useful habit when explicitly naming a file. Status should now list the file under Changes to be committed.

For administrative repositories, explicit paths are safer than reflexively using broad commands such as git add -A. Broad staging can be correct when you have reviewed every change, but it can also capture temporary files, logs, credentials, or unrelated edits. Stage narrowly first; expand scope only when you know every included path belongs in the same change.

Commit the known baseline:

git commit -m "Add SSH configuration baseline"
git status

A good commit message describes the purpose of the snapshot, not merely that “files changed.” The final git status should report a clean working tree. That is the confirmation that the working tree, staging area, and latest commit all agree.


Record one administrative configuration change

Now make a small administrative adjustment to the lab configuration. This change increases SSH logging detail in the lab copy only:

sed -i 's/^LogLevel INFO$/LogLevel VERBOSE/' ssh/sshd_config.lab

git status

Git should report that ssh/sshd_config.lab is modified but not staged. The change is visible in your working tree, but it is not yet selected for the next commit.

Stage the intended update and check status again:

git add -- ssh/sshd_config.lab
git status

Then commit it:

git commit -m "Increase SSH daemon log detail"
git status

This completes the essential Git change-recording cycle:

  1. You changed the file in the working tree.
  2. git status identified the pending modification.
  3. git add -- ssh/sshd_config.lab selected the exact revised content.
  4. git commit -m ... recorded that staged content as a local historical snapshot.
  5. A final git status verified that no unintended work remains pending.

The configuration is still not active anywhere. If this were a real SSH configuration, you would separately validate its syntax and follow a safe deployment procedure before restarting or reloading a remote-access service. Git is the evidence trail for the change, not a substitute for validation or deployment.

For a compact status view during routine work, use:

git status --short

Its two status columns distinguish staging-area state from working-tree state. For example, an M in the second column indicates a tracked file was modified but has not yet been staged. For LFCS-style administration, the normal full git status output is usually clearer until this shorthand becomes familiar.


Clone instead when history already exists

Use git clone when a configuration repository has already been created on a trusted remote server. Run it from a parent directory, not from inside another repository.

cd ~

git clone https://git.example.org/ops/system-config.git system-config
cd system-config

git status

Replace the URL and target name with the repository provided by your organization or lab.

Cloning does several things in one operation:

  • creates the destination directory, here system-config;
  • downloads the repository’s commits and tracked content;
  • creates the .git metadata directory locally;
  • checks out the currently selected version into the working tree;
  • normally records the source remote under the name origin.

After cloning, the same local workflow applies:

# Edit one intended configuration file first.
git status
git add -- PATH/TO/CONFIG
git status
git commit -m "Describe the administrative change"
git status

You can create local commits even if you lack permission to upload them. Uploading changes requires a later git push and appropriate remote authorization; it is separate from creating a correct local commit.

Do not initialize a repository inside a directory that you have already cloned. A clone is already a complete Git repository. Similarly, avoid cloning one repository inside another unless you deliberately understand the implications; nested repositories often lead to confusing status output and accidental omissions.


Operational checklist

Before making a commit that records an administrative change, verify these points:

  • You are in the intended repository and working as the normal repository owner.
  • The repository contains only the configuration content that is appropriate to track.
  • git status identifies the expected changed files.
  • You staged only the paths belonging to this logical change.
  • You have not edited a staged file without running git add again.
  • The commit message explains the administrative intent.
  • git status is clean after the commit.

You now have a disciplined baseline Git workflow for administration. git init starts tracking in a deliberate local directory; git clone obtains an existing repository and its history. git status shows what is pending, git add chooses the exact content for the next snapshot, and git commit writes that snapshot into local history.

Next, you will build on this workflow by comparing and inspecting configuration changes, then restoring or reverting a change without discarding unrelated work.

Can't find a good explanation? Sign up and we'll make it for you

Sign up