Why Git belongs in infrastructure work

A change to an SSH baseline, a systemd unit, a firewall rule, an Ansible role, a Terraform module, or a runbook can affect real services. Git gives a team a reviewable history: what changed, who proposed it, which version was approved, and how to return to a known commit when a change needs investigation.

This guide is for infrastructure and cloud teams, automation engineers, DevOps and platform practitioners, and others who manage systems through code. It focuses on using Git to review and coordinate operational changes in repositories hosted on GitHub, GitLab, Azure DevOps, or another platform. You do not need to be an application developer to benefit from these workflows.

Keep the roles clear. Git stores and versions files. A hosting platform adds pull or merge requests, permissions, policy checks, issues, and sometimes CI/CD. A pipeline or GitOps controller performs delivery. A commit alone does not change a server.

A useful mental model

Keep three places distinct while you work: the working tree (files you can edit), the index (the exact changes staged for the next commit), and the repository history (commits already recorded). A remote such as origin is another repository, commonly hosted on an internal Git service or a provider.

Working tree
The checked-out files and directories. This is where you inspect and edit configuration.
Index / staging area
A proposed snapshot for the next commit. Staging lets you choose which paths or hunks belong together.
Commit
An immutable snapshot reference with a tree, parent commit or commits, identity, timestamp, and message. A branch name points to a commit.
Remote-tracking branch
Your local record of where a remote branch was when Git last fetched it, such as origin/main. It updates on fetch; it is not a live connection.

Git stores file contents as blobs, directory structure as trees, and history as commits connected through parent links. The official Git data model reference ↗ describes these objects. A commit’s tree tells you the complete version of the repository at that point, not merely a patch file.

A safe daily workflow

Start by confirming which repository, branch, and local changes you are dealing with. These checks are useful before editing a production configuration repository or switching branches.

Inspect your workspace
git status --short --branch
git remote -v
git branch --show-current
git fetch --all --prune

A clean branch workflow keeps the change isolated, lets you inspect exactly what will be committed, and gives reviewers a small diff. Replace example branch and path names with your team’s conventions.

Example: update an SSH baseline
git switch main
git pull --ff-only origin main
git switch -c change/update-ssh-baseline

# Edit the intended files, then inspect the complete change.
git status --short
git diff --check
git diff -- path/to/configuration

# Stage only the reviewed files.
git add path/to/configuration
git diff --cached -- path/to/configuration
git commit -m "Update SSH baseline"
git push -u origin change/update-ssh-baseline

git diff shows unstaged edits; git diff --cached shows what will enter the next commit. git diff --check catches whitespace errors. In a larger change, git add -p lets you stage selected hunks rather than entire files.

Inspect before staging. Do not stage an entire repository with git add . unless you have reviewed every changed and untracked file. Local inventories, generated plans, state files, logs, and credentials can appear unexpectedly.

Branches, checkout, and remotes

A branch is a movable name pointing at a commit. Creating one is inexpensive; it does not copy the whole repository. Use short-lived topic branches for a defined operational change, such as change/rotate-log-policy, fix/sshd-baseline, or infra/add-staging-subnet.

Branch inspection and navigation
git branch --list
git branch --all
git switch -c change/rotate-log-policy
git switch main
git branch --show-current
git branch -vv

git switch -c creates and switches to a branch. git branch lists or creates branches but does not switch you. Modern Git separates navigation into git switch and file restoration into git restore. git checkout remains supported, but it serves both purposes and can be less clear when learning or scripting.

Use git fetch to download objects and update remote-tracking refs without integrating them into your current branch. Use git pull when you intentionally want fetch plus an integration step; that step may merge or rebase depending on configuration. git pull --ff-only origin main refuses to create a merge if the histories have diverged.

When publishing a new branch, git push -u origin branch-name sets its upstream so later pushes can usually use git push. See the official branch, switch, checkout, fetch, pull, and push manuals.

Commits and change review

A commit should explain a coherent operational change. “Update config” is hard to search later; “Set a 14-day journald retention limit” tells the reviewer and on-call engineer what the change intends to do. Link the relevant incident, ticket, change record, or service when your team’s policy allows it.

Before committing, confirm the staged paths and staged diff. Write a short imperative summary and add context in the body when the reason or operational risk is not obvious.

Review the staged snapshot
git status --short
git diff --cached --name-status
git diff --cached
git commit -m "Set journald retention to 14 days"

Commits are local until pushed. The platform’s branch protection and pull or merge request policy decide whether a commit can be integrated into a protected branch. Prefer review for changes that affect shared systems, access controls, production configuration, or infrastructure state.

Trees, commits, and history graphs

