NetAuto Academy

Git / NetDevOps

Git Fundamentals Through a Network Config Example

Advanced12 min read

What you'll learn

  • What a commit actually is: a snapshot, not a diff stored on its own
  • The real, executed init -> add -> commit -> log -> diff cycle
  • How to read a real unified diff against a config file
  • That every example here ran against the real, local git binary
🎓 Teach This Lesson

Listen to a guided explanation of this lesson.

Spoken narration isn't supported in this browser.

A commit is a snapshot

Not a diff -- a full snapshot

A commit records the complete state of every tracked file at that moment, not just what changed. Git computes diffs between commits when you ask to see them (below) -- but what's actually stored is a snapshot. This matters: you can jump directly to any commit's full state, not just replay a chain of edits.

Quick checkConcept check
What does a Git commit actually store?

The real cycle: init, add, commit

a real switch config, tracked from the start
import git

repo = git.Repo.init("repo1")
with repo.config_writer() as cw:
  cw.set_value("user", "name", "Network Automation Curriculum")
  cw.set_value("user", "email", "automation@example.local")

with open("repo1/sw1.cfg", "w") as f:
  f.write("hostname SW1\ninterface GigabitEthernet0/1\n description mgmt-uplink\n")

repo.index.add(["sw1.cfg"])
commit1 = repo.index.commit("Initial SW1 config")
print(commit1.hexsha[:8], repr(commit1.message))

init creates a real, empty repository. add stages a file. commit snapshots exactly what's staged -- not the whole working directory, only what add selected.

output — real, verified
4581349b 'Initial SW1 config'

Real, verified output. hexsha is git's real, content-addressed commit identifier -- shortened here to 8 characters, as is conventional.

Quick checkIdentify the correct code
Which correctly stages sw1.cfg and then commits it with a message?

Real diffs against a real change

a real change to the same config
with open("repo1/sw1.cfg", "a") as f:
  f.write("vlan 20\n name VOICE\n")

print(repo.git.diff("sw1.cfg"))

repo.git.diff() -- a direct pass-through to git's own diff command, returning a real unified diff as a plain string.

output — real, verified
diff --git a/sw1.cfg b/sw1.cfg
index 8857272..3fa0852 100644
--- a/sw1.cfg
+++ b/sw1.cfg
@@ -1,3 +1,5 @@
hostname SW1
interface GigabitEthernet0/1
description mgmt-uplink
+vlan 20
+ name VOICE

Real, verified output -- a genuine unified diff. Lines starting with + are additions; unmarked lines are unchanged context.

Quick checkPredict output
Based on the real diff above, what happened to sw1.cfg?

Committing the change, and reading history

real, executed
repo.index.add(["sw1.cfg"])
commit2 = repo.index.commit("Add VLAN 20")

for c in repo.iter_commits():
  print(c.hexsha[:8], c.message.strip())

iter_commits() walks history newest-first -- a real, verified log.

output — real, verified
06d6c2dd Add VLAN 20
4581349b Initial SW1 config

Real, verified output. Two real commits, in real reverse-chronological order -- the same repository, the same two real hexsha values from earlier in this lesson.

Quick checkScenario
A learner wants to see exactly what changed between the two real commits above, not just the working-tree diff shown earlier. What's the correct approach?

Key takeaways

  • A commit is a full snapshot, not a stored diff -- diffs are computed on demand between two snapshots.
  • init/add/commit are three distinct, real steps -- verified directly, each with its own purpose (create, stage, snapshot).
  • repo.git.diff() returns a real unified diff string -- + lines are additions, unmarked lines are unchanged context.
  • iter_commits() reads real history, newest-first -- every commit's hexsha is a real, content-addressed identifier.