Skip to main content
RunBook Academy

Git, CI/CD & GitOpsXVI · Restore and SwitchRestoreSwitch

Migrating team habits — muscle memory, training, CI scripts, and what to update when migrating

Intermediate⏱ ~22 mingit

What you'll learn

  • Identify the touchpoints that need to change when a team adopts git switch and git restore
  • Distinguish policy-level migration from muscle-memory migration
  • Design a shell alias strategy that eases the transition without confusion
  • Audit a CI pipeline for the legacy spellings and classify each line for modernisation
  • Update onboarding, runbooks, and incident postmortems to reference the new commands

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

The 2.23 split changed two commands. Migrating a team to those commands is a different problem - a documentation, training, and CI-audit problem - and the migration has more moving parts than the commands themselves. This lesson covers the touchpoints, the alias strategies that ease the transition, the audit checklist for CI scripts, and the documentation that needs updating.

The migration is not the hard part

The commands are interchangeable. git switch main and git checkout main produce the same tree state. git restore <path> and git checkout -- <path> produce the same working tree bytes. The technical migration is a rename with no behaviour change.

The hard parts are everywhere else:

  • Muscle memory. Engineers who have typed git co main for ten years do not switch overnight.
  • Documentation. Onboarding guides, runbooks, incident postmortems, and team wikis reference commands that engineers paste from prose into shells.
  • CI scripts. Pipelines that have used git checkout for years parse its output and rely on its exit code.
  • Aliases. Engineers who have aliased git co to git checkout need to know whether the alias stays or goes.
  • Code review. A team that has not decided what the new conventions are cannot enforce them in review.
flowchart LR
    A["migration"] --> B["muscle memory"]
    A["muscle memory"] --> C["documentation"]
    A["documentation"] --> D["CI scripts"]
    A["CI scripts"] --> E["aliases"]
    A["aliases"] --> F["code review"]
    A["code review"] --> B

The loop closes because each touchpoint reinforces the others: a code review that accepts git checkout keeps the muscle memory alive; a runbook that documents the new spellings accelerates the next migration step.

Phased migration plan

A phased plan, not a big-bang rewrite, is the right shape. Three phases cover most teams:

Phase 1: Documentation and policy (weeks 1-2)

The team agrees on a policy: new code uses git switch for branch operations and git restore for file operations. The policy is documented in CONTRIBUTING (or its equivalent) and announced in the team channel. No code is changed yet; the policy is a forward-looking agreement.

The deliverables:

  • CONTRIBUTING line: “new code uses git switch and git restore; legacy git checkout lines are modernised when the surrounding section is modified for another reason”
  • Updated onboarding doc: the branch-and-restore lessons reference the new commands
  • A runbook entry for “how to undo an accidental git add” pointing to git restore --staged and git restore, with the legacy equivalents noted for engineers who encounter them in old scripts

Phase 2: Low-risk cleanups (weeks 3-6)

Pure-rename changes - git checkout main to git switch main, git checkout -- file to git restore file - are applied to scripts that the team is actively touching. The rule from lesson XVI-05 applies: “while you are here, can any of the git checkout lines be cleaner as git switch or git restore?”

The deliverables:

  • A list of active scripts and their git checkout invocations
  • Pure-rename commits for each script that is being modified for another reason
  • Test runs to confirm the modernised scripts produce identical behaviour

Phase 3: Aliases and enforcement (months 2-6)

As new engineers join and old engineers adapt, the team considers whether to enforce the new spellings through aliases or review tooling. This phase is gradual and never fully complete; some legacy git checkout lines will exist in the codebase for years.

flowchart LR
    P1["Phase 1\n(weeks 1-2)"] -->|policy + docs| P2["Phase 2\n(weeks 3-6)"]
    P2 -->|cleanup commits| P3["Phase 3\n(months 2-6)"]
    P3 -->|aliases + enforcement| P4["ongoing\n(years)"]

Shell aliases: easing the transition

Engineers who have aliased git co to git checkout face a choice when the team adopts the new commands. Three strategies are common:

Strategy 1: Keep the old alias, accept the hints

The alias git co continues to expand to git checkout, and the engineer accepts the hint: output that Git 2.24+ emits. The hint is informational; it does not break the command. The downside is the engineer never sees the new spelling unless they type the full command.

Strategy 2: Repoint the alias to the new command

The alias git co is repointed to git switch. The downside is asymmetric: git co main becomes a branch switch, but git co -- file would fail because git switch does not accept a file path. Engineers who relied on the alias for both operations would have to learn the distinction.

Strategy 3: Add new aliases, retire the old one

The aliases git sw to git switch and git rs to git restore are added; the alias git co is removed. The downside is forcing every engineer to relearn their shell shortcuts.

The recommended strategy for most teams is a hybrid: keep git co as an alias for git checkout during the transition, add git sw and git rs aliases, and document in CONTRIBUTING that git co is a transition alias that will be retired in a future phase.

# Recommended alias setup during transition
git config --global alias.sw switch
git config --global alias.rs restore

# Existing alias co remains for backward compatibility
# (do not change during phase 1-2; retire in phase 3)
git config --global alias.co checkout

CI script audit checklist

A CI pipeline that uses git checkout needs to be audited in three categories:

Category 1: Pure renames (modernise freely)