In Git, a tree stores the directory structure for a snapshot. Tree entries point to blobs (file contents) or other trees (subdirectories), along with path names and file modes. A commit points to a root tree and its parent commit or commits. Branches and tags give human-readable names to points in that history.

The word “graph” usually refers to the commit history as a graph of parent-child relationships. A normal commit usually has one parent; a merge commit can have multiple parents. That is why the history can branch and later join without Git storing a separate full copy for every branch.

Read the repository tree and commit graph
git log --graph --oneline --decorate --all -20
git show --stat --oneline HEAD
git ls-tree HEAD
git ls-tree -r --name-only HEAD
git cat-file -p HEAD
git rev-parse 'HEAD^{tree}'

git ls-tree lists entries from a tree; use -r --name-only to list tracked paths recursively. git cat-file -p HEAD inspects the commit object; git rev-parse 'HEAD^{tree}' resolves the tree referenced by HEAD. These are inspection commands; they do not change the working tree.

For readable topology, start with git log --graph --oneline --decorate --all. Add --first-parent for an integration-branch view that hides much of the side-branch detail. Add -- path/to/file to trace changes affecting a configuration file. See the official git-log, git-ls-tree, and git-cat-file references.

*   52acb10 (HEAD -> main) Merge pull request #42
|\
| * c910e2a (change/ssh-baseline) Set SSH idle timeout
| * 12f8c11 Document SSH baseline change
|/
* 08d41ab (tag: infra-v1.4) Add Linux host baseline

This example shows a merge commit with two parents. A host may squash a pull request into one commit or rebase its commits during merge; those choices change the visible topology, not the fact that reviewed work was integrated.

Merge or rebase?

Both commands integrate work, but they record history differently. A merge combines histories and, when they have diverged, creates a merge commit with both histories as parents. A rebase replays commits onto a new base, creating new commit IDs and producing a more linear history.

OperationWhat it doesUseful whenTeam caution
MergeCombines histories; a divergent merge records both parents.You want to preserve the integration point or are integrating shared work.The branch relationships stay explicit in history.
RebaseReplays commits on a different base and creates new commit IDs.You are updating your own topic branch before review or integration.Do not rewrite commits teammates already use as a shared base.
Fast-forwardMoves a branch pointer forward when it has no unique commits to reconcile.A simple integration is possible and policy permits it.--ff-only fails when a true merge is needed.

For example, rebase your own unshared topic branch on the latest remote main to make review easier. Merge shared branches when preserving the integration history matters. Repository merge policy should match the team’s audit, release, and incident-review needs.

Rebase a private topic branch
git fetch origin
git switch change/update-ssh-baseline
git rebase origin/main

# After resolving a conflict and staging the file:
git add path/to/resolved-file
git rebase --continue

# To cancel the in-progress rebase:
git rebase --abort

During a rebase conflict, resolve the file, stage it, and run git rebase --continue. Use git rebase --abort to cancel. If a branch is already published and others may have based work on it, coordinate before rewriting it; a normal push will reject rewritten history for a reason. Read the official merge and rebase manuals before using less familiar flags.

Conflicts and recovery

A conflict means Git cannot safely choose between competing edits. Inspect the conflict markers and surrounding configuration, then resolve the intent—not just the syntax. For infrastructure, validate the result with the relevant linter, plan, policy check, or test before committing.

  • git restore path restores a tracked working-tree file from the index. Review first; this discards unstaged edits to that path.
  • git restore --staged path removes a path from the next commit while keeping the working-tree edit.
  • git revert <commit> creates a new commit that reverses a previous commit. It is usually safer for published shared history.
  • git reset moves the current branch pointer. Its modes affect the index and working tree differently; avoid --hard unless you intend to discard local tracked changes.

If unsure what a reset or rebase changed, stop and inspect git status, git log --graph --oneline --decorate --all, and git reflog before taking another action. The reflog is a local record of recent reference movements, useful for recovery but not a substitute for a remote backup.

Branching strategies for delivery

A branching strategy describes how work moves from an isolated change to an approved release or deployment. Pick the simplest model that matches release cadence, support requirements, and compliance controls. A branch named production does not itself make an environment safe or deployed; platform rules and automation define that behavior.

