,

Git-friendly habits for beginners

15 min read
Featured image: Git habits for beginners

Tuesday, 11:40 a.m. You asked Codex to fix a null check in a checkout helper. The patch looked fine in the chat summary. You committed straight to main with the message “fix stuff,” pushed, and went to lunch. By 1:15 a teammate’s PR no longer merges cleanly. By 1:40 someone is asking why a test file disappeared. By 2:00 you are Googling how to “undo a git push without breaking everything.” The model did not ruin your day. The missing git habits did.

This is Part 5 of the ChatGPT Codex / coding tutorial, and it closes the series. Parts 1 through 4 covered opening Codex and a first project, exploring a repo safely, skills/tasks/scheduled help as the product offers them, and the review loop where green checkmarks are not a ship button. Here we make the multiplayer layer boring on purpose: branch per task, small commits, descriptive messages, pull request review, never force-pushing blind, and undo basics you can use without drama. Codex is done when you can change code, review it, and reverse course without rewriting history like a thriller plot. Next on the ChatGPT track: the Custom GPTs tutorial.

What you’ll learn

  • Why agent speed without git hygiene creates expensive messes
  • The five-habit loop: branch, small commits, messages, PR review, no blind force-push
  • Commit and PR examples you can copy and tighten
  • Undo basics: unstage, discard, reverse a bad local commit, recover after a bad push without panic
  • A short checklist for Codex sessions that end in a clean PR
  • A recap of this five-part Codex series and where Custom GPTs fit next

Git host UIs and Codex surfaces change. The habits below are durable. Re-check your team’s branch protection and OpenAI’s current Codex docs the week you write team policy.

Why git habits matter more with Codex

Without an agent, a messy git day often means a few files and a confused afternoon. With Codex (or any coding agent), a single session can touch many paths, rewrite tests “to green,” reformat unrelated folders, and leave you with a diff that looks successful in chat and reckless in review. Speed multiplies both good and bad process.

Git is not a status symbol. It is a time machine and a team agreement. Branches isolate risk. Commits are restore points. Messages are the story other humans (and future you) read under pressure. Pull requests force a second look. Force-push rewrites shared history, so treating it casually is how trust evaporates.

Part 4 already said: read the diff, run tests, check secrets, check scope, human commit. This part is the packaging around that loop so your good review does not land as a pile of anonymous noise on main.

The five-habit loop

Memorize this sequence the way you memorize “look both ways.” It is the whole post in one strip.

Git-friendly habits for beginners: branch per task, small commits, descriptive messages, PR plus review, never force-push blind
HabitWhat good looks likeWhat fails
Branch per taskOne ticket or goal → one branch → one PRHalf agent runs stacked on main
Small commitsRestore points you can explain in one breathOne mega-commit with “all the Codex stuff”
Descriptive messagesWhy + what; readable in a logfix, wip, asdf, emoji-only noise
PR + reviewSecond human (or you after a break) sees the same diffDirect push because “it was small”
Never force-push blindKnow who shares the branch before rewriteHistory rewrite after someone already pulled

Habit 1: branch per task

Start every Codex job that will edit shared code on a named branch. Not because pure ceremony feels good. Because isolation is cheap and recovery is expensive.

Name the work before you open the agent

Pick a branch name that matches the ticket or the one-sentence goal. Examples:

git switch -c fix/checkout-null-guard
git switch -c feat/export-csv-button
git switch -c chore/bump-lint-config

If your host already created a branch from the issue, use that. Do not invent a second parallel name for the same work.

One goal per branch

Codex loves to helpfully “also clean up” nearby files. Your branch contract is: one main idea. If the agent starts a second idea (rename a module while fixing a null check), stop, restore the extras or move them to a new branch, and keep the PR reviewable. Part 3’s complexity ladder still applies: multi-file work is fine; multi-mission work is not free.

Never use main as a scratchpad

main (or master, or your release branch) is for integrated, reviewable work. Agent experiments, half prompts, and “let me try something wild” belong on throwaway or feature branches. If your team has branch protection, good. If not, behave as if it exists. Your future self is a teammate.

Habit 2: small commits

Agents can generate a large patch in one sitting. That does not mean you must store it as one opaque blob. Small commits are restore points and teaching tools for reviewers.

