freedzhost.cloud

DevOps module 1: the culture, Linux, the shell and Git

Level BeginnerEstimated time 14 hRead first DevOps path: 59 days from commit to productionA word you don't know? Glossary

Fourteen sessions to lay the ground every later tool stands on: the culture that gave DevOps its name, a Linux terminal you are at ease in, scripts that fail loudly instead of silently, and Git used as a team tool, with reviews. The module ends with your first public repository.

Every address in the examples comes from ranges reserved for documentation (RFC 5737: 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) and every domain is example.com or example.org.

Day 1 · 03/11 — What DevOps is, and where it comes from

Goal: tell the story of DevOps in five sentences and name its five pillars.

Theory 1/2: the wall between two teams

For decades, developers ("dev") were measured on how fast they shipped changes, and operations ("ops") on how stable production stayed. One team threw releases over the wall, the other pushed back. In June 2009, at O'Reilly's Velocity conference, John Allspaw and Paul Hammond of Flickr gave the talk "10+ Deploys per Day: Dev and Ops Cooperation at Flickr", at a time when one release a month was considered ambitious. Patrick Debois, a Belgian consultant who could only watch it remotely, organised the first DevOpsDays in Ghent in October 2009; the hashtag shortened to #DevOps and named the movement.

DevOps draws on Agile (2001) and on Lean manufacturing (the Toyota Production System): work flows in small batches, problems are seen early, and the people who build a service also care about running it.

Where was the first DevOpsDays held, in 2009?

  1. San Francisco
  2. Ghent
  3. Berlin
Answer

Ghent, Belgium, in October 2009, organised by Patrick Debois.

What did the 2009 Flickr talk show?

  1. That dev and ops cooperating could deploy more than ten times a day
  2. That ops should approve every release by hand
  3. That containers replace virtual machines
Answer

Frequent, small, safe deployments, made possible by dev and ops working together and by automation.

Theory 2/2: CALMS, five pillars

A common way to describe DevOps is CALMS: Culture (shared responsibility, no blame), Automation (what is repeated is scripted), Lean (small batches, remove waiting), Measurement (decide on data), Sharing (knowledge and tools are shared). The acronym started as CAMS (Damon Edwards and John Willis, 2010); Jez Humble added the L. Note that the first letter is culture: buying a tool does not make a team DevOps.

In CALMS, what does the C stand for?

Answer

Culture. Automation, Lean, Measurement and Sharing follow.

A company buys a CI tool and renames its ops team "DevOps team", nothing else changes. Is it DevOps?

  1. Yes, the tool is the core
  2. No: without shared responsibility and changed ways of working, it is a rename
Answer

No. Tools serve a culture; they do not create it.

Practice (30 min)

  1. Install your Linux machine (see the path page): a Debian or Ubuntu VM, or WSL 2. Update it: sudo apt update && sudo apt upgrade.
  2. Install Git and an editor: sudo apt install git, then check git --version.
  3. Create your notebook folder: mkdir -p ~/devops-notes && cd ~/devops-notes, and a first file day-01.md with the story of DevOps in five sentences, in your own words.
  4. Write the five letters of CALMS and, for each, one example from a job you know (even outside IT).

With your AI: "You are a strict DevOps tutor. Ask me five short questions, one at a time, on the origins of DevOps (Flickr 2009, DevOpsDays Ghent, CALMS). Wait for my answer each time, tell me if it is right, and correct me with one sentence. Do not give the answers in advance."

Recap (10 min)

Three lines: the problem DevOps answers, who named it and when, what CALMS means. Then redo the two multiple-choice questions without notes.

Day 2 · 04/11 — Measuring delivery: flow and the DORA metrics

Goal: name the DORA metrics and say what each measures.

Theory 1/2: the three ways

Gene Kim's novel The Phoenix Project (2013) and The DevOps Handbook (2016) describe three ways: flow (work moves fast from idea to production, in small batches), feedback (problems are seen quickly, where they happen) and continual learning (experiments and lessons from failures). A value stream map draws every step from an idea to production with its waiting time: most of the delay is usually waiting, not working.

A change takes 2 hours of work and 9 days of waiting for approvals. What should be improved first?

  1. Typing speed
  2. The servers
  3. The waiting between steps
Answer

The waiting: flow is limited by queues, not by work time.

Theory 2/2: the DORA metrics

