Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

5.2.2. Git Version Control and Puppet Overview

💡 First Principle: Git stores a graph of snapshots (commits), not diffs. Each commit points to its parent(s), forming a directed acyclic graph. Branches are just movable pointers to commits. This graph structure is why operations like branch, merge, and rebase are cheap — they're just pointer manipulation, not data copying.

Git Essentials:
# Repository initialization
git init                           # Create new repo in current directory
git clone https://github.com/org/repo.git   # Clone remote repo

# Staging and committing
git status                         # Show working tree status
git add file.txt                   # Stage a specific file
git add .                          # Stage all changes
git add -p                         # Interactive staging (review hunks)
git commit -m "Add nginx config"   # Commit staged changes
git commit --amend                 # Modify the most recent commit (before push)

# Branching
git branch                         # List local branches
git branch feature-x               # Create branch
git checkout feature-x             # Switch to branch
git checkout -b feature-x          # Create and switch
git switch -c feature-x            # Modern equivalent
git merge feature-x                # Merge into current branch
git rebase main                    # Rebase current branch onto main
git branch -d feature-x            # Delete merged branch
git branch -D feature-x            # Force delete unmerged branch

# Remote operations
git remote -v                      # List remotes
git remote add origin https://...  # Add remote
git fetch origin                   # Download but don't merge
git pull                           # fetch + merge (or rebase if configured)
git push origin main               # Push main branch to origin
git push --all origin              # Push all branches
git push -u origin feature-x       # Push and set upstream tracking

# History and diffs
git log --oneline                  # Compact history
git log --graph --all --oneline    # Visual branch graph
git diff                           # Unstaged changes
git diff --staged                  # Staged changes (vs last commit)
git show abc1234                   # Show a specific commit
git blame file.txt                 # Line-by-line author history

# Undoing changes
git restore file.txt               # Discard unstaged changes (modern)
git checkout -- file.txt           # Same (legacy)
git restore --staged file.txt      # Unstage a file
git reset HEAD~1                   # Undo last commit (keeps changes, UNSTAGED; use --soft to keep them staged)
git reset --hard HEAD~1            # Undo last commit (discard changes — permanent)
git revert abc1234                 # Create new commit that undoes a commit (safe)
git stash                          # Temporarily save uncommitted changes
git stash pop                      # Restore stashed changes
Git Configuration:
git config --global user.name "Alice Smith"
git config --global user.email "alice@example.com"
git config --global core.editor vim
git config --list                  # Show all config
# Global config: ~/.gitconfig
# Repo config:   .git/config
.gitignore:
# .gitignore file in repo root
*.log                              # All .log files
/build/                            # build directory at root
!important.log                     # Exception: track this log file
**/*.tmp                           # Temp files in any subdirectory
Puppet — Declarative Configuration Management:

Puppet uses a pull model: agents on managed nodes periodically check the Puppet master for their catalog (compiled configuration) and apply it. This is different from Ansible's push model.

# Puppet DSL example — /etc/puppetlabs/code/environments/production/manifests/site.pp
node 'webserver01.example.com' {
  package { 'nginx':
    ensure => installed,
  }

  service { 'nginx':
    ensure  => running,
    enable  => true,
    require => Package['nginx'],  # Don't start until package is installed
  }

  file { '/etc/nginx/nginx.conf':
    ensure  => file,
    source  => 'puppet:///modules/nginx/nginx.conf',
    notify  => Service['nginx'],  # Restart nginx if config changes
    require => Package['nginx'],
  }
}
Ansible vs Puppet — Key Differences:
CharacteristicAnsiblePuppet
ArchitecturePush (SSH)Pull (agent + master)
AgentAgentlessAgent required on nodes
LanguageYAML (playbooks)Puppet DSL (Ruby-based)
TimingOn-demandPeriodic (every 30 min)
Drift correctionManual re-runAutomatic on next agent run
Learning curveLower (YAML)Higher (DSL)

⚠️ Exam Trap (M8): git reset --hard destroys uncommitted work permanently — it cannot be undone. git revert is the safe alternative for undoing committed changes because it creates a new commit that reverses the specified commit, preserving history. Use revert on shared branches; reset only on private local branches before pushing.

CI/CD Pipelines

💡 First Principle: A CI/CD pipeline automates the path from a code commit to a running system, replacing manual build-test-deploy steps with a repeatable, auditable sequence that runs on every change. It is the automation backbone that makes Infrastructure as Code safe to change frequently.

  • Continuous Integration (CI): every commit is automatically built and tested, so integration problems surface within minutes instead of at release time.
  • Continuous Delivery (CD): every change that passes CI is automatically prepared and pushed to a staging environment, but the final production release requires a manual approval gate.
  • Continuous Deployment (CD): goes one step further — every change that passes all automated tests releases to production with no manual gate. The distinction between Delivery and Deployment is exactly that manual approval step.

Pipeline stages and gates: a pipeline runs ordered stages (e.g. build → test → deploy). Each stage is a gate — if the test stage fails, the pipeline stops and the deploy stage never runs, preventing broken code from reaching production.

Artifacts: the built, versioned output of the build stage (a compiled binary, container image, or packaged release) stored and passed to later stages, so the exact thing that was tested is the exact thing that gets deployed.

Shift left: move testing and security checks earlier (left) in the pipeline — catching defects and vulnerabilities at commit time is far cheaper than finding them in production.

GitOps: use a Git repository as the single source of truth for declarative infrastructure. A controller continuously reconciles the live system to match the repo, so changes are made by committing to Git (reviewable, revertible) rather than by hand — and drift is corrected automatically.

⚠️ Exam Trap: Continuous Delivery stops at a manual production gate; Continuous Deployment has no gate. A failed earlier stage (such as tests) must block every later stage.

Reflection Question: Your team's Puppet agent is continuously reverting a manual configuration change you made to /etc/nginx/nginx.conf. After three manual edits, all reverted within 30 minutes, you realize the problem. What is happening and where is the correct place to make the change?

Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications