---
title: "Version control of TYPO3 projects with Git"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:version-control@main"
source: "Administration/VersionControl/Index.rst"
rendered: "2026-09-18T10:16:27+00:00"
---

# Version control of TYPO3 projects with Git {#version-control-of-typo3-projects-with-git}

Using Git for version control in TYPO3 projects helps ensure consistent
collaboration, transparent change tracking, and safer deployments. It allows
teams to keep a complete history of changes, isolate new features, and revert
to a known state when needed.

Even if you are working alone — as a freelancer or solo developer — Git is
highly valuable. It acts as a time machine for your project, allowing you to:

-   Experiment with confidence by branching and reverting
-   Document and understand your progress over time
-   Sync work between devices or back it up to the cloud
-   Undo mistakes and recover lost files easily
-   Share code with clients, agencies, or collaborators when needed

Whether you are building a quick prototype or maintaining a long-term
client project, version control with Git adds safety, flexibility, and
professionalism to your workflow.

**Table of contents**

-   [Quick start: add a new TYPO3 project to Git](https://docs.typo3.org/permalink/t3coreapi:quick-start-add-a-new-typo3-project-to-git@main)
-   [Prerequisites to use Git](https://docs.typo3.org/permalink/t3coreapi:prerequisites-to-use-git@main)
-   [Git hosting platforms (GitHub, GitLab, ...)](https://docs.typo3.org/permalink/t3coreapi:git-hosting-platforms-github-gitlab@main)
-   [Which TYPO3 directories and files should be kept under version control](https://docs.typo3.org/permalink/t3coreapi:which-typo3-directories-and-files-should-be-kept-under-version-control@main)
-   [Example .gitignore](https://docs.typo3.org/permalink/t3coreapi:example-gitignore@main)
-   [Avoid committing credentials to Git](https://docs.typo3.org/permalink/t3coreapi:avoid-committing-credentials-to-git@main)

## Quick start: add a new TYPO3 project to Git {#quick-start-add-a-new-typo3-project-to-git}

This step-by-step guide explains how to add a new or existing TYPO3 project
to a Git repository. It includes instructions for safely setting up a
[.gitignore](https://docs.typo3.org/permalink/t3coreapi:version-control-gitignore-example@main)
and [avoiding the accidental inclusion of credentials](https://docs.typo3.org/permalink/t3coreapi:version-control-credentials@main) or
environment-specific files.

Make sure, you meet the [prerequisites to use Git](https://docs.typo3.org/permalink/t3coreapi:version-control-prerequisites@main).

Initialize the new Git repository in the root directory of your project:

```bash
git init
```

Depending on your installation method, some files differ. Use the relevant tab
below to identify what to include in version control.

**Composer-based**

1.  Create or review your [.gitignore](https://docs.typo3.org/permalink/t3coreapi:version-control-gitignore-example@main)

    Make sure it includes:

    -   `.env`
    -   `auth.json`
    -   `/public/index.php`
    -   `/public/_assets/`
    -   `/public/fileadmin/`
    -   `/public/typo3/`
    -   `/public/typo3temp/`
    -   `/var/`
    -   `/vendor/`
1.  Double-check for credentials and secrets

    Do not commit passwords or API keys in:

    -   `config/system/settings.php`
    -   `config/system/additional.php`
    -   [`config/sites/my_site/config.yaml`](../DirectoryStructure/SiteFolder.md#file-site-config-sites-my-site-config-yaml)
    -   [`config/sites/my_site/settings.yaml`](../DirectoryStructure/SiteFolder.md#file-site-config-sites-my-site-settings-yaml)

    See [Avoid committing credentials to Git](https://docs.typo3.org/permalink/t3coreapi:version-control-credentials@main).
1.  Add the relevant project files

    **typo3_root$ (Composer mode)**

    ```bash
    git add .gitignore
    git add composer.json composer.lock
    git add config/
    git add packages/
    git add public/.htaccess public/robots.txt
    ```

    See also: [Which TYPO3 directories and files should be kept under version control](https://docs.typo3.org/permalink/t3coreapi:version-control-commit@main).

**Classic mode (non-Composer)**

1.  Create a `.gitignore`

    Use the example in [Example .gitignore](https://docs.typo3.org/permalink/t3coreapi:version-control-gitignore-example@main).

    Typical exclusions:

    -   `typo3temp/`
    -   `typo3_src/`
    -   `fileadmin/`
    -   `.env`
1.  Check for credentials

    Do not commit passwords or API keys in:

    -   `typo3conf/system/settings.php`
    -   `typo3conf/system/additional.php`
    -   [`typo3conf/sites/my_site/config.yaml`](../DirectoryStructure/SiteFolder.md#file-site-config-sites-my-site-config-yaml)
    -   [`typo3conf/sites/my_site/settings.yaml`](../DirectoryStructure/SiteFolder.md#file-site-config-sites-my-site-settings-yaml)

    See [Avoid committing credentials to Git](https://docs.typo3.org/permalink/t3coreapi:version-control-credentials@main).
1.  Add the selected project files

    **typo3_root$ (Classic mode)**

    ```bash
    git add .gitignore
    git add typo3conf/ext/my_sitepackage
    git add typo3conf/ext/my_custom_extension
    git add .htaccess
    git add robots.txt
    ```

    See also: [Which TYPO3 directories and files should be kept under version control](https://docs.typo3.org/permalink/t3coreapi:version-control-commit@main).

The following steps apply to **all TYPO3 projects**, no matter the installation
type:

Make your initial commit, this adds the files to your local Git:

```bash
git commit -m "Initial commit: My TYPO3 project"
```

Use Git status to see if there are untracked files that are not added to the Git:

```bash
git status
```

If you are using a [Git hosting platforms (GitHub, GitLab, ...)](https://docs.typo3.org/permalink/t3coreapi:version-control-platforms@main)
you can create a remote repository on that plattform. Then add the Git SSH remote
and push your changes to that repository.

```bash
git remote add origin git@example.com:user/project.git
git push -u origin main
```

## Prerequisites to use Git {#prerequisites-to-use-git}

First test if Git is installed on your computer:

**Linux / macOS / WSL**

Open your terminal and run:

```bash
git --version
```

If you see a message like `command not found`, you need to install Git.

If Git is missing, follow the installation guide for your system:

macOS: Install via Homebrew: `brew install git`

Linux: Use your package manager, for example `sudo apt install git`

**Windows (PowerShell or CMD)**

Open PowerShell or Command Prompt and run:

```powershell
git --version
```

If you get an error like `'git' is not recognized`, you need to
[install Git](https://git-scm.com/downloads/win).

If you want to use Git across multiple computers (e.g., your laptop and a web
server), or collaborate with a team, you should choose a
[Git hosting platform (GitHub, GitLab, ...)](https://docs.typo3.org/permalink/t3coreapi:version-control-platforms@main)
and create an account there.

To connect to the remote repository via **SSH**, you need to authenticate with
your hosting provider — typically by creating and registering an **SSH key**.

See for example:

-   [Generating a new SSH key and adding it to the ssh-agent](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
    (GitHub documentation)

You can also choose to use Git through an IDE or graphical client. Popular
options include:

-   **PhpStorm** – Full Git integration with staging, history, merge tools, and more
-   **Visual Studio Code** – Git support with useful extensions
-   **GitKraken**, **Tower**, **GitHub Desktop** – Standalone Git GUIs

> [!NOTE]
> This guide focuses on the Git command line workflow. GUI tools and IDE
> integrations may look different, but the underlying Git actions are the same.

To learn more about Git and how it works, see the official Git documentation:

-   [Git - The Simple Guide](https://rogerdudler.github.io/git-guide/)
-   [Pro Git Book (free)](https://git-scm.com/book/en/v2)
-   [GitHub Docs: Git Basics](https://docs.github.com/en/get-started/using-git)

## Git hosting platforms (GitHub, GitLab, ...) {#git-hosting-platforms-github-gitlab}

A **Git hosting platform** is a service that stores your Git repositories
remotely and allows collaboration with others. It also provides tools such
as web interfaces, access control, issue tracking, continuous integration
(CI), and backups.

Using a hosting platform is recommended even for solo projects, as it makes
it easier to:

-   Share your code with others (team members, clients, ...)
-   Back up your work to the cloud
-   Track issues, bugs, and tasks
-   Set up CI/CD pipelines for automated testing and deployment

All Git hosting platforms are supported. The following are commonly used:

-   [GitHub](https://github.com/) – Popular for open-source and private projects
-   [GitLab](https://gitlab.com/) – Offers CI/CD and self-hosting options
-   [Bitbucket](https://bitbucket.org/) – Integrates with Atlassian tools
-   [Gitea](https://gitea.io/) – Lightweight, open-source, self-hosted platform
-   [Codeberg](https://codeberg.org/) – Free and open-source Git hosting
-   [Gerrit](https://www.gerritcodereview.com/) – Git server with built-in
    code review workflow; used by the TYPO3 Core team

## Which TYPO3 directories and files should be kept under version control {#which-typo3-directories-and-files-should-be-kept-under-version-control}

### Directories and files to always commit {#directories-and-files-to-always-commit}

**Composer-based**

-   `.gitignore`
-   `composer.json`, `composer.lock`
-   `config/sites` – [Site handling](https://docs.typo3.org/permalink/t3coreapi:sitehandling@main)
-   `config/system/settings.php` – [System configuration files](https://docs.typo3.org/permalink/t3coreapi:configuration-files@main)
-   `packages/` – Custom extensions and site packages

**Classic mode (non-Composer)**

-   `.gitignore`
-   `typo3conf/sites` – [Site handling](https://docs.typo3.org/permalink/t3coreapi:sitehandling@main)
-   `typo3conf/system/settings.php` – [System configuration files](https://docs.typo3.org/permalink/t3coreapi:configuration-files@main)
-   `typo3conf/ext/my_sitepackage` – Custom site packages
-   `typo3conf/ext/my_custom_extension` – Custom extensions

### Optional to commit {#optional-to-commit}

Depending on project needs, you may include:

-   Docker and CI/CD config – `.gitlab-ci.yml`, `docker-compose.yml`, ...
-   Files needed for testing like `.php-cs-fixer.dist.php`,
    `phpstan.neon`, `runTests.sh` etc.
-   Build folders containing sources for asset building like scss sources,
    typescript sources, etc. never commit `node_modules`, these files are
    managed by gulp or vite.
-   Files used during local development like `.editorconfig`, `Makefile`
    and `ddev/config.yaml`

Additional files may be versioned depending on your project requirements and
installation method:

**Composer-based**

-   `config/system/additional.php` – Depending on how this file
    should be managed to override server settings.
-   `public/.htaccess`
-   `public/robots.txt`

**Classic mode (non-Composer)**

-   `typo3conf/system/additional.php` – Depending on how this file
    should be managed to override server settings.
-   `.htaccess`
-   `robots.txt`

Information on which versions exactly have been installed - or:

-   `index.php`
-   `typo3conf/ext/` – All installed extensions (So the project
    can be fully restored from the Git repository without needing
    external packages or configuration.)
-   `typo3conf/l10n/` – If you also want to keep automatic
    localizations under version control
-   `typo3conf/PackageStates.php` – To determine which of the
    loaded extensions are installed
-   `typo3/sysext/` – The TYPO3 Core (So a project can
    be rebuild in from the Git alone)
-   `typo3/install.php`

### Directories and files to never commit {#directories-and-files-to-never-commit}

**Composer-based**

-   `public/fileadmin/` – User-uploaded files, these are managed by
    [File abstraction layer (FAL)](https://docs.typo3.org/permalink/t3coreapi:fal-introduction@main)
-   `public/typo3temp/` – Temporary cache files
-   `var/` – Cache, sessions, and lock files, managed by TYPO3
-   `vendor/` – Managed by Composer
-   `.env` – Environment-specific variables and secrets

**Classic mode (non-Composer)**

-   `fileadmin/` – User-uploaded files, these are managed by
    [File abstraction layer (FAL)](https://docs.typo3.org/permalink/t3coreapi:fal-introduction@main)
-   `typo3temp/` – Temporary cache files, sessions, and lock files, managed by TYPO3

## Example `.gitignore` {#example-gitignore}

A `.gitignore` file tells Git which files and folders to ignore when committing
to the repository. This helps prevent unnecessary or sensitive files (like cache,
uploads, or environment configs) from being tracked.

The `.gitignore` file should be placed in the root directory of your TYPO3
project (usually alongside `composer.json` or `typo3conf/`). Its contents
can vary depending on whether you use a Composer-based setup or a
classic (non-Composer) structure.

For more on how `.gitignore` works, see the official Git documentation:
[https://git-scm.com/docs/gitignore](https://git-scm.com/docs/gitignore)

**Composer-based**

For Composer-based projects, you can use the `.gitignore` from the official
GitLab TYPO3 Project Template as a solid starting point.

**project_root/.gitignore**

```plaintext
# TYPO3 system folders
/var/
/vendor/
/public/typo3temp/
/public/uploads/
/public/fileadmin/

# Environment and secrets
.env

# Node.js build tools
/node_modules/
/dist/

# IDE and editor settings
.idea/
.vscode/
*.swp

# OS metadata
.DS_Store
Thumbs.db

```

> [!NOTE]
> **See also**
>
> The official GitLab TYPO3 Project Template includes a preconfigured
> `.gitignore` file that covers most Composer-based setups. You can view
> it here:
>
> [https://gitlab.com/gitlab-org/project-templates/typo3-distribution/-/blob/main/.gitignore](https://gitlab.com/gitlab-org/project-templates/typo3-distribution/-/blob/main/.gitignore)

**Classic mode (non-Composer)**

**project_root/.gitignore**

```plaintext
# TYPO3 Core and source directory
/typo3_src/

# Temporary files and caches
/typo3temp/
/fileadmin/

# IDE/editor folders
/.idea/
/.vscode/
*.swp

# OS-specific files
.DS_Store
Thumbs.db
ehthumbs.db
Desktop.ini

# Node.js or frontend build artifacts (if used)
/node_modules/
/dist/
/build/

# Environment
.env

```

> [!NOTE]
> Some development tools such as [DDEV](https://ddev.readthedocs.io/)
> may automatically create `.gitignore` files inside specific
> subdirectories (e.g., `public/`, `.ddev/`, or `vendor/`). These are
> usually intended to prevent tool-specific or temporary files from
> being committed. You can customize or remove them if needed, but
> be aware of their purpose before doing so.

## Avoid committing credentials to Git {#avoid-committing-credentials-to-git}

> [!WARNING]
> Be very careful not to commit sensitive information such as passwords,
> API keys, access tokens, or database credentials to your Git repository.

Examples of files that often contain secrets:

-   `.env` – Environment-specific variables
-   `auth.json` – Composer credentials
-   `config/system/settings.php` – TYPO3 system-level configuration;
    may include database credentials, encryption key, install tool password,
    and global extension settings.
-   `config/system/additional.php` TYPO3 system-level configuration
    overrides
-   [`config/sites/some_site/config.yaml`](../DirectoryStructure/SiteFolder.md#file-site-config-sites-my-site-config-yaml) Solr credentials, credentials
    from other third party extension not using settings yet.
-   [`config/sites/some_site/settings.yaml`](../DirectoryStructure/SiteFolder.md#file-site-config-sites-my-site-settings-yaml) – Site-level configuration
    for individual extensions (for example CRM, analytics, etc.); can
    contain site-specific tokens or secrets.

### Best practices to avoid accidentally committing credentials {#best-practices-to-avoid-accidentally-committing-credentials}

-   Add secret files to your `.gitignore` before running `git add`
-   Use environment variables instead of hardcoded credentials
-   Split config files: version the structure (e.g., `settings.php`) but load secrets
    from untracked overrides (for example `credentials.php`)
-   Use `.env.example` to document required environment variables, and keep the real
    `.env` excluded
-   You can also use an extension like [`helhum/dotenv-connector`](https://packagist.org/packages/helhum/dotenv-connector) to
    manage secrets via environment variables.

### Credentials in the settings.php or additional.php {#credentials-in-the-settings-php-or-additional-php}

For example, you could keep all credentials in a file called
`config/system/credentials.php` and include this file into your
`config/system/additional.php` if present:

**project_root/config/system/additional.php**

```php
<?php

defined('TYPO3') || die();

// Other settings

$file = realpath(__DIR__) . '/credentials.php';
if (is_file($file)) {
  include_once($file);
  $GLOBALS['TYPO3_CONF_VARS'] = array_replace_recursive($GLOBALS['TYPO3_CONF_VARS'], $customChanges);
}

```

**config/system/credentials.php (Add to `.gitignore`, Do not commit to Git!!!)**

```php
<?php

defined('TYPO3') or die();
$customChanges = [
  'BE' => [
    'installToolPassword' => 'secret',
  ],
  'DB' => [
    'Connections' => [
      'Default' => [
        'password' => 'secret',
      ],
    ],
  ],
  'EXTENSIONS' => [
    't3monitoring_client' => [
      'secret' => 'secret',
    ],
  ],
  'SYS' => [
    'encryptionKey' => 'also secret',
  ],
];

```

### Credentials in the site configuration or settings {#credentials-in-the-site-configuration-or-settings}

It is also possible that the [site configuration](https://docs.typo3.org/permalink/t3coreapi:sitehandling@main)
[Site setting](https://docs.typo3.org/permalink/t3coreapi:sitehandling-settings@main)
files contain credentials (for example Solr credentials). You can use
environment variables directly in YAML files:

**project_root/config/sites/example/config.yaml (excerpt)**

```yaml
base: 'https://www.example.org/'

# ...

solr_host_read: '%env("SOLR_USER")%'
solr_password_read: '%env("SOLR_PASSWORD")%'

```

**project_root/.env  (Add to `.gitignore`, Do not commit to Git!!!)**

```bash
SOLR_USER=my-solr-user
SOLR_PASSWORD=secret
```

### If you accidentally committed credentials {#if-you-accidentally-committed-credentials}

1.  **Change them immediately** (reset API tokens or database passwords)
1.  Remove the file from Git history:

    ```bash
    git rm --cached .env
    echo ".env" >> .gitignore
    git commit -m "Remove .env and ignore it"
    ```
1.  If pushed to a public repo, consider using tools like
    [BFG Repo-Cleaner](https://rtyley.github.io/bfg-repo-cleaner/) or
    [git filter-repo](https://github.com/newren/git-filter-repo) to fully remove
    secrets from history.

> [!WARNING]
> Secrets committed to a public repository should be considered compromised,
> even if deleted afterward. Rotate them as soon as possible.