WorkflowTypical branch shapeGood fitWatch for
Trunk-based / short-lived topicsmain plus short-lived change/* branches; reviewed changes merge frequently.Continuous delivery and infrastructure teams that validate small changes quickly.Protect main, keep requests small, and use staged rollout where needed.
GitHub Flow styleBranch from default, commit, open a pull request, review, merge, deploy.A simple branch-and-review loop for app or operations work.The name describes a workflow, not a Git command; configure host checks.
Release branches / Git FlowLonger-lived release lines with temporary feature or hotfix branches.Products or infrastructure modules maintaining multiple supported versions.Backports and merge coordination grow with every supported line.
Branch per environmentFor example main, staging, and production.Explicit promotion gates or systems that deploy from named environment branches.Branches can drift. Define how fixes move back and how a promoted commit is identified.

A useful starting point for many infrastructure repositories is one protected main and short-lived branches per change. A pull request can run formatting, static validation, security checks, and an infrastructure plan; reviewers inspect the diff and plan; an approved merge can trigger a controlled apply or release. Keep production approval separate when your risk model requires it.

See GitHub Flow, Azure Repos branching guidance, and GitLab’s branching strategy guide for provider-specific examples.

Git and GitOps

GitOps is not simply “deploy whenever a branch changes.” The OpenGitOps principles describe desired state as declarative, versioned, and immutable; an agent automatically pulls it and continuously reconciles actual state toward that desired state. A Git-backed workflow can make infrastructure changes auditable, but the reconciliation agent, permissions, validation, and rollback design matter too.

For Kubernetes, a repository might keep common manifests under apps/base and environment-specific overlays under clusters/staging and clusters/production. A controller watches a declared repository revision and reconciles the selected path. Production promotion can be a reviewed change to the production overlay or a separate promotion pull request.

For Terraform or server configuration, Git can hold code and reviewed inputs while CI runs checks and produces a plan. A human or protected pipeline approves the apply. That is a Git-based delivery workflow, but it is not automatically continuous reconciliation in the strict GitOps sense unless a controller continuously compares and corrects actual state.

Useful GitOps default: use reviewed paths, overlays, immutable image or module versions, and promotion commits to represent environment changes. Branch-per-environment can work, but it needs disciplined promotion and drift controls.

Read the OpenGitOps principles and Flux’s guide to Git repository structures for GitOps.

Repository and project platforms

Git works across hosting providers. These platforms add collaboration and project-management features around Git; product scope, hosting choices, integrations, and plans differ. Choose based on identity and access management, audit needs, CI/CD, deployment controls, data residency, and your existing tools.

PlatformUseful forOfficial starting point
GitHubHosted repositories, pull requests, branch protections, collaboration, and GitHub Actions.GitHub Flow docs ↗
GitLabHosted or self-managed repository collaboration, merge requests, CI/CD, and project planning.GitLab docs ↗
Azure DevOps / Azure ReposGit repositories, pull requests, branch policies, and integration with Azure Boards and Pipelines.Azure Repos docs ↗
AWS CodeCommitAWS-managed private Git repositories with IAM-based access and integrations across AWS developer tools, including CodePipeline and CodeBuild.AWS CodeCommit User Guide ↗
Bitbucket CloudGit hosting and pull requests with Atlassian integrations and Bitbucket Pipelines.Bitbucket docs ↗
Gitea / ForgejoSelf-hosted software for teams that want to operate their own Git forge.Gitea docs ↗ · Forgejo docs ↗
Gerrit Code ReviewGit-based collaboration centered on explicit code review and submit workflows.Gerrit overview ↗
SourceHutA hosted development platform with Git repositories and a mailing-list-oriented collaboration model.SourceHut docs ↗

A repository host is not automatically a deployment platform for every target. Check how it authenticates to cloud accounts, runs privileged pipelines, protects production branches, and records approvals before using it to apply infrastructure changes.

Operational safeguards

  • Keep secrets out of Git. Use a secret manager or approved injection workflow. .gitignore does not remove secrets already committed or make them safe.
  • Review generated state and plans. Terraform state and plan files can contain sensitive values. Keep them out of ordinary source control unless there is an explicit encrypted, access-controlled design.
  • Protect shared branches. Require review and status checks for production or release branches; restrict direct pushes according to policy.
  • Make the target explicit. Before a push, merge, apply, or deployment, confirm repository, remote, branch, workspace, account, and environment.
  • Use an appropriate rollback. Reverting a published change creates a proposed configuration change; it still needs validation and controlled deployment.
  • Do not treat Git as a backup plan by itself. Configure repository backups or mirrors and test restoration.

If a credential is committed, revoke or rotate it first. Removing it from the latest tree does not erase it from earlier history or other clones. Read the official gitignore documentation ↗ and your host’s branch-protection guidance.

Official references

Good infrastructure change is more than a command that worked once. Git makes a change reviewable, repeatable, and easier to reason about together.

Start with one low-risk repository, learn how your team reviews changes, and build the habit before you automate delivery.