NetAuto Academy

Git / NetDevOps

Branches and Diffs: Reviewing a Change Before It Ships

Advanced15 min read

What you'll learn

  • A branch as an isolated place to propose a change
  • Diffing a branch against trunk as the real review step
  • A genuine, verified discovery about merging and the working tree
  • How this connects to dry-run/compare_config()'s review-before-commit principle
🎓 Teach This Lesson

Listen to a guided explanation of this lesson.

Spoken narration isn't supported in this browser.

A branch: propose a change without touching trunk

The same principle, a new mechanism

Reliable Automation's dry-run mode (Phase 2.8) and NAPALM's compare_config() (Phase 3.5) both taught: see what would change before committing to it. A branch is that same principle applied to history itself -- a proposed change lives somewhere separate from trunk until it's reviewed.

real, executed
feature = repo.create_head("add-vlan-30")
feature.checkout()

with open("repo1/sw1.cfg", "a") as f:
  f.write("vlan 30\n name MGMT\n")
repo.index.add(["sw1.cfg"])
repo.index.commit("Propose VLAN 30")

create_head() makes a new branch pointing at the current commit. checkout() switches to it -- trunk (master) is completely untouched by anything committed here.

Quick checkConcept check
What does creating a branch and committing to it actually do to trunk (master)?

Diffing the branch against trunk: the real review step

real, executed
trunk = repo.heads.master
print(repo.git.diff(f"{trunk.name}...{feature.name}"))

The ... syntax diffs trunk against the branch's proposed changes -- exactly what a reviewer needs to see before approving a merge.

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

Real, verified output. This is precisely what compare_config() (Phase 3.5) showed for one device's candidate config -- the same review-the-diff-first discipline, now applied to a proposed commit.

Quick checkScenario
A reviewer sees this diff before approving the branch for merge. What does it tell them, precisely?

Merging: real, verified, and a genuine discovery

real, executed
trunk.checkout()
merge_base = repo.merge_base(trunk, feature)
repo.index.merge_tree(feature, base=merge_base)
merge_commit = repo.index.commit(
  "Merge add-vlan-30",
  parent_commits=(trunk.commit, feature.commit),
)

with open("repo1/sw1.cfg") as f:
  print(f.read())

merge_tree() combines the two branches' changes into the index; commit() with two parent_commits creates a real merge commit.

A real, non-obvious discovery -- found by actually running it

The first run of this exact code showed the file STILL missing VLAN 30 after the merge commit succeeded. merge_tree() and commit() update the repository's history and its index -- but not the working-tree files on disk, until something explicitly syncs them. This is not documented prominently and was found only by checking the actual file content, not assumed from the method names.

output of the naive version — real, verified
hostname SW1
interface GigabitEthernet0/1
description mgmt-uplink
vlan 20
name VOICE

Real, verified output -- VLAN 30 is genuinely missing here, despite the merge commit existing in history. This is the actual, first-attempt result, not a hypothetical.

Quick checkPredict output
A merge commit was created successfully with parent_commits=(trunk.commit, feature.commit). Based on the real, verified discovery above, does the working-tree file on disk necessarily reflect that merge?

The fix, verified

real, executed
repo.head.reset(index=True, working_tree=True)

with open("repo1/sw1.cfg") as f:
  print(f.read())

reset() with working_tree=True explicitly syncs the on-disk files to match HEAD's current commit.

output — real, verified
hostname SW1
interface GigabitEthernet0/1
description mgmt-uplink
vlan 20
name VOICE
vlan 30
name MGMT

Real, verified output. VLAN 30 now genuinely present on disk -- the fix, confirmed by re-reading the file, not assumed to have worked.

Quick checkIdentify the correct code
After a merge commit, which correctly ensures the working-tree files reflect it?

Key takeaways

  • A branch isolates a proposed change from trunk completely -- verified directly, nothing on master changes until an explicit merge.
  • Diffing branch...trunk is the real review step -- the same principle as dry-run (Phase 2.8) and compare_config() (Phase 3.5), applied to a proposed commit instead of a device config.
  • A genuine, verified discovery: merge_tree() + commit() update history and the index, but not the working-tree files on disk, until reset(working_tree=True) explicitly syncs them.
  • This was found by actually reading the file after a 'successful' merge, not assumed from the method names -- the established verify-first discipline, applied to Git itself.