The RK Times
← All posts
DevOps

Git – Versioning System

By Romaan · Jun 9, 2026 · 6 min read · 2 views

Git is one of the most fundamental and essential tools in software development today. It is indispensable for every software engineer — and useful to anyone who wants to track their work in increments, collaborate on projects, and progress safely.

Git is a distributed version control system: every clone is a full copy of the repository and its entire history. Below is a practical, command-by-command checklist for everyday work.

Configuration

# Configure your name
git config --global user.name "Your Name"

# Configure your email
git config --global user.email "your@email.com"

# Check your configuration
git config --list

Basic commands

# Initialise a new repository
git init

# Clone a repository
git clone -b <branch-name> <repo-url> <folder-name>

# Check the status of files
git status

# Stage files
git add <path>

# Remove a file
git rm <path>

Remotes

A remote is a named reference to a hosted copy of the repository (usually called origin).

# List configured remotes
git remote -v

# Add a remote called "origin"
git remote add origin <repo-url>

# Change a remote's URL
git remote set-url origin <repo-url>

# Download new commits/branches without merging
git fetch origin

# Fetch + merge the current branch's upstream
git pull

# Push and set the upstream (so later you can just "git push")
git push -u origin <branch-name>

Inspecting history

# Compact, graphical history
git log --oneline --graph --decorate --all

# See what changed
git diff                 # unstaged changes
git diff --staged        # staged changes
git show <commit>         # one commit's diff

# Who last changed each line of a file
git blame <path>

Commits

# Commit
git commit -m "Meaningful Message"

# Amend commit (Amend by adding files)
git commit --amend --no-edit

# Amend commit message
git commit --amend -m "New message"

# Undo last commit (Keep changes)
git reset --soft HEAD~1

# Undo commit and unstage changes
git reset --mixed HEAD~1

# Remove commit and changes completely
git reset --hard HEAD~1

Common types

  • feat: → new feature
  • fix: → bug fix
  • docs: → documentation
  • refactor: → code improvement
  • test: → tests
  • chore: → maintenance

Undoing changes

reset moves a branch (rewrites history), while revert records a new commit that undoes an old one — use revert on branches you have already pushed.

# Discard unstaged changes to a file (restore from last commit)
git restore <path>

# Unstage a file but keep the changes
git restore --staged <path>

# Discard ALL local changes in the working tree (careful!)
git restore .

# Safely undo a commit on a shared branch (creates a new "revert" commit)
git revert <commit>

# Remove untracked files and directories
git clean -fd

Recovering lost work (reflog)

Git records every move of HEAD, so commits “lost” after a bad reset or rebase are almost always recoverable.

# Show the history of HEAD movements
git reflog

# Restore your branch to a previous state from the reflog
git reset --hard HEAD@{2}

Tags

# Create a lightweight tag
git tag <tag>

# Create an annotated tag (recommended for releases)
git tag -a <tag> -m "Message"

# Tag a specific past commit
git tag -a v1.0.0 <commit-hash> -m "Release"

# List tags
git tag

# Push one tag / all tags
git push origin <tag>
git push origin --tags

# Delete a tag locally, then on the remote
git tag -d <tag>
git push origin --delete <tag>

Branches

# Create and switch to a new branch
git checkout -b <branch-name>      # or: git switch -c <branch-name>

# Switch to an existing branch
git checkout <branch-name>         # or: git switch <branch-name>

# List branches (-a includes remote branches)
git branch -a

# Push a branch and set its upstream
git push -u origin <branch-name>

# Merge another branch into the current one
git merge <other-branch>

# Replay the current branch on top of another (linear history)
git rebase <base-branch>

# Delete a branch locally, then on the remote
git branch -d <branch-name>
git push origin --delete <branch-name>

Merge, rebase & conflicts

Merge joins two branches with a merge commit and preserves history exactly. Rebase replays your commits on top of another branch for a clean, linear history. Golden rule: never rebase commits you have already pushed and shared.

# A merge or rebase stops when there is a conflict:
git status                 # list the conflicting files

# Edit each file to resolve the conflict markers, then stage it:
git add <resolved-files>

git merge --continue       # or: git rebase --continue

# Or bail out and return to the previous state:
git merge --abort          # or: git rebase --abort

.gitignore

List files and patterns Git should never track in a .gitignore file at the repository root.

# Dependencies
node_modules/
venv/

# Build output
dist/
*.log

# Secrets & local env
.env
*.key

# OS / editor cruft
.DS_Store
.idea/

Cherry-pick

Apply an individual commit from one branch onto your current branch.

# Apply one commit onto the current branch
git cherry-pick <commit-hash>

# Apply a range of commits (exclusive..inclusive)
git cherry-pick <start-hash>..<end-hash>

Stash

# Save uncommitted changes and clean the working tree
git stash push -m "WIP: short description"

# List the stashes
git stash list

# Show the files in a stash (or its full patch)
git stash show --name-only stash@{0}
git stash show -p stash@{0}

# Re-apply the latest stash AND remove it from the list
git stash pop

# Re-apply a stash but keep it in the list
git stash apply stash@{0}

# Delete one stash / clear them all
git stash drop stash@{0}
git stash clear

Squash commits

# Squash the last 2 commits
git rebase -i HEAD~2

# A text editor opens listing your last two commits.
# Change "pick" to "squash" (or just "s") for the second (newer) commit, then save.

Git Worktree

Worktrees let you have multiple working directories linked to the same repository, so you can check out several branches simultaneously without repeated branch switching or re-cloning. This is ideal for parallel development, hotfixes, and isolated testing.

# List active worktrees
git worktree list

# Add a worktree
git worktree add <path> <remote>/<branch>

# Remove a worktree
git worktree remove <path>

Git Submodules

When your project depends on another project that is itself a Git repository, submodules let you embed it at a pinned commit. Think of it as a soft link to another repo — analogous to a symlink on a Linux filesystem.

# Add a submodule
git submodule add <git-url> <directory>

# Clone a repo together with its submodules
git clone --recurse-submodules <repo-url>

# Initialise + fetch submodules in an already-cloned repo
git submodule update --init --recursive

# Pull the latest commits for every submodule
git submodule update --remote

A typical feature-branch workflow

git switch -c feature/login        # branch off main
# ...make changes, committing in small steps...
git add -p
git commit -m "feat: add login form"
git push -u origin feature/login   # open a Pull Request from here
git switch main && git pull         # keep main up to date

Comments (0)

Be the first to comment.