What “small” means in practice

Small is not “one character.” Small is “one coherent step a human can describe.” For a typical Codex session that might mean:

  • Commit A: failing test that captures the bug
  • Commit B: production fix
  • Commit C: docs or comment only if truly needed

Or for a feature:

  • Commit A: types / interface change
  • Commit B: implementation
  • Commit C: tests

If the agent dumped everything at once, you can still stage in slices before you commit. Use git add -p (patch mode) or stage specific paths. You are allowed to reorganize the story even when the model produced a single wave of edits.

What not to mix

MixWhy it hurts
Feature + mass reformatReview becomes “noise vs signal”
Bugfix + dependency bumpTwo risk profiles in one review
Real fix + deleted flaky testsHides regressions as “cleanup”
Secrets “for later” + codeSecurity incident wearing a feature costume

If Codex reformatted half the tree while fixing a bug, restore the unrelated formatting, open a separate chore PR later, or reject the run and re-prompt with a tighter scope. Part 2’s bound (“what not to touch”) is a git habit, not only a chat habit.

Habit 3: descriptive commit messages

A good message answers two questions in plain language: what changed and why it matters. It is not a diary of your prompt history. Reviewers should not need the chat transcript to understand the commit.

A simple shape that works

Short summary in imperative mood (about 50 chars)

Optional body: why this change exists, what you verified,
and anything a reviewer should not miss.

Refs: TICKET-123

Examples that pass the standup test (could you say this out loud without cringing?):

fix null guard on checkout when cart is empty

Empty carts hit getItems() without a list. Guard returns early
and adds a unit test for the empty path. Manual check: empty cart
page no longer 500s.

Refs: SHOP-441
Add CSV export for weekly sales report

Exports the same columns as the on-screen table. Uses streaming
writer for large ranges. Verified on sample of 5k rows.

Refs: ANALYTICS-88

Messages that fail the standup test

  • fix, updates, misc, wip, asdf
  • codex did this (true, not helpful)
  • A full paste of the prompt chain
  • Jokes that hide a production risk

If Codex drafts a commit message for you, treat it as a first draft. Rewrite anything you could not defend. Part 4’s rule still stands: human owns the commit button and the story attached to it.

Habit 4: pull request and real review

A PR is a forced pause. It turns “I think this is fine” into a reviewable artifact: title, description, file list, CI status, comments. Even if you are a solo developer, PRs give you CI, a second look tomorrow morning, and a paper trail when something breaks.

What belongs in a Codex-assisted PR description

## Summary
- Ticket / goal:
- One sentence: what this PR is supposed to do

## Agent assist
- [ ] Codex (or other agent) used
- Scope I asked for:
- Extra files the agent touched (and what I did):

## Verification
- [ ] I read the full diff (not only the chat summary)
- [ ] Tests / commands run:
- [ ] No secrets or customer PII in the patch
- [ ] Scope matches the ticket

## Risk
- What could break:
- Rollback: revert this PR / feature flag / follow-up

You do not need a novel. You need honesty. “Codex also rewrote the logging module; I restored it” is gold for a reviewer. “LGTM, AI wrote it” is not a review.

Review checklist that matches Part 4

  • Diff: open the full file list; watch for unrelated paths and deleted tests
  • Tests: CI green on this branch; run the risky path locally if CI is thin
  • Secrets: no keys, tokens, .env bodies, customer dumps
  • Scope: matches the ticket; no surprise architecture rewrite
  • Human commit / merge: a person who understands the change hits the button

If your team requires status checks on protected branches, treat red CI as a stop, not a suggestion. Merging red “to unblock” is how agent-shaped defects become production-shaped incidents.

Habit 5: never force-push blind

Force-push rewrites history on the remote. Sometimes that is correct on a private feature branch you alone use. Often it is a landmine when anyone else has pulled, when CI is mid-run on old SHAs, or when you are “cleaning up” after Codex and do not fully understand what you are erasing.

Default rules that keep teams sane

  • Never force-push main, release branches, or any shared long-lived branch.
  • Prefer new commits (including reverts) over rewriting published history.
  • On a personal feature branch: force-with-lease is safer than force if you must rewrite, because it fails if the remote moved in ways you have not seen. Still: know who else uses that branch.
  • If Codex or a tutorial suggests force-push as the first fix, pause. Ask whether a reverse commit or a new PR would leave a clearer audit trail.

