---
title: "Git for People Who Use Agents: Branches, Small Commits and How to Go Back"
url: https://www.stacklogs.io.vn/en/engineering/git-for-people-who-use-agents/
language: en
author: "Nhu Duy Thin (Thinnd)"
published: 2026-10-30
updated: 2026-10-30
section: "Engineering"
tags: ["git", "AI agent", "branches", "commits", "undo", "worktree", "checklist"]
summary: "When you hand work to an AI agent, give each task its own Git branch, ask for small commits as save points, read git status and git diff before accepting, and know four ways back: git restore for uncommitted changes, git revert for existing commits, git reflog to rescue after a reset, and git worktree so the agent works in its own folder. Uncommitted changes that are restored cannot be recovered by Git."
license: "Cite with the author name and the canonical URL above."
---

# Git for People Who Use Agents: Branches, Small Commits and How to Go Back

> For anyone who hands code work to an AI agent, including people who have never used Git. No background needed. Every term comes with an everyday picture, and the parts with commands are marked so you can copy them or skip them.
>
> Every command and output in the worked example was really run in a practice repository (Git version 2.56.0, 30 October 2026). Scenarios marked "illustration" are made up and name no real person or company. How an agent goes wrong inside is not fully understood by anyone, so the pictures below are memory aids only.

---

## Quick summary

- An agent can edit many files in minutes. Without a way back, one bad edit can swallow a whole working session. **Git is the save point**: it remembers only what you have committed.
- The core habit: **one branch per task you give the agent**, ask the agent for **small commits**, and **read `git status` and then `git diff` before accepting the result**.
- There are four ways back, each for its own situation: `git restore` (not committed yet), `git revert` (already committed, the safest), `git reflog` (rescue after a slip), `git worktree` (let the agent work in its own folder from the start).
- The biggest blind spot: **uncommitted changes that are discarded with `git restore` cannot be recovered**. In this post's practice repository, the reflog had no entry for them.
- Save points only cover files in the repository. A deleted database or a sent email lies outside Git.
- Destructive commands (`push --force`, `reset --hard`, `clean`) belong in the agent's instructions as **do not run without asking**.

---

## Hard words, plain meaning

| Term | Plain meaning |
|---|---|
| **Repository** | The project folder plus the whole history of its saves. |
| **Commit** (save point) | One save with a name and a note, like pressing "save game" at one spot. You can always return to it. |
| **Branch** | A separate path split off from the main copy, for trying things without breaking the main copy. |
| **Diff** | The exact list of which lines were added and which were removed since the last save point. |
| **Revert** | Make a new save point that does the opposite of an older one. The history stays intact. |
| **Reset** | Move the branch back to an older save point. With `--hard`, uncommitted changes are deleted. |
| **Reflog** (movement log) | A notebook listing in order where the HEAD pointer has stood, used to find a save point that seems to have vanished. |
| **Stash** | Put work in progress into a temporary drawer so your hands are free, and take it out later. |
| **Worktree** | A second folder of the same repository, standing on another branch, like a separate desk. |

---

## 1. A picture first: a game with save points

Picture a long game. If you never save, dying once costs you an hour of play. If you save every few minutes, dying costs a few minutes.

Handing work to an agent is the same. An agent is a very fast, slightly hasty player: it can edit ten files before you finish reading the first. It is good but not always right, and the documentation of agent tools says as much (see section 6). **A save point does not make the agent err less. It makes the error cheaper.**

Git plays that role, with one important rule: **Git remembers only what has been committed.** Changes sitting in the folder without a commit are like playing mid-level without saving.

**Takeaway:** before you hand over a task, have a clean save point. While the agent works, ask it to save often.

---

## 2. The five-step routine: one branch per task

Picture a dinner table with several trays: you do not try a new dish on the main plate, you put it on a separate plate. If it fails, you throw the plate away and the main plate is untouched.

Everything below was run in a practice repository with one file, `prices.py`, which adds up an order total. There is one first save point on the branch `main`.

### Step 1. Make a branch for this task

```bash
git switch -c agent/add-discount
```

```text
Switched to a new branch 'agent/add-discount'
```

The naming habit `agent/task-name` lets you see at a glance which branches belong to the agent. It is my habit, not a Git rule.

### Step 2. Hand over the task and let the agent work

You ask the agent: "add an optional discount parameter to the `total` function". The agent edits the file.

### Step 3. Read `git status` and then `git diff` before accepting

```bash
git status -sb
git diff
```

```text
## agent/add-discount
 M prices.py
diff --git a/prices.py b/prices.py
index de87eb8..d7bc76f 100644
--- a/prices.py
+++ b/prices.py
@@ -1,2 +1,3 @@
-def total(items):
-    return sum(item["price"] * item["qty"] for item in items)
+def total(items, discount=0):
+    subtotal = sum(item["price"] * item["qty"] for item in items)
+    return subtotal * (1 - discount)
```

`M` means one file was modified. A line starting with `-` was removed, a line starting with `+` is new. This reading is the "open the evidence" step from [Make AI Output Prove Itself](https://www.stacklogs.io.vn/en/engineering/make-ai-output-prove-itself/), and the first part of [reviewing AI-written code](https://www.stacklogs.io.vn/en/engineering/reviewing-ai-written-code/).

### Step 4. Commit small, like a save point

```bash
git add prices.py
git commit -q -m "feat: add optional discount to total"
git log --oneline
```

```text
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
```

The `-q` flag only keeps the command quiet. One job per commit, describable in a sentence, in the `feat: job name` style of Conventional Commits (a popular note-writing convention, not mandatory).

### Step 5. Merge when you are satisfied

When you have read the diff and run the checks, you are the one who merges the branch into `main`:

```bash
git switch main
git merge --no-ff -q agent/add-discount -m "merge: add discount"
git log --oneline --graph
```

```text
*   04cbf8d merge: add discount
|\  
| * 5aee66b feat: add extra script
| * c5b6fbf Revert "refactor: simplify total"
| * 6f88dd0 refactor: simplify total
| * c9c7cf3 feat: add optional discount to total
|/  
* 6dd4973 feat: add total function
```

The `main` branch only receives what you have looked at. The middle save points (`refactor`, `Revert`, `extra script`) come from the experiments in section 3.

### 2.1 A calculation you can redo (illustration, skippable)

This is an example with made-up numbers. Suppose an agent works for 3 hours (180 minutes) without a break and something goes wrong in the last minute.

```python
session = 180
no_commit_loss = session            # never saved: lose up to 180 minutes
every = 20
saves = session // every            # 9 save points
worst_loss = every                  # lose at most 20 minutes
print(saves, worst_loss, session - worst_loss)
# 9 20 160
```

Reading the result: committing every 20 minutes gives 9 save points, and the worst accident costs at most 20 minutes instead of 180, so 160 minutes are kept. The 20 minutes is my assumption for the illustration. Real life has no formula, but the rule is to make steps small enough to look back at and dare to throw away.

---

## 3. Going back: the right command for the right situation

Picture accidentally deleting a paragraph. How you get it back depends on whether you had saved the document.

| Situation | Command | What happens | Risk |
|---|---|---|---|
| The agent just edited wrongly, nothing committed | `git restore file-name` | The file goes back to the last committed version | **Uncommitted changes are lost for good** |
| A commit exists and is wrong | `git revert HEAD` | A new commit undoes it, history stays | Safe |
| Work in progress, you need free hands | `git stash push -m "note"` | Put aside, later `git stash pop` | Safe |
| You need to pull the branch back to an older point | `git reset --hard save-point` | The branch moves back, uncommitted changes are deleted | **Dangerous**, commits can be rescued with reflog |
| You slipped on a reset | `git reflog` then `git reset --hard HEAD@{n}` | Find where HEAD used to be | Rescues commits, not uncommitted changes |

### 3.1 `git restore`: discard uncommitted changes

The agent edits the file into a useless function:

```bash
git status -sb
git diff --stat
git restore prices.py
git status -sb
```

```text
## agent/add-discount
 M prices.py
 prices.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
## agent/add-discount
```

After `restore`, `git status` no longer shows the `M` line, meaning the file is back to the committed version. Warning: **if the discarded change was something you wanted to keep, there is no way back**. I tested it: edit the file, run `git restore`, then look at the reflog and the stash list.

```bash
git reflog | head -2
git stash list | wc -l
```

```text
5aee66b HEAD@{0}: reset: moving to HEAD
5aee66b HEAD@{1}: reset: moving to HEAD@{1}
       0
```

The two reflog lines belong to earlier operations. There is no record for the discarded line, and the stash list is empty (0 entries). The `git restore` manual page describes the command as restoring content from a source, so the current content is replaced. To keep it, `git stash` first, or commit first.

### 3.2 `git revert`: undo an existing commit

The agent commits a "simplification" that breaks the function:

```bash
git commit -qam "refactor: simplify total"
git revert --no-edit HEAD
git log --oneline
```

```text
[agent/add-discount c5b6fbf] Revert "refactor: simplify total"
 Date: Fri Oct 30 17:31:17 2026 +0700
 1 file changed, 2 insertions(+), 1 deletion(-)
c5b6fbf Revert "refactor: simplify total"
6f88dd0 refactor: simplify total
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
```

The broken commit stays in the history, and a new commit undoes it. According to the Git documentation, `git revert` creates new commits that undo earlier ones instead of deleting them. Because it does not rewrite history, it is the safe choice on a shared branch.

### 3.3 `git reset --hard` then `git reflog`: a slip can still be rescued

This is the scariest part, so I ran it for real. Add one more commit, then step back two:

```bash
git reset --hard HEAD~2
git log --oneline
ls
```

```text
HEAD is now at 6f88dd0 refactor: simplify total
6f88dd0 refactor: simplify total
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
prices.py
```

The file `extra.py` disappeared from the folder, and the function in `prices.py` went back to the broken version. But the reflog remembers:

```bash
git reflog | head -8
```

```text
6f88dd0 HEAD@{0}: reset: moving to HEAD~2
5aee66b HEAD@{1}: commit: feat: add extra script
c5b6fbf HEAD@{2}: revert: Revert "refactor: simplify total"
6f88dd0 HEAD@{3}: commit: refactor: simplify total
c9c7cf3 HEAD@{4}: commit: feat: add optional discount to total
6dd4973 HEAD@{5}: checkout: moving from main to agent/add-discount
6dd4973 HEAD@{6}: commit (initial): feat: add total function
```

The save point `5aee66b` is still there. Set the branch back to it:

```bash
git reset --hard HEAD@{1}
git log --oneline
ls
```

```text
HEAD is now at 5aee66b feat: add extra script
5aee66b feat: add extra script
c5b6fbf Revert "refactor: simplify total"
6f88dd0 refactor: simplify total
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
extra.py
prices.py
```

Everything is back. According to the Git documentation, reflog entries are kept for 90 days by default, and 30 days for entries no longer on any branch, so rescue early. The reflog is a notebook on **your machine** and is not pushed to the server.

### 3.4 `git stash`: put work in progress aside

```bash
git stash push -m "half done idea"
git stash list
git stash pop
```

```text
Saved working directory and index state On agent/add-discount: half done idea
stash@{0}: On agent/add-discount: half done idea
Dropped refs/stash@{0} (377cf291f166fc06e84e9ac41e27da37fa79d8d9)
```

Between the two commands, `git status` was clean. After `pop`, the changes came back. Use it when you want free hands to let the agent do something else, without making a half-baked commit.

**Takeaway:** remember one sentence: *what is committed can almost always be rescued, what is not committed cannot.* That is why you commit small.

---

## 4. Worktree: give the agent its own desk

Picture a kitchen with two counters: you cook at one, the assistant cooks at the other. Same kitchen, same pantry, but you do not bump elbows.

A worktree is a second working folder of the same repository. According to the Git documentation, it shares the repository with the main folder but has its own `HEAD` and index, and by default Git does not let two worktrees stand on the same branch.

```bash
git worktree add ../demo-git-wt -b agent/refactor-names
git worktree list
```

```text
Preparing worktree (new branch 'agent/refactor-names')
HEAD is now at 5aee66b feat: add extra script
/path/to/demo-git    5aee66b [agent/add-discount]
/path/to/demo-git-wt 5aee66b [agent/refactor-names]
```

(I shortened the paths to `/path/to/` for readability.) Now the agent works in `demo-git-wt` while you keep editing in the main folder. When it is done, clean up:

```bash
git worktree remove ../demo-git-wt
git branch -d agent/refactor-names
```

```text
Deleted branch agent/refactor-names (was 5aee66b).
```

Without `--force`, `git worktree remove` only removes a clean folder. Claude Code has a shortcut, `claude --worktree job-name`, that opens a session in a new worktree, according to its Common workflows page. Other tools may have their own way, so check the documentation of the tool you use.

---

## 5. House rules for the agent

Picture handing a house key to a helper: you say which rooms they may enter and which not.

### 5.1 Habits worth writing down as rules

- **Do not commit straight to `main`.** One branch per task.
- **No `push --force`**, and no pushing without asking. Pushing to a server is an action other people see.
- **No `reset --hard`, no `clean`, no deleting branches** without asking. `git clean` deletes files Git is not tracking, so I treat them as having no copy to rescue.
- **Do not touch files that hold keys**, such as `.env`. Let `.gitignore` block them, and check with `git check-ignore -v .env`.

```bash
git check-ignore -v .env
```

```text
.gitignore:1:.env	.env
```

The line says the rule on line 1 of `.gitignore` is blocking the file `.env`. (In the practice repository my environment would not let me create a real `.env` file, so I only checked the rule and did not try `git status` with a real file.)

### 5.2 Five lines to paste into the agent's instructions

Put this block in [AGENTS.md or your tool's instruction file](https://www.stacklogs.io.vn/en/engineering/writing-agents-md/):

```text
## Git
- Work on a branch named agent/<task-name>, never commit straight to main.
- Commit small, one job per commit, run the checks before committing.
- Do not use push --force, reset --hard, clean or delete branches without asking.
- Do not push. Do not edit .env or any file that holds keys.
- At the end: paste the output of git status and git diff --stat.
```

This is guidance written in words, and an agent may ignore it. It is the first barrier, not the only one: also use the tool's permission settings and the branch protection of your code hosting service, if available.

### 5.3 What an agent's commit note should look like

```text
feat: add optional discount to total

- discount defaults to 0, so existing callers keep working
- checked with: python -m pytest tests/test_prices.py (3 passed)
```

The first line says what, the body says why and how it was checked. The note is itself a small piece of evidence, in line with way 2 in [Make AI Output Prove Itself](https://www.stacklogs.io.vn/en/engineering/make-ai-output-prove-itself/).

---

## 6. Numbers and documents used

| Source | Says | How to read it | Caveat |
|---|---|---|---|
| Git, `git-restore` page | Restores paths from a source, current content is replaced | Basis for the warning about losing uncommitted changes | The page does not say outright that it cannot be recovered, that is the result I tested |
| Git, `git-revert` page | Creates new commits that undo earlier ones, without deleting them | Basis for section 3.2 | Needs a clean folder when reverting |
| Git, `git-reflog` page | Records where references used to be. Kept 90 days by default, 30 days for entries no longer on a branch | Basis for section 3.3 | Only on your machine |
| Git, `git-worktree` page | A linked worktree shares the repository, with its own `HEAD` and index. By default no two places on one branch | Basis for section 4 | `remove` needs `--force` if the folder is not clean |
| Claude Code docs, Checkpointing | Checkpoints track edits made by file tools. They do not track files changed only by Bash, usually do not restore subagent edits, and are not a replacement for version control | Why Git is still needed | A tool maker's documentation, may change by version |
| Claude Code docs, Common workflows | `claude --worktree job-name` runs a session in its own worktree, and needs a repository with at least one commit | Basis for the shortcut in section 4 | About this tool only |
| News reports (Tom's Hardware, heise) on the Replit case, July 2025 | An agent was reported to have deleted a company's production database during a code freeze | Git save points do not cover a database | Most details come from posts by the person involved, and sources differ on recoverability |
| The practice repository in this post | Every command in sections 2 to 5 was really run | The output is real | One very small repository, one machine, Git 2.56.0, not a survey |

**Read it correctly:** the Git and Claude Code documents support using save points and separate branches. I **did not find** a study measuring how much a separate branch reduces incidents when using agents, so the habits above are good practice, not measured results.

---

## 7. Where save points still fail

Picture saving the game on this machine while the character has already done something in the real world outside.

| Situation | Why it fails | How to avoid or catch it |
|---|---|---|
| Uncommitted changes hit by `restore` or `reset --hard` | Git has no copy | Commit or stash first, commit small and often |
| The agent runs `git clean` | Untracked files have no copy in Git | Forbid it in the rules, add important files to Git |
| The agent pushes, especially `--force` | Changes are on the server, others pull them | Do not allow pushes, protect the main branch, never `--force` |
| A key leaks into a commit | The key lives in the history, `revert` does not erase it | Use `.gitignore`, and treat a leaked key as one you must replace |
| Things outside the repository: deleting a database, sending mail, calling a paid API | Git stores only files | Separate test environments, limit permissions, see the post on [fake packages](https://www.stacklogs.io.vn/en/engineering/slopsquatting-fake-packages/) about permission to run commands |
| A Bash command changes a file the tool is not tracking | The tool's checkpoint does not cover it | Rely on Git, not only on an undo button |
| Too many mixed commits | Hard to tell which point is good | One job per commit, clear notes |

### 7.1 Illustration: a morning with an agent

This is an illustration, naming no real person or product.

- **09:00.** The dev creates the branch `agent/add-discount` and assigns the job "add a discount to the total function".
- **09:20.** The agent says it is done. The dev runs `git diff --stat` and sees that one file changed more than expected. On a closer look, the agent rewrote the whole old function.
- **09:25.** Nothing is committed yet, so the dev has two choices: `git restore` (lose everything, including the good part) or `git stash` and then pick what is needed. The dev chooses stash, keeps the good part, and asks the agent to redo the rest more tightly.
- **10:10.** The agent commits a second time. The dev notices this commit breaks a test and runs `git revert HEAD`. The history stays, the function goes back as before.
- **10:30.** The dev merges into `main` after reading the diff.

What to do: **commit early, read the diff before accepting, and get used to `stash` and `revert` more than `restore` and `reset`.** This illustration proves nothing. The evidence lies in the documents above, and in one real case worth remembering: 2025 news reports said that during a trial by a founder, an agent was reported to have deleted a production database despite a code freeze. The sources disagree on details such as recoverability, and most of the information comes from the person involved. If it happened as told, it was about a database, not files, which lies outside what Git save points cover.

---

## 8. Habits to apply from tomorrow

### 8.1 Eight questions before handing over and before accepting

1. Am I on this task's own branch, or on `main`?
2. Before handing over, is `git status` clean, or is there unsaved work in progress?
3. Does the agent know the Git rules (own branch, small commits, no push)?
4. After the agent worked, have I read `git status` and `git diff`?
5. Was any file changed that I did not ask for?
6. Is there anything that looks like a key or a password in the diff?
7. If I drop this edit, do I use `stash`, `restore` or `revert`, and am I losing anything uncommitted?
8. Does this job touch anything outside the repository (database, mail, API)?

### 8.2 Three things to do right now

1. Paste the five-line block from 5.2 into the instruction file of the tool you use.
2. Try once in a scratch repository: `reset --hard`, then `reflog`, then set it back, so you do not panic when it matters.
3. Turn on protection for the `main` branch on your code hosting service, if it has one.

---

## 9. A balanced view: what Git does and does not do

**What it does:** gives you save points, lets you try things without fear, allows several jobs in parallel through worktrees, and turns every change the agent makes into a readable diff.

**What it does not do:**

- It does not cover things outside the repository: databases, sent mail, money moved.
- It cannot rescue uncommitted changes.
- It does not stop an agent from doing something bad, it only helps you go back after it happens. Prevention needs permissions and rules.
- Learning Git has a cost. For a newcomer, the few commands in this post are enough to start. Harder cases such as merge conflicts take more time to learn.
- I have not seen a controlled trial measuring the effect of each habit. Try them in your team and adjust.

**Do not exaggerate:** Git is not a safety switch. **Do not play it down:** most accidents when using agents on files can shrink to "lost 20 minutes" if a save point is close by.

---

## 10. Conclusion

Agents are fast, and fast even when wrong. Give each task its own branch, ask it to save often, read the diff before accepting, and remember four ways back: `restore` for the uncommitted part (and understand it is a real loss), `revert` for an existing commit, `reflog` to rescue after a slip, `worktree` so each agent has its own desk. A save point does not make the agent err less, but it makes you less afraid.

---

## References

Commands and facts rest on public documentation and a practice repository run on 30 October 2026 (Git 2.56.0). The news reports on the Replit case mostly retell the posts of the person involved, so open the originals before quoting.

- Git, [git-restore](https://git-scm.com/docs/git-restore), [git-revert](https://git-scm.com/docs/git-revert), [git-reflog](https://git-scm.com/docs/git-reflog), [git-worktree](https://git-scm.com/docs/git-worktree)
- Anthropic, [Checkpointing](https://code.claude.com/docs/en/checkpointing) and [Common workflows, section Run parallel sessions with worktrees](https://code.claude.com/docs/en/common-workflows)
- Tom's Hardware, [AI coding platform goes rogue during code freeze and deletes entire company database](https://tomshardware.com/tech-industry/artificial-intelligence/ai-coding-platform-goes-rogue-during-code-freeze-and-deletes-entire-company-database-replit-ceo-apologizes-after-ai-engine-says-it-made-a-catastrophic-error-in-judgment-and-destroyed-all-production-data) and [heise](https://heise.de/-10499597) (July 2025)
- Conventional Commits, [Specification 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/)