The DORA research programme (DevOps Research and Assessment; Nicole Forsgren, Jez Humble and Gene Kim's book Accelerate, 2018) linked a few delivery measures to company performance. The original four keys: deployment frequency, lead time for changes, change failure rate, time to restore service. DORA has since renamed and extended them; today it describes five:

  • Throughput: change lead time (commit to production), deployment frequency, failed deployment recovery time;
  • Instability: change fail rate (share of deployments needing an immediate fix) and deployment rework rate (unplanned deployments caused by an incident).

The lesson of the research: speed and stability are not a trade-off; the best teams have both.

"Time from a commit to that commit running in production" is…

  1. deployment frequency
  2. change lead time
  3. recovery time
Answer

Change lead time.

Out of 20 deployments, 3 needed an immediate rollback or hotfix. What is the change fail rate?

  1. 15 %
  2. 3 %
  3. 85 %
Answer

3 / 20 = 15 %.

According to DORA's research, going faster…

  1. always lowers stability
  2. goes together with stability in the best-performing teams
Answer

The high performers are both faster and more stable.

Practice (30 min)

  1. Pick a process you know (ordering a meal, enrolling at a school, publishing a video). Draw its value stream in your notebook: each step, its work time, its waiting time.
  2. Compute the share of waiting in the total. Circle the longest queue.
  3. Read DORA's page on the metrics at dora.dev and copy into your notebook, in your own words, the definition of each of the five.

With your AI: "Here is a value stream I drew: [paste your steps with work and waiting times]. Act as a Lean coach. Do not redraw it for me: ask me three questions that make me find the biggest waste myself, then tell me if my answer is consistent with the numbers."

Recap (10 min)

Three lines: the three ways, the five DORA metrics in two groups, why waiting matters more than working time. Then compute a change fail rate for 4 failures out of 50 deployments (8 %).

Day 3 · 05/11 — The Linux command line

Goal: move around the file system, read files and find help without a search engine.

Theory 1/2: the tree and the paths

Linux has one tree starting at /. A few folders matter every day: /etc (configuration), /var/log (logs), /home (users' folders), /usr/bin (programs), /tmp (temporary files). An absolute path starts with /; a relative path starts from where you are (pwd); ~ is your home folder, . the current folder, .. the parent.

pwd              # where am I
ls -la           # list, with hidden files and details
cd /var/log      # go to an absolute path
cd ..            # up one level
cd ~             # back home

In which top-level folder do you look for a service's configuration?

Answer

/etc.

You are in /var/log. Where does cd ../lib take you?

  1. /lib
  2. /var/lib
  3. /var/log/lib
Answer

.. is /var, so /var/lib.

Theory 2/2: reading and finding

cat prints a file, less pages through it (q to quit, / to search), head and tail show its start or end, tail -f follows a log as it grows. find /etc -name "*.conf" finds files by name. The help is on the machine: man ls, ls --help. The Unix philosophy, written down by Doug McIlroy at Bell Labs: programs that do one thing well and work together.

Which command follows a log file as new lines arrive?

Answer

tail -f file (-F also survives the file being rotated).

Which command opens the manual page of a program?

Answer

man, for example man find.

Practice (30 min)

  1. Visit /, /etc, /var/log with cd and ls -la; note what you find in each.
  2. Read /etc/os-release with cat: which distribution and version are you running?
  3. Open man ls, find with / what -h does, then run ls -lh /var/log.
  4. Find every .conf file directly under /etc: find /etc -maxdepth 1 -name "*.conf".
  5. Create ~/lab/day03 with mkdir -p, copy /etc/hostname into it with cp, rename it with mv, delete it with rm.

With your AI: "I am learning the Linux command line on Debian. Give me ten small tasks of increasing difficulty using only pwd, cd, ls, cat, less, head, tail, find, cp, mv, rm and mkdir. Give the tasks only, numbered, no solutions. When I paste my commands, check each one and explain any mistake."

Recap (10 min)

Three lines: absolute versus relative path, five important folders, where to find help. Then redo the find command without notes.

Day 4 · 06/11 — Users and permissions

Goal: read and set permissions in letters and in numbers, and know why a service runs under its own user.

Theory 1/2: owner, group, others

Every file belongs to a user and a group. ls -l shows ten characters: the type (- file, d folder), then three triplets for the owner, the group and others: r read, w write, x execute (for a folder: enter it). In numbers, r = 4, w = 2, x = 1, added per triplet: rwxr-x--- is 750.

chmod 640 app.conf          # rw- r-- ---
chmod u+x deploy.sh         # add execute for the owner
sudo chown app:app /srv/app # change owner and group

What is rw-r--r-- in numbers?

Answer

6 (4+2), 4, 4: 644.

Endless generated exercise (needs JavaScript): convert permissions.

Theory 2/2: root, sudo and least privilege

root can do everything; sudo runs one command as root and leaves a trace in the logs. A service (a web server, a database) gets its own user with only the rights it needs: if it is compromised, the attacker gets that user, not the machine. This is the principle of least privilege, and it comes back everywhere in this path (containers, CI tokens, Kubernetes).

A script must be run by its owner only, read by nobody else. Which mode?

  1. 755
  2. 700
  3. 777
Answer

700: rwx for the owner, nothing for group and others. 777 is almost never the answer.

Why run a web server under a dedicated user rather than root?

  1. To limit what an attacker gets if it is compromised
  2. Because root is slower
Answer

Least privilege: a breach stays inside that user's rights.

Practice (30 min)

  1. Create a user and a group for a fictitious service: sudo useradd --system --no-create-home app, then id app.
  2. sudo mkdir -p /srv/app, then give it to app: sudo chown app:app /srv/app and sudo chmod 750 /srv/app.
  3. As yourself, try ls /srv/app: why is it refused? Read ls -ld /srv/app.
  4. Create ~/lab/hello.sh containing echo hello. Run ./hello.sh: refused. Add the execute bit, run it again.
  5. Do five rounds of the generated exercise above.

With your AI: "Quiz me on Linux permissions: give me eight cases, one at a time, mixing 'write this mode in numbers' (for example rwxr-x---) and 'which mode for this need' (for example a private SSH key). Wait for each answer, correct it, and explain the security reason when my answer is too open."

Recap (10 min)

Three lines: the three triplets, r/w/x = 4/2/1, why least privilege. Then redo the conversion of rwxr-x--- (750) without notes.

Day 5 · 07/11 — Processes, services, systemd

Goal: see what runs, start and stop a service, and read its logs.

Theory 1/2: processes and signals

A running program is a process with a number (PID). ps aux lists them, top (or htop) shows them live. You send a process a signal: kill PID sends SIGTERM (please stop, clean up), kill -9 PID sends SIGKILL (stop now, no clean-up). Try TERM first; KILL can leave half-written files.

Which signal lets a program finish cleanly?

  1. SIGKILL (9)
  2. SIGTERM (15)
Answer

SIGTERM, the default of kill. SIGKILL cannot be caught.

Theory 2/2: systemd and journald

On most distributions the first process (PID 1) is systemd (Lennart Poettering and Kay Sievers, 2010). It starts services described by unit files and restarts them if needed. Its log collector, journald, is read with journalctl.

systemctl status ssh            # state, PID, last log lines
sudo systemctl restart ssh      # restart
sudo systemctl enable --now ssh # start now and at every boot
journalctl -u ssh --since "1 hour ago"
journalctl -u ssh -f            # follow

Which command makes a service start at every boot?

Answer

systemctl enable (with --now it also starts it right away).

Write the command that shows the logs of the nginx unit.

Answer

journalctl -u nginx.

Practice (30 min)

  1. List processes with ps aux | head, then open top and find the one using most memory (M), q to quit.
  2. Run sleep 600 &, find its PID with pgrep sleep, stop it with kill.
  3. Write a minimal unit /etc/systemd/system/tick.service:
    [Unit]
    Description=Write the date every 10 seconds
    
    [Service]
    ExecStart=/bin/sh -c 'while true; do date; sleep 10; done'
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
  4. sudo systemctl daemon-reload && sudo systemctl enable --now tick, then journalctl -u tick -f. Stop it with sudo systemctl disable --now tick.

With your AI: "Here is the output of systemctl status for a service that fails: [paste it]. Do not give me the fix. Explain each line of this output in one sentence, then ask me which line I think points to the cause."

Let an agent do it: now that you have written a unit by hand, an agent can draft the next one. Instruction: "Write a systemd unit for /usr/local/bin/backup.sh that runs as user backup, restarts on failure, and logs to the journal; output only the file." You still check by hand: the user exists, the path is right, systemd-analyze verify passes, and the service starts.

Recap (10 min)

Three lines: PID and signals, what systemd does, how to read a service's logs. Then redo the enable --now and journalctl -u commands without notes.

Day 6 · 08/11 — Pipes, redirections, text tools

Goal: answer a question about a log file with one line of chained commands.

Theory 1/2: standard streams

Every program has three streams: stdin (0, input), stdout (1, normal output), stderr (2, errors). You redirect them: > writes stdout to a file (overwriting), >> appends, 2> redirects errors, 2>&1 sends errors where stdout goes. The pipe |, invented by Doug McIlroy and added to Unix in 1973, sends one program's stdout to the next one's stdin.

What does cmd >> out.log 2>&1 do?

  1. Overwrites out.log with errors only
  2. Appends both output and errors to out.log
  3. Discards everything
Answer

>> appends stdout, 2>&1 sends stderr to the same place.

Theory 2/2: grep, cut, sort, uniq, wc

grep " 500 " access.log               # lines containing " 500 "
grep -c "ERROR" app.log               # count matching lines
cut -d' ' -f1 access.log              # first field (the client)
sort | uniq -c | sort -rn | head -5   # top 5 by frequency
wc -l file                            # number of lines

sed and awk go further (replace, compute per column); learn them when you need them.

Write the command that counts the lines containing ERROR in app.log.

Answer

grep -c ERROR app.log.

Why sort before uniq -c?

  1. To go faster
  2. For alphabetical output
  3. Because uniq only merges identical lines that are next to each other
Answer

uniq compares each line with the previous one only.

Practice (30 min)

  1. Create a fake access log:
    for i in $(seq 1 200); do
      echo "198.51.100.$((RANDOM % 5)) GET /page$((RANDOM % 3)) $(shuf -n1 -e 200 200 200 404 500)"
    done > ~/lab/access.log
  2. How many 500 errors? grep -c " 500$" ~/lab/access.log.
  3. Which client makes the most requests? Chain cut, sort, uniq -c, sort -rn, head -1.
  4. Which page returns the most 404s? Start with grep " 404$", then cut the third field (-f3).
  5. Save each answer with >> ~/devops-notes/day-06.md.

With your AI: "Here is a one-liner I wrote to find the top 5 client IPs in an access log: [paste it]. Explain what each command in the pipe receives and outputs, then tell me one input line for which my one-liner gives a wrong result, if there is one."

Let an agent do it: an agent with shell access can answer "which page returns the most 404s in access.log" by itself. Ask it to show the command it ran, not only the result. You still check: rerun its command, and compare with a grep count on one value.

Recap (10 min)

Three lines: the three streams, > versus >>, what a pipe does. Then redo the top-client one-liner without notes.

Day 7 · 09/11 — Bash scripts 1: variables, tests, exit codes

Goal: write a script that stops at the first error and says why.

Theory 1/2: a script and its exit code

A script is a text file starting with a shebang, #!/usr/bin/env bash, made executable. Every command returns an exit code: 0 for success, anything else for failure; $? holds the last one. CI pipelines, systemd and Ansible all decide "passed or failed" on that number.

#!/usr/bin/env bash
set -euo pipefail          # stop on error, on unset variable, on a failed pipe
name="${1:-world}"         # first argument, "world" by default
if [[ -f /etc/os-release ]]; then
  echo "Hello $name, this is $(. /etc/os-release; echo "$PRETTY_NAME")"
else
  echo "no os-release" >&2
  exit 1
fi

Which exit code means success?

Answer

0. Everything else is a failure.

Without set -e, a command fails in the middle of a script. What happens?

  1. The script stops
  2. The script carries on as if nothing happened
Answer

It carries on, often doing damage with missing data. set -e stops it.

Theory 2/2: quotes and tests

Always quote variables: "$file", otherwise a name with a space becomes two arguments. [[ -f x ]] tests a file, -d a folder, -z "$v" an empty string, "$a" == "$b" equality. cmd1 && cmd2 runs cmd2 only if cmd1 succeeded; cmd1 || cmd2 only if it failed.

file="my notes.txt"; rm $file: what does rm receive?

  1. Two arguments, my and notes.txt
  2. One argument, my notes.txt
Answer

Two: without quotes the shell splits on the space. Write rm "$file".

Write the line that makes a bash script stop on errors, unset variables and failed pipes.

Answer

set -euo pipefail.

Practice (30 min)

  1. Write ~/lab/check-disk.sh: it takes a threshold in percent (default 80), reads the use of / with df --output=pcent / | tail -1 | tr -dc '0-9', prints OK or ALERT, and exits with 0 or 1.
  2. Make it executable, run it with 80, then with 1 to force the alert, and check echo $? each time.
  3. Remove set -euo pipefail, misspell a command in the middle, run it: see it carry on. Put the line back.

With your AI: "Review this bash script as a senior sysadmin: [paste check-disk.sh]. List problems by severity (bug, robustness, style), quote the exact line for each, and do not rewrite the whole script: I will fix it myself."

Recap (10 min)

Three lines: the shebang, the exit code, why set -euo pipefail and quotes. Then rewrite the first five lines of the script without notes.

Day 8 · 10/11 — Bash scripts 2: loops, functions, ShellCheck, prompting for scripts

Goal: write a reusable script that passes ShellCheck, and write a prompt that gets a usable script from an AI.

Theory 1/3: loops, functions, arguments

check() {                         # a function, called with: check example.com
  local host="$1"
  if curl -fsS -o /dev/null --max-time 5 "https://$host"; then
    echo "OK   $host"
  else
    echo "FAIL $host"; return 1
  fi
}
failed=0
for host in "$@"; do              # every argument given to the script
  check "$host" || failed=$((failed + 1))
done
exit "$failed"

"$@" is every argument, each kept whole; local keeps a variable inside its function.

What is "$@"?

  1. The script's name
  2. All the arguments, each kept as one word
  3. The last exit code
Answer

All the arguments. $0 is the name, $? the last exit code.

Theory 2/3: ShellCheck

ShellCheck (Vidar Holen, open source) reads a script and points out unquoted variables, wrong tests and many classic traps, each with a code (SC2086 for a missing quote) and a page explaining it. Install it with sudo apt install shellcheck; in module 2 it runs in your pipeline.

Which tool lints bash scripts?

Answer

ShellCheck: shellcheck script.sh.

Theory 3/3: prompting for a script

A weak prompt: "write me a backup script". What is wrong: no system, no source or destination, no rule on failures, no format, no way to check. The model will guess and invent.

The edited prompt:

Role: you are a careful Linux sysadmin.
Context: Debian 13, bash 5, no root; rsync is installed.
Task: write backup.sh that copies ~/projects to /mnt/backup/projects.
Constraints: set -euo pipefail; quote every variable; exit 1 with a
message on stderr if the destination is not mounted; no rm, no sudo.
Inputs: none, both paths as constants at the top.
Output: the script only, in one code block, with a comment per step.
Check: I will run shellcheck and a test with the disk unmounted.

Each line removes a guess: the role sets the tone, the context the versions, the constraints the dangers, the output format what you will receive, the check what the answer must survive.

Which prompt is better? A: "Write a script to clean logs, make it good." B: "Bash 5 on Debian: delete *.log files older than 14 days in /var/log/myapp only, print each file deleted, dry-run by default, --apply to delete; output the script only; I will test it with shellcheck."

  1. A, it leaves the model free
  2. B: scope, safety, format and check are stated
Answer

B. "Make it good" is not a constraint; a dry-run default and a precise folder are.

"Fix my script, it doesn't work." What is missing first?

  1. Politeness
  2. A role
  3. The script and the exact error message
Answer

The inputs: without the real script and the real error, the model can only guess.

Practice (30 min)

  1. Type the check script above into ~/lab/check-sites.sh and run it with example.com example.org, then with a name that does not exist.
  2. Run shellcheck on it and on yesterday's check-disk.sh; fix every warning, reading the SC page of each.
  3. Add a -h option that prints a usage line.

With your AI: send the edited backup prompt above, as written. Then run shellcheck on its answer and test it with the destination missing. Write in your notebook what it got right and wrong.

Let an agent do it: an agent in your repository can run ShellCheck on every script and propose fixes. Instruction: "Run shellcheck on every .sh file, fix the warnings without changing behaviour, show me the diff." You still check: read every changed line, rerun the scripts' tests, and refuse any fix that silences a warning with a disable comment without a reason.

Recap (10 min)

Three lines: "$@" and local, what ShellCheck catches, the seven parts of a good prompt. Then rewrite the backup prompt from memory.

Day 9 · 11/11 — The network from a terminal: DNS, HTTP, SSH

Goal: find out from a terminal whether a service answers, by name, by port and by HTTP code.

Theory 1/2: names, ports, HTTP

A machine has an IP address; DNS turns a name into that address (dig example.com). A service listens on a port: 22 SSH, 80 HTTP, 443 HTTPS, 5432 PostgreSQL. ss -tlnp lists the ports your machine listens on. HTTP answers with a status code: 2xx success, 3xx redirection, 4xx client error, 5xx server error. curl -I https://example.com shows the code and headers.

On which port does HTTPS listen by default?

Answer

443.

Endless generated exercise (needs JavaScript): HTTP status codes.

Theory 2/2: SSH and keys

SSH (Tatu Ylönen, 1995) opens an encrypted shell on a remote machine. Rather than a password, you use a key pair: the private key stays on your machine (mode 600), the public key goes into ~/.ssh/authorized_keys on the server. Ansible, Git remotes and deployments all ride on it.

ssh-keygen -t ed25519 -C "laptop"     # create a key pair
ssh-copy-id deploy@203.0.113.10      # install the public key on the server
ssh deploy@203.0.113.10

Which key do you copy to the server?

  1. The private key
  2. The public key (.pub)
Answer

The public key. The private key never leaves your machine.

curl returns 502 from a site behind a reverse proxy. Where do you look first?

  1. The application behind the proxy (it is down or unreachable)
  2. Your own browser
Answer

502 Bad Gateway: the proxy got no valid answer from the server behind it.

Practice (30 min)

  1. dig +short example.com, then dig example.com MX: note the address and the type of record.
  2. curl -I https://example.com and curl -I https://example.com/nothing-here: note both codes.
  3. ss -tlnp: which ports does your machine listen on? Start python3 -m http.server 8000 in another terminal and look again, then curl -I http://127.0.0.1:8000.
  4. Create an ed25519 key pair with ssh-keygen, check that ~/.ssh/id_ed25519 has mode 600. If you have a second VM, install the key and log in without a password.

With your AI: "I run curl -v https://example.com and paste the output below. Explain, in order, each step you see (DNS, TCP, TLS, HTTP request, response), quoting the line that shows it, in under 15 lines: [paste the output]."

Let an agent do it: an agent can now run the whole "does it answer?" check for a list of URLs and report name, port and code for each. Ask for the commands it used. You still check one result by hand with dig and curl -I, so you know the report is real.

Recap (10 min)

Three lines: what DNS does, the families of HTTP codes, public versus private key. Then redo five rounds of the HTTP code exercise.

Day 10 · 12/11 — Git 1: the model, the first commits

Goal: understand what a commit is, and version your notebook.

Theory 1/2: why Git, and how it thinks

Linus Torvalds wrote Git in April 2005, when the Linux kernel lost the free use of its previous tool, BitKeeper. Git is distributed: every clone holds the whole history. A commit is a snapshot of the whole project, with an author, a message and a pointer to its parent; it is named by a hash of its content, so history cannot be changed silently. Three places: the working directory (your files), the staging area (what the next commit will hold, filled by git add) and the repository (the commits).

What does git add do?

  1. Creates a commit
  2. Puts changes in the staging area for the next commit
  3. Sends the code to the server
Answer

It stages. git commit records, git push sends.

A commit stores…

  1. a snapshot of the project, named by a hash
  2. only the lines that changed, named by a number
Answer

A snapshot (Git compresses and shares identical content), named by its hash.

Theory 2/2: the everyday commands

git init                    # start a repository
git status                  # what changed, what is staged
git add day-10.md           # stage a file
git commit -m "Add day 10"  # record
git log --oneline --graph   # history
git diff                    # unstaged changes; git diff --staged for staged
git restore file            # throw away an unstaged change

A .gitignore file lists what Git must never version: build outputs, local settings, and above all secrets.

Which command tells you what changed and what is staged?

Answer

git status, the command you run most.

Which command shows what the next commit will contain?

Answer

git diff --staged (or --cached).

Practice (30 min)

  1. Set your identity: git config --global user.name "Your Name" and git config --global user.email "you@example.org" (your real address goes there, not in a public page).
  2. In ~/devops-notes: git init, git add ., git commit -m "Add notes for days 1 to 9".
  3. Change one file, look at git diff, stage it, look at git diff --staged, commit.
  4. Create a .gitignore with *.tmp, create x.tmp, check that git status ignores it.
  5. Read the history with git log --oneline.

With your AI: "Explain the three areas of Git (working directory, staging area, repository) with an analogy, then give me six commands in a random order and ask me, for each, which area it moves data from and to. Correct my answers."

Recap (10 min)

Three lines: what a commit is, the three areas, what .gitignore is for. Then redo the add / commit / log sequence without notes.

Day 11 · 13/11 — Git 2: branches, merge, rebase, conflicts

Goal: work on a branch, bring it back, and resolve a conflict without panic.

Theory 1/2: a branch is a label

A branch is only a movable label pointing to a commit; HEAD says which branch you are on. Creating one costs nothing.

git switch -c feature/greeting   # create and move to a branch
# ... commits ...
git switch main
git merge feature/greeting       # bring the work back

If main has not moved, the merge is a fast-forward: the label just moves. Otherwise Git creates a merge commit with two parents. git rebase main, run on the feature branch, instead replays its commits on top of main: a straight history, but rewritten commits; never rebase commits others already pulled.

What is a Git branch?

  1. A copy of every file
  2. A movable pointer to a commit
Answer

A pointer; that is why branches are cheap.

Why not rebase a branch your colleagues already pulled?

  1. Rebase rewrites its commits, and their copies no longer match
  2. Rebase deletes the branch
Answer

The commits get new hashes; everyone else's history diverges.

Theory 2/2: conflicts

A conflict happens when two branches changed the same lines. Git stops and marks the file:

<<<<<<< HEAD
greeting="Hello"
=======
greeting="Bonjour"
>>>>>>> feature/greeting

You edit the file to the right content, remove the markers, git add it, then git commit (or git rebase --continue). git merge --abort goes back to before.

Which command cancels a merge in progress?

Answer

git merge --abort.

You fixed the conflicting file. Next step?

  1. git push --force
  2. git reset --hard
  3. git add the file, then commit
Answer

Staging the file tells Git the conflict is resolved.

Practice (30 min)

  1. Play the first levels of Learn Git Branching ("Introduction Sequence").
  2. In a new repo ~/lab/conflict: commit a file greet.sh with greeting="Hello" on main.
  3. Create feature/fr, change the line to "Bonjour", commit. Go back to main, change it to "Hi", commit.
  4. git merge feature/fr: resolve the conflict, commit, read git log --oneline --graph.
  5. Start again with git rebase instead of merge, and compare the graphs.

With your AI: "Here is the output of git status and the conflicted file during a merge: [paste both]. Do not resolve it for me. Explain which part comes from which branch, and ask me which version the final file should keep and why."

Let an agent do it: agents resolve simple conflicts well once told the intent. Instruction: "Rebase this branch on main; for every conflict, keep main's behaviour plus this branch's new feature, and list each conflict and your choice." You still check: read the list, run the tests, and compare git diff main with what the branch was meant to change.

Recap (10 min)

Three lines: branch = pointer, merge versus rebase, how to resolve a conflict. Then redraw from memory the graph of a merge commit.

Day 12 · 14/11 — Git 3: remotes and branching workflows

Goal: push to a forge, open a pull request, and choose a branching workflow.

Theory 1/2: remotes and pull requests

A remote is another copy of the repository, usually on a forge (GitHub, Forgejo, GitLab). git push sends your commits, git fetch brings theirs without touching your work, git pull fetches and merges. A pull request (merge request on GitLab) proposes to merge a branch: it is where the code is discussed, reviewed and tested before reaching main.

git remote add origin git@github.com:you/ops-scripts.git
git push -u origin main
git switch -c fix/typo && git commit -am "Fix typo" && git push -u origin fix/typo

Which command downloads the remote's new commits without changing your branch?

Answer

git fetch. git pull also merges.

Theory 2/2: three branching workflows

  • Git Flow (Vincent Driessen, January 2010): develop, feature/*, release/*, hotfix/* branches around main. In a note added in March 2020 its author says it suits versioned software, and that continuously delivered web applications are better served by something simpler.
  • GitHub Flow (Scott Chacon, 2011): main is always deployable; every change is a short branch, a pull request, a review, a merge, a deployment.
  • Trunk-based development: everyone integrates into the trunk (main) at least daily, with very short branches and feature flags for unfinished work. DORA's research associates it with high performance.

You deploy a web app several times a day. Which workflow does Git Flow's own author advise against for you?

  1. Trunk-based development
  2. Git Flow
  3. GitHub Flow
Answer

Git Flow: its author points continuously delivered web apps to simpler workflows.

In trunk-based development, how do you merge a feature that is not finished?

  1. Behind a feature flag, switched off
  2. You keep it on a branch for three months
Answer

Behind a flag: the code is integrated, the feature hidden.

Practice (30 min)

  1. Create an account on GitHub or on a Forgejo instance, add your SSH public key in its settings.
  2. Create an empty public repository ops-scripts; locally, put in it your check-disk.sh and check-sites.sh, commit, add the remote, push.
  3. Create a branch docs/readme, add a README.md saying what each script does, push it, open a pull request, read its diff on the forge, merge it.
  4. Locally: git switch main && git pull, and check the README is there.

With your AI: "My team is two people, we deploy a small web app each time we merge, and we have no release versions. Compare Git Flow, GitHub Flow and trunk-based development for this case in a table (branches, merge frequency, risks), then ask me which one I would pick and challenge my choice once."

Recap (10 min)

Three lines: push / fetch / pull, what a pull request is for, the three workflows in one sentence each. Then redo the branch, push and pull request sequence without notes.

Day 13 · 15/11 — Code review and commit hygiene

Goal: write commits a reviewer can read, and review a pull request usefully.

Theory 1/2: small commits, clear messages

A good commit does one thing, and its message says why. A widespread convention, Conventional Commits 1.0.0, prefixes the subject with a type: feat:, fix:, docs:, ci:, refactor:… Tools can then compute a version number (Semantic Versioning: MAJOR.MINOR.PATCH) and a changelog from the history. The subject stays short, in the imperative ("add", not "added"); the body explains the reason.

fix: stop check-disk from passing when df fails

df returns nothing on an unmounted path, and the empty value was read
as 0 %, so the script printed OK. Exit 2 when df gives no number.

Which subject follows Conventional Commits?

  1. "changes"
  2. "fix: handle an empty df output"
  3. "Fixed stuff in the script!!"
Answer

Type, colon, short imperative subject.

A new feature that breaks nothing bumps which part of a semantic version 1.4.2?

  1. MINOR: 1.5.0
  2. MAJOR: 2.0.0
  3. PATCH: 1.4.3
Answer

MINOR. PATCH is for fixes, MAJOR for breaking changes.

Theory 2/2: reviewing

Google publishes its code review guidelines. Their standard: approve a change once it improves the overall health of the code, even if it is not perfect. A reviewer looks at design, behaviour, tests, naming, comments, and keeps pull requests small (a few hundred lines at most are reviewed well). Comments are about the code, never the person, and say what is blocking and what is a suggestion ("nit:").

A 3,000-line pull request mixing a refactor and a feature. Best answer?

  1. Approve without reading, it is too long
  2. Ask to split it into smaller pull requests
Answer

Split: small changes are reviewed properly and merged faster.

Which comment is the better review comment?

  1. "This loop reads the file once per host; could we read it once before the loop?"
  2. "Did you even test this?"
Answer

Specific, about the code, with a suggestion.

Practice (30 min)

  1. In ops-scripts, open a branch that fixes yesterday's ShellCheck findings or adds the -h option, in two separate commits with Conventional Commits messages and a body.
  2. Open the pull request with a description: what, why, how to test.
  3. Review it yourself the next morning, as a stranger: leave at least two comments on the forge, one blocking, one "nit:".
  4. If you know another learner, swap a review.

With your AI: "Review this diff as a reviewer following Google's code review guidelines: [paste git diff main]. Give at most five comments, each with the file and line, marked BLOCKING or NIT, and one sentence on whether the change improves the code overall. Do not rewrite the code."

Let an agent do it: agents can write commit messages and pull request descriptions from a diff. Instruction: "Write a Conventional Commits message for the staged diff: subject under 60 characters, body explaining why." You still check that the "why" is true: the agent only sees the diff, not your reason.

Recap (10 min)

Three lines: what a good commit is, MAJOR.MINOR.PATCH, the Google review standard. Then rewrite one of your old commit messages properly.

Day 14 · 16/11 — Module 1 deliverable: your ops-scripts repository

Goal: publish a clean repository of two to three documented scripts, and check what you learnt.

Theory 1/2: what makes a repository readable

A stranger, a recruiter or you in six months opens the repository: the README.md says what it does, how to install, how to run, how to test; a LICENSE file says what others may do with it (for example MIT); the history tells a story in small commits; nothing secret is in it, not even in an old commit.

You committed a password last week, then deleted it in a new commit. Is it gone?

  1. Yes
  2. No, it is still in the history: change the password
Answer

Every old commit still holds it. Rotate the secret first; cleaning the history comes second.

Theory 2/2: module review

Which of these is not one of the DORA metrics?

  1. Deployment frequency
  2. Change fail rate
  3. Lines of code per day
Answer

Lines of code measure activity, not delivery.

rwxr-x--- in numbers?

Answer

750.

A script ends with exit 3. For a CI pipeline, the step…

  1. failed
  2. passed with a warning
Answer

Any non-zero code is a failure.

Endless generated exercise (needs JavaScript): permissions review.

Practice (30 min)

  1. Finish ops-scripts: check-disk.sh, check-sites.sh, and a third of your choice (for example a log summary built on day 6). Each passes shellcheck, has -h, exits non-zero on failure.
  2. Write the README: purpose, requirements, usage with an example, how to test. Add a LICENSE.
  3. Check the history: git log --oneline reads like a story; nothing secret in it (git log -p | grep -i pass).
  4. Push, and add the repository link to your notebook: it is deliverable 1 of your portfolio.

With your AI: "Act as a hiring manager for a junior DevOps role. Here is the README and the file list of my repository: [paste them]. Tell me in five bullet points what you would ask me in an interview about it, and one thing that would make you stop reading. Do not compliment."

Let an agent do it: an agent can draft a README from the scripts' code and -h output. You still check every command in it by running it, and you rewrite the "why" in your own words: the recruiter will ask you, not the agent.

Recap (10 min)

Count your score on the review. Topics you missed come back on day 54, when you design your final project.

Sources

Found this useful? Tell us what to measure next.