Branch protection on GitHub, GitLab, and similar hosts can block force-pushes to protected branches. Turn that on. Product settings beat sticky-note hope.

When people reach for force-push (and better options)

SituationOften better than blind force-push
Bad commit only on your laptop, not pushedgit reset variants (see undo section)
Bad commit already on shared remoteRevert commit or fix-forward PR
Secret committedRotate the secret first; history rewrite is secondary and needs a real incident process
Messy agent commits on solo branch before PRInteractive rebase only if you own the branch alone and know the tool
You are unsureNew branch from known good tip; open a clean PR; ask a teammate

Force-push is a sharp tool. Sharp tools belong in trained hands with a reason, not as the default “Codex made a mess, erase the evidence” reflex.

Undo basics (without rewriting the universe)

You will need undo. Agents make that more common, not less. Learn a small kit. Practice on a throwaway repo once so panic is not your first tutor.

See what is going on

git status
git diff
git diff --stat
git log --oneline -n 10

If you cannot explain the output of those four commands, do not run destructive history commands yet. Part 4’s smell list pairs well here: unrelated files, deleted tests, secrets, huge rewrites, force-push suggestions.

Unstage or discard local work

# Unstage a path (keep file contents)
git restore --staged path/to/file

# Discard uncommitted changes in a path (destructive to working tree)
git restore path/to/file

# Discard everything uncommitted (nuclear; be sure)
git restore .
git clean -fd   # removes untracked files; double-check first

Prefer path-level restore over nuclear options when Codex only spoiled two files.

Undo a commit that never left your machine

# Keep changes staged, remove last commit
git reset --soft HEAD~1

# Keep changes unstaged, remove last commit
git reset HEAD~1

# Throw away last commit and its changes (only if you are sure)
git reset --hard HEAD~1

--hard deletes work. Soft and mixed keep the edits so you can recommit cleanly. When in doubt, soft first.

Undo something already pushed (shared branch)

Prefer a reverse commit that future people can see:

git revert HEAD
# or revert a specific SHA
git revert abc1234
git push

Revert adds history. That is a feature on shared branches. Force-pushing to pretend the bad commit never existed is how teammates’ clones diverge and incident notes get fuzzy.

“I committed a secret”

Order of operations: rotate the credential first (API key, password, token). Assume anything pushed is compromised. Then remove the secret from the tree going forward, and follow your org’s process for history cleanup if required. Do not treat “rewrite git” as the main fix while the key still works in the wild.

A Codex session that ends clean

Put the five habits into one Monday-ready script.

  1. Name the goal in one sentence. If you cannot, you are not ready for multi-file edits.
  2. Branch from an up-to-date default branch: git switch main && git pull && git switch -c …
  3. Bound the work in the prompt (Part 2): what to touch, what not to touch, how to run tests.
  4. Let Codex edit on that branch only. No silent side quests into deploy scripts.
  5. Review with Part 4’s loop: diff, tests, secrets, scope.
  6. Commit in slices with messages you can defend. Stage intentionally.
  7. Push the feature branch and open a PR. Fill the agent-assist section honestly.
  8. Merge only when review + CI agree. You (or a teammate) own the button.
  9. If something goes wrong, restore paths, soft-reset local commits, or revert on shared history. Do not force-push blind.

That is the entire product of this series packaged as muscle memory: explore safely, escalate complexity on purpose, review hard, package with git habits that other humans can live with.

Worked mini-example: one bug, one branch, two commits

Imagine a tiny Python helper that should return zero items for an empty cart but currently throws. You open Codex after branching.

git switch -c fix/empty-cart-count
# Prompt (sketch): “Add a failing test for empty cart item count,
# then fix cart.py only. Do not reformat other packages. Show the diff.”

After review you stage and commit in two steps:

git add tests/test_cart.py
git commit -m "$(cat <<'EOF'
Add failing test for empty cart item count

Empty carts should report zero items. Captures the current throw
so the fix is locked in.

Refs: SHOP-441
EOF
)"

git add src/cart.py
git commit -m "$(cat <<'EOF'
Return zero items when cart list is missing

