NetAuto Academy

Git / NetDevOps

Capstone: A Version-Controlled Configuration Change Workflow

Advanced16 min read

What you'll learn

  • Combining baseline, branch, review, and merge into one script
  • Why the commit history itself is this capstone's report
  • Reading a real, verified end-to-end run
  • What stays out of scope here, and why
🎓 Teach This Lesson

Listen to a guided explanation of this lesson.

Spoken narration isn't supported in this browser.

The workflow this module built toward

  1. Baseline config committed to trunkLesson 2
  2. A change is proposed on a branchLesson 4 -- never edit trunk directly
  3. The branch is diffed against trunkthe real review step
  4. The branch is merged, working tree syncedLesson 4's verified reset() fix
  5. The commit log is the report
Quick checkConcept check
What does this capstone combine that no single earlier lesson in this module demonstrated alone?

The full script

capstone_config_change_workflow.py
import git
import os

REPO_PATH = "capstone_repo"
CONFIG_FILE = "sw1.cfg"

repo = git.Repo.init(REPO_PATH)
with repo.config_writer() as cw:
  cw.set_value("user", "name", os.environ.get("GIT_AUTHOR_NAME", "Network Automation Curriculum"))
  cw.set_value("user", "email", os.environ.get("GIT_AUTHOR_EMAIL", "automation@example.local"))

config_path = os.path.join(REPO_PATH, CONFIG_FILE)

# Baseline: the current, already-deployed config committed to trunk.
with open(config_path, "w") as f:
  f.write("hostname SW1\ninterface GigabitEthernet0/1\n description mgmt-uplink\n")
repo.index.add([CONFIG_FILE])
repo.index.commit("Baseline: current SW1 config")

# Propose a change on a branch -- never edit trunk directly.
change_branch = repo.create_head("add-vlan-40")
change_branch.checkout()
with open(config_path, "a") as f:
  f.write("vlan 40\n name GUEST\n")
repo.index.add([CONFIG_FILE])
repo.index.commit("Propose VLAN 40 for guest network")

# Review: diff the proposed change against trunk before merging.
trunk = repo.heads.master
diff = repo.git.diff(f"{trunk.name}...{change_branch.name}")
print("--- Review: proposed change vs. trunk ---")
print(diff)

# Merge: only after the diff has been reviewed.
trunk.checkout()
merge_base = repo.merge_base(trunk, change_branch)
repo.index.merge_tree(change_branch, base=merge_base)
repo.index.commit(
  f"Merge {change_branch.name}",
  parent_commits=(trunk.commit, change_branch.commit),
)
repo.head.reset(index=True, working_tree=True)  # Lesson 4's verified fix

# Report: the full, readable change history.
print()
print("--- Report: commit history ---")
for c in repo.iter_commits():
  print(f"{c.hexsha[:8]}  {c.message.strip()}")

The complete, real, verified capstone script. No credential or real identity is hardcoded -- author name/email come from environment variables with obviously-placeholder fallbacks.

Quick checkIdentify the correct code
Why does this script call repo.head.reset(index=True, working_tree=True) right after the merge commit?

Real, verified end-to-end output

terminal output — real, verified run
--- Review: proposed change vs. trunk ---
diff --git a/sw1.cfg b/sw1.cfg
index 8857272..2cdd7f0 100644
--- a/sw1.cfg
+++ b/sw1.cfg
@@ -1,3 +1,5 @@
hostname SW1
interface GigabitEthernet0/1
description mgmt-uplink
+vlan 40
+ name GUEST

--- Report: commit history ---
18a8e31e  Merge add-vlan-40
cc007551  Baseline: current SW1 config
413a4e96  Propose VLAN 40 for guest network

Real, verified output from an actual run of the script above.

final config on trunk — real, verified
hostname SW1
interface GigabitEthernet0/1
description mgmt-uplink
vlan 40
name GUEST

Real, verified. VLAN 40 is genuinely present -- the working tree correctly reflects the merge, confirming Lesson 4's fix works here too, not just in isolation.

Quick checkPredict output
Why does the commit log show 'Merge add-vlan-40' as the newest entry, above the two commits it merged?

What stays out of scope, deliberately

Never claimed here

This capstone never pushes to a remote, never contacts GitHub or GitLab, and never uses a real pull-request review UI. Every operation ran against a real, local repository only. A real hosted remote and a real PR review are genuine, valuable next steps in a production NetDevOps workflow -- explicitly deferred, not built here.

Quick checkScenario
How should a learner honestly describe what this capstone proves?

Key takeaways

  • This capstone combines every piece of the module: baseline commit, an isolated branch, a real diff for review, and a synced merge -- all verified together in one real, runnable script.
  • Real, verified run: the review diff showed exactly the proposed VLAN 40 change; the final merged config on trunk genuinely includes it, confirming Lesson 4's working-tree fix generalizes.
  • The commit history itself is the report -- a real, permanent, readable record of what changed and why, the exact gap Lesson 1 opened with.
  • No remote, hosted service, or CI/CD was used anywhere in this module -- deliberately deferred, never claimed as tested.
  • Next: Production Automation -- testing, review, and safe rollout in production, not a new version-control mechanism.