Git, CI/CD & GitOpsXVI · Restore and SwitchRestoreSwitch
Migrating team habits — muscle memory, training, CI scripts, and what to update when migrating
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
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 mainfor 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 checkoutfor years parse its output and rely on its exit code. - Aliases. Engineers who have aliased
git cotogit checkoutneed 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 switchandgit restore; legacygit checkoutlines 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 togit restore --stagedandgit 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 checkoutinvocations - 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 maingit checkout -b feature/x->git switch -c feature/xgit checkout -- file->git restore filegit 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 switchandgit restore. - Runbooks. Each runbook that references
git checkouthas 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 checkoutin 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
- Adopt a policy, not a rewrite. New code uses the new commands; legacy code is modernised when touched; stable code is not rewritten.
- Document the policy in CONTRIBUTING. Engineers who join the team need the rule in writing.
- Audit CI scripts during the migration window. Pure renames are safe; ambiguous arguments require intent verification; behaviour-different flags require decisions.
- Keep
git coas a transition alias. Retiring the alias too early forces a muscle-memory reset that causes mistakes. - Review against the new conventions. The checklist
item “uses
git switchfor branch work andgit restorefor file work” is the lightest-weight enforcement.
Cross-course references
- Ansible for Production Sysadmins - Part XXXVII
(RepoArch) has a runbook entry on the
git switchmigration 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+ retainedgit coapproach. - 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
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?
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.
Q3. Name the three categories a CI script audit should classify `git checkout` lines into, and what action each category implies.
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.