Git is a distributed version control system created in 2005 for Linux kernel development. A normal Git repository can record history locally without a server. Remotes such as a company Git server, GitHub, GitLab, or Bitbucket are added when repositories need to exchange commits.

Read Version Control first if terms such as repository, commit, or distributed version control are new.

Check Git

git --version

Git’s core workflow is stable, but command options and defaults can vary by installed version and configuration. The examples here choose the initial branch name explicitly instead of assuming a system default.

Start a Repository

There are two common starting points.

Start a new project

mkdir network-configs
cd network-configs
git init -b main

git init creates a .git directory containing the repository’s object database, references, configuration, and other metadata. It does not begin tracking every file in the directory.

Running it near the filesystem root or in a directory containing unrelated files can accidentally place too much content inside one repository. Check the current directory before initializing.

Copy an existing repository

git clone https://github.com/ORG/PROJECT.git
cd PROJECT

git clone creates a new directory, copies repository data, configures the source as a remote named origin, and normally checks out an initial branch. Do not run git init inside the clone.

A normal clone includes project history, but Git also supports shallow, partial, and sparse forms that intentionally copy less data or check out fewer files.

Configure Commit Identity

Git attaches an author name and email address to commits:

git config --global user.name "John Smith"
git config --global user.email "USER_EMAIL"

--global applies the values to repositories used by the current operating-system user. Omit it inside a repository to set values only for that repository:

git config user.name "John Smith"
git config user.email "USER_EMAIL"

Inspect where a value came from:

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

Note: Commit identity is metadata, not authentication. Setting an email does not log in to a hosting service or prove the author’s real-world identity. Authentication for fetching and pushing is configured separately.

Git’s Local Areas

The common three-area model is:

AreaWhat it contains
Working treeFiles currently checked out for editing
Staging area or indexThe file content selected for the next commit
Local repositoryCommits, objects, references, and metadata under .git

HEAD normally identifies the commit currently checked out through the current branch.

flowchart LR
    New["New directory"] -->|"git init -b main"| Repo["Local repository<br/>.git"]
    Existing["Existing repository"] -->|"git clone"| Repo
    Existing -->|"git clone checks out files"| Working["Working tree"]
    Working -->|"git add"| Index["Staging area<br/>index"]
    Index -->|"git commit"| Repo
    Repo -->|"checkout or restore content"| Working

The areas are not three copies that constantly move as a unit. Each represents a different view of project content:

HEAD commit      → last committed snapshot
staging area     → proposed next snapshot
working tree     → current files on disk

Tracked and Untracked Files

  • A tracked path is known to the current Git history or index.
  • An untracked path exists in the working tree but is not in the index.
  • An ignored path matches a rule such as one in .gitignore and is normally hidden from routine untracked-file suggestions.

Use status frequently:

git status
git status --short

git status reports the current branch, staged changes, unstaged changes, untracked files, and relevant upstream information. It does not modify anything.

Stage Content with git add

git add switch1.cfg
git add switch2.cfg

For an untracked file, git add places its current content in the index and makes it eligible for the next commit. For a tracked file, it refreshes the staged content to match the selected working-tree content.

If the file changes again after git add, the staged version and working-tree version can differ:

switch1.cfg in the index       → version selected earlier
switch1.cfg in the working tree → newer edits not yet staged

Inspect both comparisons:

# Working tree compared with the staging area
git diff
 
# Staging area compared with HEAD
git diff --staged

Key Insight: git add selects content for the next commit. It does not upload anything to a remote repository.

Record a Commit

git commit -m "Add initial switch configurations"

The commit records the staged project snapshot and metadata such as:

  • author and committer identity
  • timestamps
  • commit message
  • parent commit or commits
  • a reference to the recorded tree

Git models commits as snapshots. It stores unchanged content efficiently, so this does not mean that every unchanged file is duplicated as a fresh full file for each commit.

The commit is local. It is not published until it is sent to another repository with git push.

Inspect history:

git log --oneline --decorate
git show HEAD

Remove a Tracked File

git rm old-switch.cfg

By default, git rm removes the path from both the working tree and index, staging that deletion for the next commit.

To stop tracking a file but leave the working-tree file in place:

git rm --cached local-settings.cfg

Usually the path should also be added to .gitignore so it is not staged again accidentally.

Ignore Generated or Local Files

A .gitignore file describes untracked paths Git should normally ignore:

# Local credentials and environment configuration
.env
 
# Generated Python environment
.venv/
 
# Generated logs
*.log

Ignoring a path does not remove it from existing history. If a secret was committed, remove it from use and rotate it. History cleanup is a separate, coordinated operation.

Basic Local Workflow

git init -b main
 
git config user.name "John Smith"
git config user.email "USER_EMAIL"
 
git status
git add switch1.cfg switch2.cfg
git diff --staged
git commit -m "Add initial switch configurations"
git log --oneline

At this point the repository is fully usable locally. A remote is optional.

Command Summary

CommandPurpose
git init -b mainCreate a repository with an explicit initial branch name
git clone <url>Create a local repository from another repository
git configRead or write Git configuration
git statusInspect working-tree and index state
git add <path>Stage current path content
git diffCompare working-tree content with the index
git diff --stagedCompare staged content with HEAD
git commitRecord the staged snapshot
git logInspect commit history
git rm <path>Remove a tracked path and stage the deletion

Common Misunderstandings

  • git init creates repository metadata; it does not track files automatically.
  • The staging area describes the next commit, not unfinished work in general.
  • git add can stage new files, modifications, and deletions.
  • A commit is local until it is pushed.
  • A configured author email is not a login credential.
  • A .gitignore rule does not remove a file already tracked or erase old commits.
  • Git tracks content, not whether a configuration was successfully deployed to a device.

TL;DR

  • Use git init for a new local repository and git clone for an existing repository.
  • The working tree contains current files, the index contains the next proposed snapshot, and .git stores repository data.
  • git add stages content; git commit records the staged snapshot locally.
  • git status and the two forms of git diff explain what is changed and what is staged.
  • Remotes and pushing are separate from the local commit workflow.

Resources

Continue with Git Remotes to publish commits and retrieve work from another repository.

Note: Commands and defaults were checked against current Git documentation in July 2026.