Lines that are exact synonyms with no behaviour change. Examples:

  • git checkout main -> git switch main
  • git checkout -b feature/x -> git switch -c feature/x
  • git checkout -- file -> git restore file
  • git checkout HEAD -- file -> git restore --staged --worktree file

These can be modernised as low-risk cleanup commits.

Category 2: Behaviour-equal but ambiguous arguments

Lines where the legacy form is ambiguous between branch and file operations. Examples:

  • git checkout terraform/.terraform.lock.hcl (no --)

The bare form is ambiguous: depending on whether a branch or tag of that name exists, this may be a switch or a file restore. The modernisation requires verifying intent and making the intent explicit. Recommended modernisation: git restore terraform/.terraform.lock.hcl (if the intent was file restore) or git switch terraform/.terraform.lock.hcl (if the intent was branch switch - very unlikely for a file-named argument).

Category 3: Behaviour-different flags

Lines where the legacy flag has no direct new equivalent. Examples:

  • git checkout --overlay <ref> -- <path> (controls untracked file behaviour at the target path)
  • git checkout --no-overlay <ref> -- <path> (deletes untracked files at the target path)

These require explicit decision: either keep the legacy form and document why, or replace with a multi-step sequence in the new commands.

flowchart TD
    A["git checkout line"] --> B{"pure rename?"}
    B -- "yes" --> C["modernise freely"]
    B -- "no" --> D{"ambiguous arg?"}
    D -- "yes" --> E["verify intent, modernise with care"]
    D -- "no" --> F{"behaviour-diff flag?"}
    F -- "yes" --> G["document decision"]
    F -- "no" --> H["modernise when touched"]

Documentation updates

The team’s documentation surface is bigger than the CI scripts. The migration touches:

  • CONTRIBUTING file. The policy line from phase 1.
  • Onboarding doc. The branch and undo lessons point to git switch and git restore.
  • Runbooks. Each runbook that references git checkout has the reference updated to the new spelling. The legacy form is noted as “still works” for engineers who encounter it.
  • Incident postmortems. Postmortems from before the migration may reference git checkout in their timeline or remediation. Leave the historical postmortems alone - they describe what happened, not what should happen - but note in the postmortem template that new postmortems should use the new spellings.
  • Architecture decision records (ADRs). If the team writes ADRs, the migration is worth one. The ADR captures the policy, the rationale, and the timeline.
flowchart LR
    A["CONTRIBUTING"] --> B["onboarding doc"]
    B --> C["runbooks"]
    C --> D["incident postmortems"]
    D --> E["ADR"]
    E --> F["team wiki"]
    F --> A

The loop closes because each piece of documentation references the others. An engineer who reads the onboarding doc and follows a link to a runbook should find consistent language; an engineer who reads the ADR should find the same policy that CONTRIBUTING states.

Code review: enforcing the policy

A code review checklist that includes the new spellings is the lightest enforcement mechanism:

[ ] Branch work uses `git switch` (not `git checkout <branch>`)
[ ] File work uses `git restore` (not `git checkout -- <path>`)
[ ] Legacy `git checkout` in surrounding code is modernised
    if it is a pure rename (and this PR touches it)

The checklist is enforced by reviewers, not by tooling - there is no widely-used linter that flags git checkout in a shell script. The enforcement is human, which means the policy will sometimes be missed. That is acceptable; the goal is gradual improvement, not perfection.

Production discipline

  1. Adopt a policy, not a rewrite. New code uses the new commands; legacy code is modernised when touched; stable code is not rewritten.
  2. Document the policy in CONTRIBUTING. Engineers who join the team need the rule in writing.
  3. Audit CI scripts during the migration window. Pure renames are safe; ambiguous arguments require intent verification; behaviour-different flags require decisions.
  4. Keep git co as a transition alias. Retiring the alias too early forces a muscle-memory reset that causes mistakes.
  5. Review against the new conventions. The checklist item “uses git switch for branch work and git restore for file work” is the lightest-weight enforcement.

Cross-course references

  • Ansible for Production Sysadmins - Part XXXVII (RepoArch) has a runbook entry on the git switch migration that is reused (with attribution) for the GitOps course. The patterns are shared.
  • GitOps with Argo CD - Part II (Repos) documents the alias strategy in the team’s onboarding guide, with the hybrid git sw + git rs + retained git co approach.
  • Terraform for Production Sysadmins - Part XV (CIHooks) uses the CI audit checklist verbatim, with the Terraform lock-file ambiguity called out specifically.

Quiz

Knowledge check · 4 questions

  1. Q1. An engineer is leading a team's migration from `git checkout` to `git switch` and `git restore`. What is the right shape for the rollout?

  2. Q2. Shell aliases like `git co` for `git checkout` should be removed at the start of the migration, because leaving them in place prevents engineers from learning the new commands.

  3. Q3. Name the three categories a CI script audit should classify `git checkout` lines into, and what action each category implies.

  4. Q4. Design a one-quarter migration plan for a 12-engineer team adopting `git switch` and `git restore`, identifying the deliverables and the risks at each phase.

    A team of 12 engineers maintains a Terraform monorepo with 40 CI scripts, 20 runbooks, and an onboarding doc. The team lead has decided to adopt the new commands over the next quarter. The team has 3 senior engineers, 6 mid-level engineers, and 3 engineers in their first 90 days. The migration must not break the CI pipeline and must not slow down the team's release cadence.

Passing score: 75%. Answers are checked in this browser.