Guard get_item_count before iterating. Keeps existing behavior for
non-empty carts. Tests green locally.

Refs: SHOP-441
EOF
)"

git push -u origin fix/empty-cart-count
# open PR, paste verification notes, wait for CI

Notice what you did not do: commit on main, one vague “fix cart” blob, force-push after rewriting, or merge before reading the diff. The agent wrote code. You wrote history that a teammate can trust.

Common mistakes

  • Committing on main because “it was a one-liner.” One-liners still break builds.
  • Trusting the chat summary instead of git diff. Summaries skip files and soften risk.
  • One mega-commit for a whole agent afternoon. You cannot restore a middle state.
  • Letting Codex delete flaky tests to get green. That is hiding fire under paint.
  • Force-pushing after a shared PR already has review comments. Comments point at old SHAs; people get lost.
  • Putting secrets in the repo “just for local Codex.” Local secrets still leak when you push the wrong path.
  • Skipping PR description honesty about agent use. Reviewers need the real risk surface.
  • Using Work for code or Codex for press releases. Wrong door, wrong blast radius (see the Work series).
  • Learning force-push before learning restore. Teach reverse and recover first.

Practice (45 minutes)

  1. Clone or open a throwaway repo. Create practice/agent-git-habits.
  2. Make a deliberate mess: edit three files, stage two, commit one bad message on purpose.
  3. Practice git restore --staged, git restore on a path, and git reset --soft HEAD~1.
  4. Run a tiny Codex (or manual) fix on a new branch with a clear message and open a draft PR.
  5. Write a five-line PR description using the agent-assist template above.
  6. Optional: on that solo branch only, try an interactive rebase or soft reset, then push with a normal (non-force) update if you rewrote nothing published. If you do not fully understand the command, skip force entirely.
  7. Note one personal rule you will keep: for example “no commits on main” or “always git diff --stat before commit.”

What this Codex series covered

ChatGPT Codex / coding tutorial was the deep coding-agent track for people who will touch a real project with ChatGPT’s coding surface:

PartFocus
1Open coding features and first project
2Exploring a repo safely (ask, map, bound, then change)
3Skills, tasks, and scheduled help as the product offers them
4Review, tests, and not trusting green checkmarks alone
5Git-friendly habits for beginners (this post)

If you keep one idea from five parts: Codex is a strong pair-programmer with tools, not an unsupervised release engineer. Explore before you edit. Escalate complexity on purpose. Review diffs like a skeptic. Package work so git history and teammates can survive your speed.

Where this sits on the ChatGPT path

Series path on AMS ChatGPT track: Learn, Map, Everyday, Work, Codex here, Custom GPTs next

Orientation and earlier tracks still matter when you are choosing doors:

What comes next: Custom GPTs tutorial

This closes the ChatGPT Codex / coding tutorial. Next deep track on the plan is the Custom GPTs tutorial: build a simple GPT for a repeating task; instructions, knowledge files, and light actions; share with a team without chaos; and when a Custom GPT is the wrong solution.

Custom GPTs are not “Codex but friendlier.” They are packaged recipes for chat-shaped work: a stable instruction set, optional files, optional actions, shared with a group. You bring the same judgment you practiced here (scope, secrets, verification), applied to prompts and knowledge instead of pull requests. Do not paste production credentials into a GPT’s knowledge files just because the builder UI makes it easy. Do import the habit of writing down what the thing is for and what it must never do.

If your day job is still pure software on a repo, stay on the Codex habits in this post and keep shipping through PRs. If your day job is “the same analysis brief twelve times a month,” Custom GPTs are the next lesson. Wrong tool, wrong series: that chooser is the point of the whole ChatGPT track on AMS.

Quick recap

  • Branch per task; keep main clean.
  • Prefer small commits you can restore and explain.
  • Write messages that pass the standup test.
  • Open a PR; review the real diff; keep CI honest.
  • Never force-push blind on shared history; prefer revert on remotes.
  • Learn undo kit: status, diff, restore, soft reset, revert.
  • Series done: open → explore → power-ups → review → git habits.
  • Next: Custom GPTs tutorial for packaged chat recipes, not repo agents.

Sources

Research and further reading used for this article: