# How the GPT-Engineer Git Staging Feature Tracks Uncommitted AI-Generated Changes

> Discover how GPT-Engineer tracks uncommitted AI-generated changes using its Git staging feature. Protect your local work during AI file generation.

- Repository: [Anton Osika/gpt-engineer](https://github.com/AntonOsika/gpt-engineer)
- Tags: internals
- Published: 2026-03-06

---

**GPT-Engineer automatically detects uncommitted changes in your repository and stages them before writing AI-generated files, ensuring no local work is lost during the generation process.**

The **git staging feature** in GPT-Engineer provides a critical safety mechanism that **tracks uncommitted AI-generated changes** by preserving existing local modifications before new code is written. This functionality, implemented in the [`gpt_engineer/core/git.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/git.py) module, ensures that developers never lose their work when the AI updates or overwrites files in an existing project.

## Understanding the Git Staging Workflow in GPT-Engineer

Before GPT-Engineer writes any AI-generated code to disk, it executes a protective workflow that treats your existing uncommitted changes as the baseline. This approach creates a **safety checkpoint** by staging current modifications, allowing you to later inspect exactly what the AI changed through Git's diff capabilities.

The workflow operates silently in the background unless uncommitted changes are detected, at which point it notifies you which files are being staged before the AI generation proceeds.

## Step-by-Step: How Uncommitted Changes Are Detected and Staged

### Detecting Git Availability

The process begins by verifying that Git is installed on the system. The `is_git_installed()` function checks for the `git` executable before attempting any repository operations.

```python

# From gpt_engineer/core/git.py lines 10-12

def is_git_installed() -> bool:
    """Check if git is installed."""
    return shutil.which("git") is not None

```

### Initializing the Repository

If the project directory is not already a Git repository and the tool is running in standard generation mode (not *improve* mode), `init_git_repo()` automatically runs `git init` to create a new repository.

```python

# From gpt_engineer/core/git.py lines 73-77

def init_git_repo(path: Path) -> None:
    """Initialize a git repository if it doesn't exist."""
    if not is_git_repo(path):
        subprocess.run(["git", "init"], cwd=path, check=True)

```

### Identifying Files with Uncommitted Changes

The core detection logic resides in `filter_files_with_uncommitted_changes()`. This function executes `git diff --name-only` to retrieve a list of paths that have unstaged modifications, then intersects that list with the AI-generated `FilesDict` to identify which files require protection.

```python

# From gpt_engineer/core/git.py lines 41-52

def filter_files_with_uncommitted_changes(
    basepath: Path, files_dict: FilesDict
) -> List[Path]:
    """Return files that have uncommitted changes."""
    # Git returns a newline-separated list of changed paths

    files_with_diff = subprocess.run(
        ["git", "diff", "--name-only"],
        cwd=basepath,
        stdout=subprocess.PIPE
    ).stdout.decode().splitlines()
    
    # Keep only those that appear in the AI file map

    return [f for f in files_dict.keys() if f in files_with_diff]

```

### Staging Files Before AI Generation

When uncommitted files are identified, `stage_files()` executes `git add` to stage them. The system outputs a console message informing the user which specific files are being preserved before the AI writes new content.

```python

# From gpt_engineer/core/git.py lines 54-58

def stage_files(basepath: Path, files: List[Path]) -> None:
    """Stage files to git."""
    for file in files:
        subprocess.run(["git", "add", str(file)], cwd=basepath, check=True)

```

## Implementation Details and Source Code References

The **git staging feature** is orchestrated by `stage_uncommitted_to_git()` in [`gpt_engineer/core/git.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/git.py) (lines 71-86). This high-level function coordinates the entire safety workflow: detecting the repository, initializing it if necessary, filtering for uncommitted changes, and staging them before the AI generation proceeds.

The actual integration point occurs in [`gpt_engineer/applications/cli/main.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/applications/cli/main.py) (lines 48-50), where the CLI calls `stage_uncommitted_to_git()` immediately before writing the AI-generated files to disk via `files.push(files_dict)`.

## Practical Code Examples

### Direct Invocation of the Staging Workflow

You can manually trigger the git staging safety check using the `stage_uncommitted_to_git()` function:

```python
from gpt_engineer.core.git import stage_uncommitted_to_git
from gpt_engineer.core.files_dict import FilesDict
from pathlib import Path

project_path = Path("/my/project")
files_dict: FilesDict = {"src/main.py": "print('AI generated code')"}
improve_mode = False

# This call will: init repo if missing → find uncommitted files → stage them

stage_uncommitted_to_git(project_path, files_dict, improve_mode)

```

### Integrated CLI Flow

The staging logic is seamlessly integrated into the main execution flow:

```python

# Inside gpt_engineer/applications/cli/main.py

if not no_execution:
    # ... AI generates files_dict ...

    stage_uncommitted_to_git(path, files_dict, improve_mode)
    files.push(files_dict)  # write the AI-generated files

```

### Detecting Uncommitted Changes

The underlying helper that identifies modified files:

```python
def filter_files_with_uncommitted_changes(basepath: Path, files_dict: FilesDict) -> List[Path]:
    # Git returns a newline-separated list of changed paths

    files_with_diff = subprocess.run(
        ["git", "diff", "--name-only"], cwd=basepath, stdout=subprocess.PIPE
    ).stdout.decode().splitlines()
    # Keep only those that appear in the AI file map

    return [f for f in files_dict.keys() if f in files_with_diff]

```

## Summary

- **GPT-Engineer's git staging feature** automatically preserves uncommitted changes by detecting modified files and staging them before AI-generated code is written.
- The workflow executes `git diff --name-only` via `filter_files_with_uncommitted_changes()` to identify files at risk of being overwritten.
- Key implementation files include [`gpt_engineer/core/git.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/git.py) for the staging logic and [`gpt_engineer/applications/cli/main.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/applications/cli/main.py) for CLI integration.
- This safety mechanism ensures **traceability** and **data preservation**, allowing developers to review AI changes through standard Git diff tools.

## Frequently Asked Questions

### How does GPT-Engineer detect which files have uncommitted changes?

GPT-Engineer uses the `filter_files_with_uncommitted_changes()` function in [`gpt_engineer/core/git.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/git.py) to execute `git diff --name-only`. This command returns a list of paths with local modifications, which the function then filters against the AI-generated file dictionary to identify overlapping files that require staging.

### What happens if the project directory is not a Git repository?

If no repository exists and the tool is running in standard generation mode (not *improve* mode), the `init_git_repo()` function automatically runs `git init` to create a new repository. This ensures the git staging feature can track uncommitted AI-generated changes from the very first generation.

### Can I disable the automatic staging of uncommitted changes?

The automatic staging is integrated into the main execution flow in [`gpt_engineer/applications/cli/main.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/applications/cli/main.py) and triggers via `stage_uncommitted_to_git()`. There is no explicit CLI flag mentioned in the source code to disable this behavior, as it serves as a critical safety mechanism to prevent data loss.

### How can I review what changes were staged before the AI generation?

Because the tool stages uncommitted changes using `git add` before writing new files, you can use standard Git commands to inspect the staged state. Run `git diff --cached` to see the previously uncommitted changes that were staged, and `git diff` to see the new AI-generated modifications that exist in the working directory but are not yet staged.