# Git

A SELECT workspace is a folder on disk, and it is a folder you chose: see
[Workspace Folder](/docs/workspace/workspace-folder/). Your SQL files, database
configs and lint rules all live as regular files that you can browse, edit, and
back up however you like. Git is entirely optional, you can use SELECT without
it.

When you work with a team, git becomes useful: keep files in sync across members
and use branches to version your work.

![The source control panel beside a diff: a branch, staged and unstaged changes, and the working copy of a query against its last commit.](/shots/git.light.webp)

## Getting started

SELECT does not set up git for you. It reads the folder you opened, the same way
your editor does:

- **No git**: work locally, no setup needed. You can always add git later.
- **A folder you cloned**: clone the repository yourself, then open that folder.
  Its remote, its branches and its history are already there.
- **A folder you want to version**: run `git init` in it, from your shell or from
  the built-in terminal (`` Ctrl+` ``). The panel picks it up.

Whoever cloned the folder chose its remote, and `git remote` is where that choice
lives. SELECT never rewrites it, and never re-materializes your working tree from
somewhere else.

## Operations

The git panel exposes standard operations:

- **Stage / Unstage**: select which files to include in the next commit, or stage all at once
- **Commit**: create a commit from staged changes
- **Pull**: fetch and merge from origin. Pull with rebase is also available
- **Push**: push your branch to origin. Force push with lease is available when needed

Push and pull need an `origin`; committing does not. A repository with no remote
still gets staging, commits, branches and diffs.
- **Revert**: discard changes to a file or revert all uncommitted changes
- **Branches**: list branches and switch between them

You can also use the **built-in terminal** (`` Ctrl+` ``) for any git operation you prefer to run manually.

## Workspace files

A workspace folder contains:

- `select.config.json`, which is what makes the folder a workspace. Commit it:
  it is how a teammate who clones the repository lands in the right workspace.
  See [Workspace Folder](/docs/workspace/workspace-folder/)
- `.sql` files and their `.metadata.json` sidecars
- `datasource.config.json` files (credentials should use `$VAR` references, not hardcoded values)
- `.env` files (add to `.gitignore` if they contain secrets)
- `.lint` rules

When git is enabled, these workspace files are tracked. Use a `.gitignore` file
to exclude files from version control. See [.gitignore](/docs/workspace-files/gitignore/)
for details.

### Personal settings are not tracked

Some settings are **personal to you**, not team policy, so they live in a
per-user config directory **outside** the workspace and are **never committed**:

- `.theme`: your UI appearance ([Theme file](/docs/personal-files/theme/))
- `.config`: your keybindings and editor snippets
  ([Config file](/docs/personal-files/config/))

This keeps one teammate's color scheme and keybindings from overwriting
everyone else's on pull, and lets your personal settings follow you across every
workspace.

### Workspace settings are synced through the backend

Some settings are team policy but are **not** stored as files. They live on the
workspace and sync through the SELECT backend (like roles and permissions):

- **Execution limits** (`statement_timeout_ms`, `max_result_size_mb`), edited in
  **Settings → Workspace**.

## Sync

Changes to users, roles, permissions, and workspace settings (including execution
limits) are synced through the SELECT backend. These are not stored in git but
kept in sync across team members through the server, whether or not the folder is
a repository.

> [!NOTE]
> Git syncs your **files**. The SELECT backend syncs your **team settings**
> (users, roles, permissions, execution limits).
