# Asset Preview Source: https://docs.diversion.dev/advanced/asset_preview Preview your images, 3D models, and code directly in Diversion Click any supported file in Diversion to preview it instantly—no need to open external applications. ## 3D Models Preview and inspect 3D models with an interactive viewer. Rotate the camera around your model to examine it from any angle. **Supported formats:** * .gltf, .glb * .fbx * .obj **File size limit:** 25 MB ## Images **Supported formats:** .jpg, .jpeg, .png, .gif, .webp, .tif, .tiff, .bmp, .ico, .svg **File size limit:** 2 MB ## Unreal Engine Assets Preview `.uasset` files by extracting their embedded thumbnails. **File size limit:** 2 MB ## Code and Shaders Preview text-based files with syntax highlighting. **Supported formats:** * .uproject, .uplugin * .usf, .ush (Unreal Shader Format) * .glsl, .hlsl * .ispc, .isph **File size limit:** 2 MB # Obliterate Source: https://docs.diversion.dev/advanced/obliterate Permanently delete file blobs from a repository to reclaim storage and remove sensitive content. `obliterate` permanently deletes the underlying blob storage for every version of files that match a path pattern, across all branches and commits. Unlike `dv rm`, which records a deletion in history but keeps the old versions reachable, obliterate removes the bytes themselves and rewrites references in history so the blobs cannot be retrieved. Use it when: * A very large file (game build, dataset, mistakenly committed binary) is consuming storage and is no longer needed in history. * A secret, credential, or other sensitive file was committed and must be expunged. Obliterate is **destructive and irreversible**. There is no undo. Always run a preview first and read the plan carefully before executing. ## Requirements * You must be a [**repository admin**](/basic/access-levels#organization-level-access). * Obliterate is not supported on git-synced repositories. ## How It Works 1. You supply one or more path globs (e.g. `'/assets/*.psd'`). 2. The server resolves every (path, version) match across the repo's history. 3. Each match is classified as either **deletable** (the underlying blob is only reachable through paths covered by your globs) or **not deleted** (the same blob content is reachable through some other path that you did not include). 4. On execute, the deletion runs asynchronously. You get back a `job_id` you can poll for progress. The "not deleted" partition matters because Diversion stores file contents by hash -- the same bytes shared across paths are stored once. If the same content also lives at another path you did not include, the storage stays. The preview tells you exactly which other paths are blocking deletion -- you can widen your glob set and re-run. ## Glob Syntax Patterns are **anchored to the repo root**. Always quote them so your shell does not expand the wildcards. | Pattern | Matches | | ------------------- | ----------------------------------------------------- | | `/assets/*.psd` | `.psd` files directly under `/assets/`, root-anchored | | `/assets/.../*.psd` | `.psd` files anywhere under `/assets/` (recursive) | | `/.../secrets.env` | Any file named `secrets.env` anywhere in the repo | | `/build/large.bin` | One specific file | The preview returns a warning if a pattern is broadly unanchored (e.g. matches across the entire repo, or only at the root when you probably meant recursive). Redundant patterns -- ones already covered by another pattern in the same call -- are also flagged. ## Preview Always start with a preview. Nothing changes on the server. ```bash theme={null} dv obliterate preview '/assets/old_textures/*.psd' ``` The preview returns: * **Headline counts**: deletable versions / files, not-deleted versions / files, and any matches in shared (grouped) storage that obliterate cannot reach. * **Reclaim estimate**: total bytes that will be freed, deduplicated by content hash (the same blob at N paths counts once). * **Deletable paths**: per-path summary -- versions and total bytes -- sorted by largest reclaim first. * **Not deleted paths**: per-path summary plus `unblock_paths`: the other paths in the repo that still hold the same content. Add them to your glob set if you want the blob removed. * **Per-glob summary**: for each input glob, the files / versions / total bytes it matched on its own (before cross-glob deduplication). Only surfaced in JSON output, and in the human CLI's per-glob block when you pass more than one glob. * **Warnings**: surfaced when a glob is broadly unanchored or redundant. Pass multiple globs in one call to plan their combined obliteration: ```bash theme={null} dv obliterate preview '/assets/*.psd' '/builds/.../*.pak' ``` ### Human vs JSON output The human CLI shows the **top 20** deletable / not-deleted paths sorted by bytes desc, with a trailing line like `... and 980 more (use --json for the full list)` when the result was capped. The server returns the full byte-desc-sorted lists; only the display is capped. For the full machine-readable plan, pass `--json`: ```bash theme={null} dv obliterate preview --json '/assets/old_textures/*.psd' | jq '.deletable_paths | length' ``` `--json` emits a single JSON document on stdout with banners and warnings suppressed (warnings move into a `warning` string field on the document). ## Execute Once the preview matches what you intend to delete: ```bash theme={null} dv obliterate execute '/assets/old_textures/*.psd' ``` You will be prompted to type the repository name or ID to confirm. Pass `--yes` to skip the prompt (for scripting): ```bash theme={null} dv obliterate execute --yes '/assets/old_textures/*.psd' ``` Execute returns the same plan as preview plus a `job_id` and starts polling the job until it reaches a terminal state. The polling cap is **18 seconds** (status endpoint every 3 seconds); for shorter jobs you will see the run complete inline, and for longer jobs the CLI prints the `job_id` and exits, leaving you to follow up with `dv obliterate status`. Flags: * `--nowait` -- enqueue and exit immediately without polling. The CLI prints the `job_id` and you check progress yourself. * `--json` -- emit a single JSON document instead of the human banner. **Requires `--yes`** -- an interactive confirmation prompt would corrupt the JSON stream. Exit codes: | Code | Meaning | | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `0` | Polling reached a terminal state and the job completed without failures. | | `2` | Polling reached a terminal state and the job had one or more failed deletions. | | `101` | The 18s polling cap elapsed with the job still in progress. Distinguishes "gave up waiting" from "done" so scripts can branch on it; follow up with `dv obliterate status`. | `execute` returns as soon as the job is enqueued -- the actual deletion runs in the background, which is why you poll the status endpoint for progress. Concurrent commits to the same files during an obliterate run are an edge case. Avoid running obliterate while other users are actively committing to the targeted paths. ## Tracking a Job Each execute returns a `job_id` (e.g. `dv.obliterate.593d2b8a8dbf47559bcc73c8bcf54f41`). Check progress with: ```bash theme={null} dv obliterate status ``` The response carries an overall `status` plus per-row counts: ``` Obliterate job dv.obliterate.593d2b8a8dbf47559bcc73c8bcf54f41 Status: in_progress Counts: pending=18200 done=11800 failed=0 Started: 2026-06-18T08:39:01.147736+00:00 ``` ### Status values | Status | Meaning | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `queued` | The worker has not started yet. | | `in_progress` | Worker is running. `pending` is dropping as batches complete; `done` and `failed` are growing. | | `succeeded` | Worker finished and all rows are `done`. | | `failed` | Worker finished but one or more rows are `failed`. The response includes the first 20 errors with the failing SHA and a truncated error message. | | `archived` | The job has aged out of the queue but its counts are still inspectable. | A 404 from the status endpoint means there is no obliterate job with that id in this repo. ## What Gets Touched * **History**: the obliterated file versions are removed from the repo's change log. * **Open merges**: any open merge whose conflict referenced an obliterated file is closed, since finalizing it would otherwise produce a commit with a dead reference. ## Limits * The preview/execute resolution call has a server-side time budget (60 seconds). If your glob matches too many files, the call is rejected with an error asking you to narrow the pattern. Split the work into more specific glob sets and run them sequentially. * Files stored in **shared (grouped) storage** -- small files packed together for efficiency -- cannot be individually obliterated. The preview reports them as a separate skipped count so you know how many were excluded. ## Related * [`dv obliterate`](/cmd-ref/obliterate) -- CLI reference * [Storage](/concepts/storage) -- how blobs are stored and shared * [Going back in time](/basic/going-back-in-time) -- non-destructive history navigation # Pre-Commit Hooks Source: https://docs.diversion.dev/advanced/pre-commit-hooks Run custom scripts before commits to validate changes, enforce standards, and automate checks. Pre-commit hooks let you run custom scripts that automatically validate your changes before each commit. If the script exits with a non-zero code, the commit is blocked - giving you a chance to fix issues before they reach the repository. ## Overview Hooks are executable scripts stored in a `.dvhooks/` directory at the root of your repository. Because they live inside the repository, they sync to all collaborators just like any other file. **Common use cases:** * Lint and syntax checks * Code formatting enforcement * Preventing commits of large or forbidden files * Custom project-specific validation **How it works:** * Before a commit, Diversion runs the `.dvhooks/pre-commit` script with the committed files as command-line arguments * Exit code `0` means the hook passed - the commit proceeds * Any non-zero exit code means the hook failed - the commit is blocked * The hook's stdout/stderr output is displayed to the user Pre-commit hooks are client-side only. They run when committing via the CLI or Desktop app. Commits made directly through the WebApp or API bypass hooks. ## Creating a Pre-Commit Hook Create a `.dvhooks` directory at the root of your repository: ```bash theme={null} mkdir .dvhooks ``` Create a `pre-commit` script inside `.dvhooks/`. The script can be written in any language, as long as it's executable. ```bash Mac/Linux (.dvhooks/pre-commit) theme={null} #!/bin/sh echo "Running pre-commit checks..." # Committed files are passed as arguments ($@) for file in "$@"; do if echo "$file" | grep -q '\.js$'; then if grep -q "console.log" "$file"; then echo "Error: Remove console.log from $file before committing." exit 1 fi fi done echo "All checks passed." exit 0 ``` ```bat Windows (.dvhooks/pre-commit.bat) theme={null} @echo off echo Running pre-commit checks... REM Committed files are passed as arguments (%*) for %%f in (%*) do ( echo Checking %%f ) echo All checks passed. exit /b 0 ``` ```powershell Windows (.dvhooks/pre-commit.ps1) theme={null} Write-Host "Running pre-commit checks..." # Committed files are passed as arguments ($args) foreach ($file in $args) { if ($file -match '\.js$') { if (Select-String -Path $file -Pattern "console.log" -Quiet) { Write-Host "Error: Remove console.log from $file before committing." exit 1 } } } Write-Host "All checks passed." exit 0 ``` On Mac/Linux, make the script executable: ```bash theme={null} chmod +x .dvhooks/pre-commit ``` Commit the `.dvhooks/` directory to share the hook with your collaborators: ```bash theme={null} dv commit .dvhooks -m "Add pre-commit hook" ``` Once committed, every collaborator on the branch will have the hook and it will run automatically before their commits. ## File Arguments The files being committed are passed to your hook script as **command-line arguments**. Your script can access them via `$@` (Mac/Linux) or `%*` (Windows). When the file list is too large for a single command invocation, Diversion automatically splits it into chunks and runs the hook multiple times in parallel. If any invocation fails, the commit is blocked. **Example - check committed files for large binaries:** ```bash Mac/Linux theme={null} #!/bin/sh # Reject files larger than 100MB MAX_SIZE=$((100 * 1024 * 1024)) for file in "$@"; do if [ -f "$file" ]; then size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null) if [ "$size" -gt "$MAX_SIZE" ]; then echo "Error: $file is too large ($(($size / 1024 / 1024))MB, limit 100MB)." exit 1 fi fi done exit 0 ``` ```bat Windows theme={null} @echo off REM Check committed files for %%f in (%*) do ( echo Checking: %%f ) exit /b 0 ``` ## Environment Variables Diversion also passes context to your hook script via environment variables: | Variable | Description | | ------------------- | ----------------------------------- | | `DV_REPO_ROOT` | Absolute path to the workspace root | | `DV_COMMIT_MESSAGE` | The commit message | | `DV_BRANCH` | Current branch name | **Example - require a ticket number in the commit message:** ```bash Mac/Linux theme={null} #!/bin/sh # Require commit messages to contain a ticket reference (e.g., PROJ-123) if ! echo "$DV_COMMIT_MESSAGE" | grep -qE '[A-Z]+-[0-9]+'; then echo "Error: Commit message must include a ticket number (e.g., PROJ-123)." echo "Your message: $DV_COMMIT_MESSAGE" exit 1 fi exit 0 ``` ```bat Windows theme={null} @echo off REM Require commit messages to contain a ticket reference (e.g., PROJ-123) echo %DV_COMMIT_MESSAGE% | findstr /R "[A-Z]*-[0-9]*" >nul 2>&1 if %errorlevel% neq 0 ( echo Error: Commit message must include a ticket number (e.g., PROJ-123). echo Your message: %DV_COMMIT_MESSAGE% exit /b 1 ) exit /b 0 ``` ## Skipping Hooks Use the `--no-verify` flag to bypass pre-commit hooks for a single commit: ```bash theme={null} dv commit -a -m "quick fix" --no-verify ``` This is useful for urgent fixes when you need to commit without running validation. ## Behavior Details * **Timeout**: Hooks have a 60-second timeout. If the hook doesn't finish in time, the commit is blocked with a timeout message. * **Working directory**: The hook runs with the workspace root as its working directory. * **Output limit**: Hook output is capped at 1 MB. Output beyond that limit is truncated. * **Output display**: Hook output is always shown to the user, whether the hook passes or fails. * **Platform detection**: * **Mac/Linux**: Diversion looks for an executable file named `pre-commit` in `.dvhooks/`. If the file exists but isn't executable, you'll see an error prompting you to run `chmod +x`. * **Windows**: Diversion looks for `pre-commit.bat`, `pre-commit.cmd`, or `pre-commit.ps1` in `.dvhooks/` (checked in that order). # Selective Sync Source: https://docs.diversion.dev/advanced/selective-sync Only sync the files you need This one is for artists who don't want code, or for developers who aren't artistically inclined. ## What is Selective Sync? Selective Sync is a feature that allows you to choose which folders you want to sync locally. This will allow you to only have the files you need to work on, saving space on your computer. ## How to use Selective Sync Open the workspace's **... (more options) menu** next to the workspace selector ("THIS WORKSPACE") and choose Selective sync. From your local folder, run `dv view`, or click the View Repo button in the UI. Open repo Click the **... (more options) button** next to the workspace selector to open the "THIS WORKSPACE" menu, then choose **Selective sync** ("Choose which folders sync to this machine"). Open settings Selective Sync page ### Unsyncing a folder Let's take a look at `folder 1`. In the UI: Selective Sync ui full And locally: Selective Sync local full Let's unsync `folder 1.2`. Unselect the folder in the UI and hit Save. Selective Sync removing folder 1.2 Locally, the folder disappears automatically. Selective Sync removed folder 1.2 local It's also missing in the UI. Selective Sync removed folder 1.2 ui ### What about my uncommitted changes? Have no fear! If you have any uncommitted changes, you won't be able to change your selective sync settings. Let's see what that looks like. Inside `folder 1.1`, let's make changes to `text document 1.1.1.txt` and save. Selective Sync editing 1.1.1.txt Back in the workspace settings, let's try to unsync `folder 1.1`. Selective Sync fail to unsync 1.1 We got an error message! We'll have to commit or discard our changes before unsyncing the folder. Selective Sync fail to unsync 1.1 error ## Loose files Right now, we can only selectively sync folders. This means that files are handled differently, if they're not in a folder. Let's take a look at `folder 2`. Selective Sync folder with loose file Notice that it has a file directly under it - `text document 2.1.txt`. In this situation, unsyncing `folder 2.1` will also unsync `text document 2.1.txt`! That's despite the file being a sibling of the folder and not a child of it. This is because `folder 2` will be marked as partially synced, so only explicitly synced folders (in this case, `folder 2.2`) will be kept. This still supports the main use-case of this feature: 1. Artists who don't want to sync code locally can ignore the root `Source` folder, or equivalent. 2. Developers who don't want to sync heavy assets can ignore the root `Content` folder, or equivalent. ## Per workspace The selective sync feature works on a per-workspace basis. This means that you can have different selective sync settings for different workspaces. This is useful if you have multiple projects in the same repo, or if you're working on different parts of the same project. # Agent Quickstart Source: https://docs.diversion.dev/agent-quickstart Set up Diversion as the version control for your coding agent This page is written for **AI coding agents** (Claude Code, Cursor, Codex, or any tool that runs shell commands). It explains how to use Diversion as the version control for a repository with the `dv` CLI. Diversion is a cloud-native version control system — an alternative to Git and Perforce, built for large binary files with automatic sync. **Use Diversion when** your repo has large or binary files (game assets, models, datasets, build artifacts) that Git and Git LFS handle poorly, when you want commits to sync to teammates automatically (no push or pull), or when you're running multiple agents that each need an isolated copy of the repo. Setting up Diversion yourself with the desktop app? Start with the [Quickstart](/quickstart) instead. **Pointing an agent here?** The full machine-readable docs index lives at [`docs.diversion.dev/llms.txt`](https://docs.diversion.dev/llms.txt) (and [`/llms-full.txt`](https://docs.diversion.dev/llms-full.txt) for the complete text). Give your agent that URL together with this page. ## How Diversion differs from Git Diversion is not Git. Internalize these rules before running commands: * **Auto-sync — no `push` or `pull`.** Every commit replicates to the cloud and to teammates automatically. There is no `dv push` or `dv pull`. * **No staging area — no `git add`.** Diversion tracks every change in the working tree continuously. You commit files directly. * **One workspace = one working directory.** A *workspace* is a local copy of a single branch. To work on two branches at once, use two workspaces — see [Run agents in parallel](#run-agents-in-parallel). * **Always pass a subcommand.** Run `dv status`, `dv commit`, and so on. Running bare `dv` opens an interactive shell; avoid it in non-interactive or agent contexts. ## Install ```bash theme={null} curl -sL https://get.diversion.dev/unix | bash ; export PATH="$HOME/.diversion/bin:$PATH" ``` Add the `export PATH` line to your shell profile (`~/.bashrc` or `~/.zshrc`) to make it permanent. Download and run the [Windows installer](https://get.diversion.dev/win). Confirm the install: ```bash theme={null} dv version ``` ## Authenticate ```bash theme={null} dv login ``` This opens a browser to sign in. **A human runs this once** in the environment where the agent operates; the agent reuses the session afterward. **Headless or CI agents (no browser):** generate an API token (in the web app: avatar → **Integrations** → **Generate a new API token**) and authenticate non-interactively with `dv authenticate ` — no browser needed. The [CI/CD guide](/ci-cd) has the full setup. The same token also works as a `Bearer` token against the [REST API](/api-reference/introduction). API access requires the [Pro plan or above](https://www.diversion.dev/pricing). ## Core commands ```bash theme={null} # Start tracking a new project in the current directory dv init # Get a working copy of an existing repository dv clone [path] # See what changed in the working tree dv status # Commit all current changes (replicates automatically — no push needed) dv commit -a -m "your message" # Create a new branch and switch to it dv branch -c # Switch to an existing branch, commit, or tag dv checkout # Merge another branch into the current one dv merge # View history dv log ``` Full reference: [CLI Reference](/cmd-ref/about-cmd). ## Git → Diversion command map | Git | Diversion (`dv`) | | ---------------------------------- | ------------------------------------------------------- | | `git clone ` | `dv clone [path]` | | `git init` | `dv init` | | `git add ` | *(not needed — changes are tracked automatically)* | | `git status` | `dv status` | | `git commit -am "msg"` | `dv commit -a -m "msg"` | | `git push` / `git pull` | *(not needed — auto-sync)* | | `git checkout -b ` | `dv branch -c ` | | `git switch ` | `dv checkout ` | | `git merge ` | `dv merge ` | | `git log` | `dv log` | | `git worktree add ` | `dv clone --new-workspace --ref ` | ## Run agents in parallel To run agents in isolated workspaces — the Diversion equivalent of `git worktree` — clone the repository into a separate directory with its own workspace, **each on its own branch**. The workspaces are isolated on disk, and a dedicated branch per agent keeps their commits from interfering. (Agents that share a branch still auto-sync to it and can conflict — give each one its own branch.) ```bash theme={null} # Create an isolated workspace on a dedicated branch dv clone /tmp/-agent-1 --new-workspace --ref ``` The agent works inside `/tmp/-agent-1` and commits as usual — changes auto-sync to that branch. When the work is done, tear the workspace down: ```bash theme={null} dv workspace # list workspaces to find the one to remove (id starts with dv.ws.) dv unregister -f # run from inside /tmp/-agent-1 — detaches the local copy dv workspace delete -f rm -rf /tmp/-agent-1 ``` Today this clones the full repository, including binary assets. For asset-heavy repositories (e.g. Unreal projects) that is a large download per workspace. Code-only ("selective sync") cloning from the CLI is on the roadmap. ## Next steps The Diversion plugin for Claude Code links every commit to the conversation that produced it, so you can ask later *why* any change was made. Optional. Every `dv` command, flag, and argument. Automate Diversion over REST. Diversion's built-in AI coding agent. # Get billing information Source: https://docs.diversion.dev/api-reference/account/get-billing-information get /account/billing Get billing information for the authenticated user # Get client configuration Source: https://docs.diversion.dev/api-reference/authentication/get-client-configuration get /auth/config Get configuration for the authenticated client including optional cache and update URLs # Get enterprise login URL Source: https://docs.diversion.dev/api-reference/authentication/get-enterprise-login-url get /auth/enterprise Get the enterprise login URL for a given organization # Test token Source: https://docs.diversion.dev/api-reference/authentication/test-token get /auth/test Test token validity and repo write access # Accept a repository invitation Source: https://docs.diversion.dev/api-reference/collaborators/accept-a-repository-invitation post /repos/{repo_id}/invites/{invite_id}/accept Accepts a repository collaboration invitation, granting the user access with the specified mode (READ, WRITE, ADMIN). **Behavior:** - If the repository belongs to an organization, the user is automatically added as an organization member if not already - Restores any previously deleted workspaces for this user **Returns:** - `409 Conflict` if already a collaborator - `204 No Content` on success # Invite collaborator Source: https://docs.diversion.dev/api-reference/collaborators/invite-collaborator put /repos/{repo_id}/invites Invite a collaborator to a repository # List collaborators Source: https://docs.diversion.dev/api-reference/collaborators/list-collaborators get /repos/{repo_id}/collaborators Get all collaborators and pending invites for repo # Reject a repository invitation Source: https://docs.diversion.dev/api-reference/collaborators/reject-a-repository-invitation post /repos/{repo_id}/invites/{invite_id}/reject Rejects a repository collaboration invitation without granting access. **Behavior:** The invitation is marked as redeemed with REJECTED status. **Validation:** - Invitation is addressed to the user's email - Invitation hasn't been redeemed - Invitation hasn't expired **Returns:** - `409 Conflict` if already processed - `204 No Content` on success # Revoke collaborator access Source: https://docs.diversion.dev/api-reference/collaborators/revoke-collaborator-access delete /repos/{repo_id}/collaborators/{user_id} Revoke a user's access level to the repo # Update collaborator access Source: https://docs.diversion.dev/api-reference/collaborators/update-collaborator-access patch /repos/{repo_id}/collaborators/{user_id} Change a user's access level to the repo # Developer Guide Source: https://docs.diversion.dev/api-reference/developer-guide Getting started with Diversion API ## Overview This section describes how to use the Diversion API to build custom integrations and clients. ## Authentication All API endpoints, unless stated otherwise, are authenticated using Bearer tokens. ``` Authorization: Bearer ``` ## Base URL All API endpoints are relative to the base URL `https://api.diversion.dev/v0`. ## Making Your First Request Once you have your token, you can test that it works by making a request to the `/auth/test` endpoint: ```python Python theme={null} import requests response = requests.get( "https://api.diversion.dev/v0/auth/test", headers={"Authorization": "Bearer "} ) print(response.status_code) # Should print 204 ``` ```typescript TypeScript theme={null} const response = await fetch("https://api.diversion.dev/v0/auth/test", { headers: { "Authorization": "Bearer " } }); console.log(response.status); // Should print 204 ``` ```bash cURL theme={null} curl -X GET "https://api.diversion.dev/v0/auth/test" \ -H "Authorization: Bearer " ``` ```go Go theme={null} package main import ( "fmt" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.diversion.dev/v0/auth/test", nil) req.Header.Set("Authorization", "Bearer ") client := &http.Client{} resp, _ := client.Do(req) fmt.Println(resp.StatusCode) // Should print 204 } ``` ```csharp C# theme={null} using System; using System.Net.Http; using System.Threading.Tasks; var client = new HttpClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer "); var response = await client.GetAsync("https://api.diversion.dev/v0/auth/test"); Console.WriteLine((int)response.StatusCode); // Should print 204 ``` ## Real-World Example: Create a New Repo See the endpoint's full documentation [here](/api-reference/repository-management/create-a-repo). ```python theme={null} import requests response = requests.post( "https://api.diversion.dev/v0/repos", headers={"Authorization": "Bearer "}, json={ "name": "my-repo", "description": "My first repo" } ) print(response.json()) # Should print the created repo ``` ## Error handling Some common errors can be returned from most API endpoints and are listed below. Errors that are specific to an API endpoint are listed in the endpoint's documentation. ### Error format All errors are returned in the following format: ```json theme={null} { "detail": "", "status": , "title": "" } ``` ```jsonschema theme={null} { "type": "object", "properties": { "detail": { "type": "string", "description": "A detailed description of the error" }, "status": { "type": "integer", "description": "HTTP status code", "examples": [400, 401, 403, 404, 500] }, "title": { "type": "string", "description": "A short, human-readable summary of the error type" }, }, "required": ["detail", "status", "title"] } ``` ### Common errors #### 400 Bad Request Returned when the request is invalid. Example response: ```json theme={null} { "detail": "'st' is too short\n\nFailed validating 'minLength' in schema:\n {'type': 'string',\n 'example': 'example_id',\n 'minLength': 3,\n 'maxLength': 128}\n\nOn instance:\n 'd'", "status": 400, "title": "Bad Request" } ``` #### 401 Unauthorized Returned when the authentication token is invalid or expired. Example response: ```json theme={null} { "detail": "Invalid authentication token", "status": 401, "title": "Unauthorized" } ``` #### 403 Forbidden Returned when the authentication token is valid but the user is not authorized to access the endpoint. Example response: ```json theme={null} { "detail": "User not authorized to perform the requested action on the resource", "status": 403, "title": "Forbidden" } ``` #### 404 Not Found Returned when the requested resource is not found. Example response: ```json theme={null} { "detail": "Workspace id not found", "status": 404, "title": "Not Found" } ``` #### 500 Internal Server Error Returned when the server encountered an unexpected condition that prevented it from fulfilling the request. Example response: ```json theme={null} { "detail": "Internal server error", "status": 500, "title": "Internal Server Error" } ``` # Delete file Source: https://docs.diversion.dev/api-reference/file-mutation/delete-file delete /repos/{repo_id}/files/{ref_id}/{path} Deletes a file or directory at the specified path in a workspace. **Requirements:** - The `ref_id` must be a workspace ID - Requires a client ID header **Behavior:** The deletion is recorded in the workspace's draft commit and can be reverted before committing. **Returns:** - `404 Not Found` if the path doesn't exist - `202 Accepted` on successful deletion # Move file Source: https://docs.diversion.dev/api-reference/file-mutation/move-file patch /repos/{repo_id}/files/{ref_id}/{path} Moves or renames a file from the current path to a new path specified in the `new_path` parameter. **Requirements:** - The `ref_id` must be a workspace ID - Requires a client ID header **Validation:** Both paths are normalized and validated before the operation. **Returns:** - `404 Not Found` if the source path doesn't exist - `202 Accepted` on successful move # Upload file Source: https://docs.diversion.dev/api-reference/file-mutation/upload-file post /repos/{repo_id}/files/{ref_id}/{path} Creates or updates a file in a workspace. **Requirements:** - The `ref_id` must be a workspace ID - Requires a client ID header **File content options:** - Inline as binary data - Via storage hints (storage_backend, storage_uri, sha1, size) **Parameters:** - `mode` - specifies file permissions - `mtime` - sets the modification time **Validation:** Reserved paths containing '.diversion' are rejected. **Returns:** - `202 Accepted` on success - `204 No Content` if no change was made # Introduction Source: https://docs.diversion.dev/api-reference/introduction Complete customization and integration with Diversion via APIs If you're not looking to build a new client or a custom integration, you probably want to look at the [Quickstart](/quickstart) guide. ## Welcome This section describes client-facing APIs. Diversion's native clients and web app use these endpoints. Server-side APIs are coming soon, if you want early preview access [contact us](mailto:hello@diversion.dev). ## Next Steps * Read the [Developer Guide](/api-reference/developer-guide) # Accept organization invite Source: https://docs.diversion.dev/api-reference/organization-management/accept-organization-invite post /organizations/{org_id}/invites/{invite_id}/accept Accepts an organization invitation, adding the user as a member with the role specified in the invite. **Validation checks:** - Invitation is addressed to the user's email - Invitation is still pending - Invitation hasn't expired **Returns:** - `409 Conflict` if the user is already a member - `403 Forbidden` if the invite isn't for this user - `204 No Content` on success # Change member role Source: https://docs.diversion.dev/api-reference/organization-management/change-member-role patch /organizations/{org_id}/members/{user_id}/role Update the role of an existing organization member # Create organization Source: https://docs.diversion.dev/api-reference/organization-management/create-organization post /organizations Creates a new organization with the user as the owner If the user is already a member of an organization with the same name, the request will fail # Get organization details Source: https://docs.diversion.dev/api-reference/organization-management/get-organization-details get /organizations/{org_id} Retrieves detailed information about a specific organization including: - Name - Description - Owner ID - Total storage usage - Warning group status **Requirements:** Requires READ access to the organization (user must be a member). **Returns:** - `404 Not Found` if the organization doesn't exist or user lacks access # Get organization member Source: https://docs.diversion.dev/api-reference/organization-management/get-organization-member get /organizations/{org_id}/members/{user_id} Get details about a specific member in the organization # Invite member to organization Source: https://docs.diversion.dev/api-reference/organization-management/invite-member-to-organization post /organizations/{org_id}/invites Sends an invitation to the specified user to join the organization with the chosen role. # Leave organization Source: https://docs.diversion.dev/api-reference/organization-management/leave-organization post /organizations/{org_id}/leave Leave the organization as a member. Organization owners and repository owners cannot leave until they transfer ownership. # List accessible repos Source: https://docs.diversion.dev/api-reference/organization-management/list-accessible-repos get /organizations/{org_id}/members/{user_id}/repos Returns a list of repositories the member will lose access to if removed. # List organization invites Source: https://docs.diversion.dev/api-reference/organization-management/list-organization-invites get /organizations/{org_id}/invites Retrieves a list of users who have been invited to the organization but have not yet accepted the invitation. # List organization members Source: https://docs.diversion.dev/api-reference/organization-management/list-organization-members get /organizations/{org_id}/members Get a paginated list of all members in the organization, sorted by name # List organization repositories Source: https://docs.diversion.dev/api-reference/organization-management/list-organization-repositories get /organizations/{org_id}/repos Get a list of all repositories in the organization # List pending org invites Source: https://docs.diversion.dev/api-reference/organization-management/list-pending-org-invites get /organizations/invites Retrieves all pending organization invitations for the current user based on their email address. Only returns non-expired invitations with optional status filtering (defaults to PENDING). Each invite includes organization details, inviting user information, role assignment, and expiration time. Invitations are automatically sent to the user's registered email address. # List user's organizations Source: https://docs.diversion.dev/api-reference/organization-management/list-users-organizations get /organizations Lists all organizations the user is a member of, optionally filtered to show only owned organizations when `owned=true`. **Sorting:** Results are sorted alphabetically by organization name. **Information included:** Each organization includes: - Basic metadata - A flag indicating if it's in a warning group (quota breach or payment issue) **Returns:** An empty list if the user is not a member of any organizations. # Organization subscriptions Source: https://docs.diversion.dev/api-reference/organization-management/organization-subscriptions get /organizations/subscription-info Get subscription and plan details for organizations the user is a member of # Reject organization invite Source: https://docs.diversion.dev/api-reference/organization-management/reject-organization-invite post /organizations/{org_id}/invites/{invite_id}/reject Rejects an organization invitation without adding the user as a member. **Behavior:** The invitation status is updated to REJECTED and the user will not be added to the organization. **Validation checks:** - Invitation is addressed to the user's email - Invitation is still pending - Invitation hasn't expired **Returns:** - `409 Conflict` if already processed - `204 No Content` on success # Remove organization member Source: https://docs.diversion.dev/api-reference/organization-management/remove-organization-member delete /organizations/{org_id}/members/{user_id} Only organization admins can delete members. # Rename organization Source: https://docs.diversion.dev/api-reference/organization-management/rename-organization patch /organizations/{org_id} Change the name of an organization. Only admins can perform this action. # Revoke invites by email Source: https://docs.diversion.dev/api-reference/organization-management/revoke-invites-by-email post /organizations/{org_id}/invites/revoke Revokes all organization and repository invitations for a specific email address within the organization. # Get Perforce import state Source: https://docs.diversion.dev/api-reference/perforce-repository-import/get-perforce-import-state get /repos/{repo_id}/p4-import-state Retrieve the current state of the continuous Perforce import job for this repository, including the last imported changelist, error information, and running status. # Mark P4 import as running Source: https://docs.diversion.dev/api-reference/perforce-repository-import/mark-p4-import-as-running post /repos/{repo_id}/p4-import-state/mark-running Mark the Perforce import job as currently running by generating a new running_job_id and setting the start timestamp. This should be called when a continuous import job begins. # Mark P4 import as stopped Source: https://docs.diversion.dev/api-reference/perforce-repository-import/mark-p4-import-as-stopped post /repos/{repo_id}/p4-import-state/mark-stopped Mark the Perforce import job as no longer running by clearing the running_job_id and started_unix timestamp. This should be called when a continuous import job completes or stops. The job will only be marked as stopped if the current running_job_id matches the one in the database to prevent race conditions. # Update P4 import state Source: https://docs.diversion.dev/api-reference/perforce-repository-import/update-p4-import-state post /repos/{repo_id}/p4-import-state Initialize or update the state of a continuous Perforce import job after manual initial import. Creates or updates a P4ImportJob record tracking the last imported changelist for incremental syncing. # Create branch Source: https://docs.diversion.dev/api-reference/repository-branch-manipulation/create-branch post /repos/{repo_id}/branches Create a branch, optionally with a branch description # Delete branch Source: https://docs.diversion.dev/api-reference/repository-branch-manipulation/delete-branch delete /repos/{repo_id}/branches/{branch_id} Delete a branch. The default branch cannot be deleted. # Get branch details Source: https://docs.diversion.dev/api-reference/repository-branch-manipulation/get-branch-details get /repos/{repo_id}/branches/{branch_id} Retrieves detailed information about a specific branch including: - ID - Name - Author - Creation time - Associated commit ID - Description - Deletion status - Draft commit status **Requirements:** Requires READ access to the repository. **Returns:** Branch details with enriched author information from the user database. # List branches Source: https://docs.diversion.dev/api-reference/repository-branch-manipulation/list-branches get /repos/{repo_id}/branches Get a list of all branches in the repo # Update a branch Source: https://docs.diversion.dev/api-reference/repository-branch-manipulation/update-a-branch patch /repos/{repo_id}/branches/{branch_id} Updates branch properties including: - Name - Description - The commit it points to - Protection status and configuration **Parameters:** The following optional fields can be provided in the request body: - `branch_name` - `branch_description` - `commit_id` - `is_protected` - Whether the branch is protected (requires ADMIN access) - `protection_config` - Configuration for protected branches (requires ADMIN access) **Limitations:** - Renaming branches is not supported for repositories synced with Git. - Setting protection requires ADMIN access to the repository. **Returns:** - `409 Conflict` if a branch with the new name already exists - `403 Forbidden` if attempting to modify protection without ADMIN access - `204 No Content` on success # Commit on behalf of author Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/commit-on-behalf-of-author post /repos/{repo_id}/workspaces/{workspace_id}/commit-on-behalf Commit workspace changes with custom author information and timestamp. This endpoint is used for importing commits from external VCS systems (e.g., Perforce) where the original author and timestamp should be preserved. Requires Admin access to the repository. # Commit workspace Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/commit-workspace post /repos/{repo_id}/workspaces/{workspace_id}/commit Commit workspace to base branch # Count commit changes Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/count-commit-changes get /repos/{repo_id}/commits/{commit_id}/count_changes Get the number of changes in a commit # Get commit details Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/get-commit-details get /repos/{repo_id}/commits/{commit_id} Get details of a specific commit # Get commits bulk Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/get-commits-bulk get /repos/{repo_id}/commits/bulk Get bulk details of commits by their reference IDs # List commits Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/list-commits get /repos/{repo_id}/commits Get a list of commits. (Executed on secondary shard) # Revert commit Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/revert-commit post /repos/{repo_id}/revert The operation reverts any changes done in the single commit represented by revert_ref_id (compared to its own parent). These opposing changes are then applied into the branch represented by base_id. If any changes were done between revert_ref_id and base_id, they will be checked for conflicts with the revert changes. # Revert to commit Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/revert-to-commit post /repos/{repo_id}/revert_to_commit_workspace The operation gets the file version in the specific commit and applies it to the workspace. Changes are the saved to the workspace. # Update commit message Source: https://docs.diversion.dev/api-reference/repository-commit-manipulation/update-commit-message patch /repos/{repo_id}/commits/{commit_id} Update a commit message. Can only be called on commits authored by the current user. # Compare refs Source: https://docs.diversion.dev/api-reference/repository-content-comparison/compare-refs get /repos/{repo_id}/compare Compare two refs (commit/branch/workspace/tag/tree) in this repo # Close draft commit Source: https://docs.diversion.dev/api-reference/repository-draft-commits/close-draft-commit post /repos/{repo_id}/draft-commits/{draft_commit_id}/close Close a draft commit. This operation changes the status to 'closed' and marks the draft branch as deleted. # List draft commits Source: https://docs.diversion.dev/api-reference/repository-draft-commits/list-draft-commits get /repos/{repo_id}/draft-commits List draft commits for the current user # Create a path permission Source: https://docs.diversion.dev/api-reference/repository-granular-permissions/create-a-path-permission post /repos/{repo_id}/granular-permissions Create a new path permission rule for this repository # Delete a path permission Source: https://docs.diversion.dev/api-reference/repository-granular-permissions/delete-a-path-permission delete /repos/{repo_id}/granular-permissions/{permission_id} Delete a path permission rule from the repository # Get path permission details Source: https://docs.diversion.dev/api-reference/repository-granular-permissions/get-path-permission-details get /repos/{repo_id}/granular-permissions/{permission_id} Get details of a specific path permission rule # List granular permissions Source: https://docs.diversion.dev/api-reference/repository-granular-permissions/list-granular-permissions get /repos/{repo_id}/granular-permissions List all granular permissions configured for this repository # Update a path permission Source: https://docs.diversion.dev/api-reference/repository-granular-permissions/update-a-path-permission patch /repos/{repo_id}/granular-permissions/{permission_id} Update an existing path permission rule # Create a repo Source: https://docs.diversion.dev/api-reference/repository-management/create-a-repo post /repos Create an empty repo. Optionally also skip the default `.dvignore` file or make it branchless. # List pending repo invites Source: https://docs.diversion.dev/api-reference/repository-management/list-pending-repo-invites get /repos/invites Retrieves all pending repository collaboration invitations for the current user based on their email address. **Filtering:** Returns non-expired invitations with optional status filtering (defaults to PENDING). **Each invite includes:** - Repository name - Organization (if applicable) - Inviting user details - Access mode - Expiration time **Use case:** Used by clients to display pending invitations requiring user action. # List user's repositories Source: https://docs.diversion.dev/api-reference/repository-management/list-users-repositories get /repos Get a list of repositories accessibly by the authenticated user # Delete repository Source: https://docs.diversion.dev/api-reference/repository-manipulation/delete-repository delete /repos/{repo_id} Delete a repo. All files, workspaces, commits, branches permissions etc. associated with the repo will be deleted. # Download file tree snapshot Source: https://docs.diversion.dev/api-reference/repository-manipulation/download-file-tree-snapshot get /repos/{repo_id}/tree_snapshot/{ref_id} Get URL to file tree snapshot. Either one of workspace, branch or commit ID needs to be specified as ref ID. If the requested commit doesn't have a snapshot, the endpoint will return the nearest available ancestor snapshot along with the `commit_id` of that snapshot. # Get blob contents Source: https://docs.diversion.dev/api-reference/repository-manipulation/get-blob-contents get /repos/{repo_id}/blobs/{ref_id}/{path} Get blob contents snapshot. Either one of workspace, branch or commit ID needs to be specified # Get file entry Source: https://docs.diversion.dev/api-reference/repository-manipulation/get-file-entry get /repos/{repo_id}/files/{ref_id}/{path} Get file entry (either tree or blob). Either one of workspace, branch or commit ID needs to be specified # Get file history Source: https://docs.diversion.dev/api-reference/repository-manipulation/get-file-history get /repos/{repo_id}/files/history/{ref_id}/{path} Retrieves the complete change history for a specific file or directory path from a given reference (branch or commit). **Returns:** A list of commits that modified the path, with each entry containing: - Commit details - File entry state at that commit **Features:** - Supports pagination via optional `limit` and `skip` parameters **Requirements:** Requires READ access to the repository. # Get file tree Source: https://docs.diversion.dev/api-reference/repository-manipulation/get-file-tree get /repos/{repo_id}/trees/{ref_id} Get file tree snapshot. Either one of workspace, branch or commit ID needs to be specified as ref ID # Get repository details Source: https://docs.diversion.dev/api-reference/repository-manipulation/get-repository-details get /repos/{repo_id} Retrieves detailed repository information including: - Name - Description - Size in bytes - Owner ID - Creation timestamp - Digest method - Default branch details - Git sync configuration (if enabled) - Organization ID (if part of an organization) - Default auto-forwarding status **Requirements:** Requires READ access to the repository. **Returns:** - `404 Not Found` if the repository doesn't exist or user lacks access # Get tree content stream Source: https://docs.diversion.dev/api-reference/repository-manipulation/get-tree-content-stream get /repos/{repo_id}/tree_content/{ref_id} Get file tree snapshot. Either one of workspace, branch or commit ID needs to be specified as ref ID # Import Git repository Source: https://docs.diversion.dev/api-reference/repository-manipulation/import-git-repository post /repos/{repo_id}/import Import a Git repo with all history from a Git URL. {repo_id} must have no commits and no branches, or be already marked as synced with the same git_url. The git repo URL must have http credentials embedded or otherwise hosted on Github and the owner has the Diversion Github app integration set up. # Rename repository Source: https://docs.diversion.dev/api-reference/repository-manipulation/rename-repository post /repos/{repo_id}/rename Change the name of a repository # Set default branch Source: https://docs.diversion.dev/api-reference/repository-manipulation/set-default-branch post /repos/{repo_id}/default_branch Change default branch for a repository # Set repo auto-forwarding Source: https://docs.diversion.dev/api-reference/repository-manipulation/set-repo-auto-forwarding post /repos/{repo_id}/set_def_auto_forwarding Set default auto-forwarding value, which determines whether they automatically advance to the latest commit when their branch receives new commits. This only affects workspaces created after this setting is changed. Existing workspaces retain their current auto-forwarding status. # Sync Git repository Source: https://docs.diversion.dev/api-reference/repository-manipulation/sync-git-repository post /repos/{repo_id}/sync Sync all history from Git. The repo must already be associated with a Git repo (see import). # Transfer ownership Source: https://docs.diversion.dev/api-reference/repository-manipulation/transfer-ownership post /repos/{repo_id}/transfer Transfer repository ownership or attach to an organization. Two modes of operation: - Transfer ownership within an organization: Provide new_owner_user_id to change the repository owner to another user in the same organization - Transfer personal repo to organization: Provide target_organization_id to attach a personal repository to an organization Exactly one of new_owner_user_id or target_organization_id must be provided. # Verify Git repository import Source: https://docs.diversion.dev/api-reference/repository-manipulation/verify-git-repository-import post /repos/import/check The git repo URL must have http credentials embedded or otherwise hosted on Github and the owner has the Diversion Github app integration set up. # Get merge details Source: https://docs.diversion.dev/api-reference/repository-merge-manipulation/get-merge-details get /repos/{repo_id}/merges/{merge_id} Retrieves detailed information about a specific open merge including all conflicts with their base, other, and result indices. **Each conflict shows:** - File paths - Modes - Sizes - Storage locations - Resolution status **Returns:** - `404 Not Found` if the merge doesn't exist - `405 Method Not Allowed` if the merge is obsolete # List open merges Source: https://docs.diversion.dev/api-reference/repository-merge-manipulation/list-open-merges get /repos/{repo_id}/merges Lists all open merge operations for a repository, optionally filtered by `base_id` (target branch) and `other_id` (source branch/commit). **Sorting:** Results are sorted with the current user's merges first, then by creation time. **Information included:** Each merge includes basic information without conflict details. **Requirements:** Requires READ access to the repository. # Merge refs Source: https://docs.diversion.dev/api-reference/repository-merge-manipulation/merge-refs post /repos/{repo_id}/merges Merge branch / workspace / commit into target branch # Apply shelf Source: https://docs.diversion.dev/api-reference/repository-shelves-manipulation/apply-shelf post /repos/{repo_id}/shelves/{shelf_id}/apply Applies a shelf's saved changes to a workspace specified in the `workspace_id` parameter. **Parameters:** - `workspace_id` (required) - `delete_shelf` (optional, defaults to false) - deletes the shelf after successful application **Conflict handling:** If conflicts occur during application, returns the merge ID for resolution. **Returns:** - `404 Not Found` if the shelf or workspace doesn't exist - `202 Accepted` with merge_id if conflicts occurred - `204 No Content` on clean application # Create a shelf Source: https://docs.diversion.dev/api-reference/repository-shelves-manipulation/create-a-shelf post /repos/{repo_id}/shelves Creates a new shelf by saving the current state of a workspace's uncommitted changes. **Parameters:** - `name` (required) - `workspace_id` (required) - `reset_workspace` (optional, defaults to true) - clean the workspace after shelving **Returns:** - `409 Conflict` if a shelf with the same name exists - `204 No Content` if the workspace has no changes - `201 Created` with the shelf details on success # Delete a shelf Source: https://docs.diversion.dev/api-reference/repository-shelves-manipulation/delete-a-shelf delete /repos/{repo_id}/shelves/{shelf_id} Permanently deletes a shelf and its saved changes. **Important:** The shelf cannot be recovered after deletion. **Requirements:** Requires WRITE access to the repository. **Returns:** - `404 Not Found` if the shelf doesn't exist or the user doesn't own it - `204 No Content` on successful deletion # Get shelf details Source: https://docs.diversion.dev/api-reference/repository-shelves-manipulation/get-shelf-details get /repos/{repo_id}/shelves/{shelf_id} Retrieves detailed information about a specific shelf including: - ID - Name - Creation timestamp - Associated branch ID (if applicable) - Commit ID **Requirements:** Requires READ access to the repository. **Returns:** - `404 Not Found` if the shelf doesn't exist or the user doesn't own it # List shelves Source: https://docs.diversion.dev/api-reference/repository-shelves-manipulation/list-shelves get /repos/{repo_id}/shelves Lists all shelves (saved workspace states) for the current user in a repository, optionally filtered by `branch_id` parameter. **Each shelf includes:** - ID - Name - Creation timestamp - Associated branch and commit IDs **About shelves:** Shelves allow users to temporarily save uncommitted changes for later reapplication. **Requirements:** Requires READ access to the repository. # Rename a shelf Source: https://docs.diversion.dev/api-reference/repository-shelves-manipulation/rename-a-shelf patch /repos/{repo_id}/shelves/{shelf_id} Renames an existing shelf by updating its name. **Parameters:** - `shelf_name` (required) - will be stripped of whitespace **Requirements:** Requires WRITE access to the repository. **Returns:** - `400 Bad Request` if the name is empty after stripping - `409 Conflict` if a shelf with the new name already exists - `204 No Content` on success # Create a tag Source: https://docs.diversion.dev/api-reference/repository-tag-manipulation/create-a-tag post /repos/{repo_id}/tags Creates a new tag pointing to a specific commit. **Parameters:** - `name` (required) - `commit_id` (required) - `description` (optional) **Validation:** Tag names must be unique within the repository. **Requirements:** Requires WRITE access. **Returns:** - `409 Conflict` if a tag with the same name exists - `503 Service Unavailable` if Git sync is in progress - `201 Created` with the tag ID on success # Delete a tag Source: https://docs.diversion.dev/api-reference/repository-tag-manipulation/delete-a-tag delete /repos/{repo_id}/tags/{tag_id} Marks a tag as deleted (soft delete). **Behavior:** The tag can no longer be retrieved or listed but may remain in the database for audit purposes. **Requirements:** Requires WRITE access to the repository. **Returns:** - `404 Not Found` if the tag doesn't exist or is already deleted - `503 Service Unavailable` if Git sync is in progress - `204 No Content` on successful deletion # Get tag details Source: https://docs.diversion.dev/api-reference/repository-tag-manipulation/get-tag-details get /repos/{repo_id}/tags/{tag_id} Retrieves detailed information about a specific tag including: - ID - Name - Author (enriched from user database) - Creation time - Associated commit ID - Description **Requirements:** Requires READ access to the repository. **Returns:** - `404 Not Found` if the tag doesn't exist or has been deleted # List tags Source: https://docs.diversion.dev/api-reference/repository-tag-manipulation/list-tags get /repos/{repo_id}/tags Lists all non-deleted tags in a repository, including: - Tag ID - Name - Author details (enriched from user database) - Creation time - Associated commit ID - Description **About tags:** Tags are lightweight named references to specific commits, useful for marking releases or important milestones. **Requirements:** Requires READ access to the repository. # Update a tag Source: https://docs.diversion.dev/api-reference/repository-tag-manipulation/update-a-tag patch /repos/{repo_id}/tags/{tag_id} Updates tag properties including: - Name - Description - The commit it points to **Parameters:** The following optional fields can be provided in the request body: - `name` - `description` - `commit_id` **Requirements:** Requires WRITE access to the repository. **Returns:** - `409 Conflict` if a tag with the new name already exists - `400 Bad Request` if the commit doesn't exist - `204 No Content` on success # Checkout workspace ref Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/checkout-workspace-ref post /repos/{repo_id}/workspaces/{workspace_id}/checkout Set the workspace to follow a different branch or commit (checkout). Currently supports only moving to a branch with an identical commit as the workspace's current branch, or moving to any branch/commit if the workspace has no working changes. # Cherry-pick commit Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/cherry-pick-commit post /repos/{repo_id}/workspaces/{workspace_id}/cherry-pick Cherry-picks changes from a specific commit (identified by `ref_id`) into the current workspace. **Process:** - Creates a temporary patch from the source commit - Applies it to the workspace - If conflicts occur, returns a merge ID that must be resolved before proceeding **Requirements:** Requires WRITE access. **Returns:** - `404 Not Found` if the reference doesn't exist - `202 Accepted` with merge_id if conflicts occurred - `204 No Content` on clean application # Copy file into workspace Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/copy-file-into-workspace post /repos/{repo_id}/workspaces/{workspace_id}/copy_from/{ref_id}/{path} Copy a file from a ref to the workspace, overwriting any existing file. # Create a workspace Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/create-a-workspace post /repos/{repo_id}/workspaces Create a new workspace with the given name, on the chosen branch or commit. If neither is specified, the default branch is used. If a commit is specified, the workspace will be created on that commit, in a "detached" state, meaning it will not be associated with any branch and new commits cannot be published by it. # Create draft commit Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/create-draft-commit post /repos/{repo_id}/workspaces/{workspace_id}/commit-draft Create a draft commit from workspace changes, optionally with a review # Delete workspace Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/delete-workspace delete /repos/{repo_id}/workspaces/{workspace_id} Deletes a workspace, removing it from the user's workspace list. **Important:** The workspace's uncommitted changes are lost unless previously shelved or committed. **Use cases:** - Cleaning up unused workspaces - Switching between different working contexts **Requirements:** Requires READ access to the repository. **Returns:** - `404 Not Found` if the workspace doesn't exist - `204 No Content` on successful deletion # Get workspace details Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/get-workspace-details get /repos/{repo_id}/workspaces/{workspace_id} Get a workspace object details. # Get workspace preferences Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/get-workspace-preferences get /repos/{repo_id}/workspaces/{workspace_id}/preferences Retrieves workspace-specific preferences including sync path rules that control which paths are synchronized to the local file system. **Sync path rules:** The `sync_paths_rules` array contains glob patterns for selective sync. This enables users to work with large repositories by syncing only relevant subdirectories. **Requirements:** Requires READ access to the repository. **Returns:** An empty rules array if no preferences are set. # List workspaces Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/list-workspaces get /repos/{repo_id}/workspaces List user's workspaces. Repo owners and admins can optionally list all workspaces in the repo (not just their own) by setting scope=all. # Merge base branch Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/merge-base-branch post /repos/{repo_id}/workspaces/{workspace_id}/forward Fast-forwards a workspace to incorporate the latest changes from its base branch. **Conflict handling:** When explicitly requested by users, conflicts are created and returned as a merge ID for manual resolution. This ensures the workspace is up-to-date with the branch before committing. **Returns:** - `412 Precondition Failed` if the workspace is detached - `503 Service Unavailable` if a dependent service is unavailable - `202 Accepted` with merge_id if conflicts occurred - `200 OK` if changes were applied - `204 No Content` if already up-to-date # Other workspace statuses Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/other-workspace-statuses get /repos/{repo_id}/workspaces/{workspace_id}/other_statuses Get list of potential conflicts with files in other users' workspaces and branches # Reset changes in workspace Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/reset-changes-in-workspace post /repos/{repo_id}/workspaces/{workspace_id}/reset Resets uncommitted changes in a workspace by discarding modifications and optionally deleting added files. **Parameters:** - `all=true` - reset everything - `paths` array - reset specific files - `delete_added` (defaults to false) - controls whether newly added files are deleted - `write_to_journal` (defaults to true) - records the reset operation **Returns:** Lists of: - Succeeded paths - Failed paths - Skipped paths **Requirements:** Requires WRITE access. # Set auto-forwarding status Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/set-auto-forwarding-status post /repos/{repo_id}/workspaces/{workspace_id}/set_auto_forwarding Set whether the workspace will automatically advance to the latest commit when its branch receives new commits. # Update workspace name Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/update-workspace-name post /repos/{repo_id}/workspaces/{workspace_id}/rename Renames a workspace to a new name specified in the `name` parameter. **Validation:** - The name cannot be empty - Must be unique for the user within the repository - Cannot exceed 256 characters **Requirements:** Requires READ access to the repository. **Returns:** - `400 Bad Request` if the name is invalid (empty or exceeds 256 characters) - `409 Conflict` if a workspace with the new name already exists - `204 No Content` on success # Update workspace preferences Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/update-workspace-preferences put /repos/{repo_id}/workspaces/{workspace_id}/preferences Updates workspace preferences, specifically the `sync_paths_rules` array that controls which paths are synchronized. **Validation:** New rules are validated to ensure no unselected paths contain uncommitted changes. **Requirements:** Requires WRITE access to the repository. **Returns:** - `409 Conflict` if attempting to deselect paths with changes (must commit or reset first) - `202 Accepted` on success # Workspace status Source: https://docs.diversion.dev/api-reference/repository-workspace-manipulation/workspace-status get /repos/{repo_id}/workspaces/{workspace_id}/status Retrieves the current status of a workspace including: - Counts of new files - Counts of modified files - Counts of deleted files - Optionally detailed file entries **Features:** - Pagination via `limit` and `skip` - Filtering by `path_prefix` - Recursive/non-recursive listing via `recurse` parameter - `detail_items` parameter controls whether full file entries are returned - Results filtered based on path permissions - Supports caching and ETags for performance # Add review comment Source: https://docs.diversion.dev/api-reference/reviews/add-review-comment post /repos/{repo_id}/reviews/{review_id}/comments Add a comment to a review with optional file reference # Create review Source: https://docs.diversion.dev/api-reference/reviews/create-review post /repos/{repo_id}/reviews Create a new review for comparing two refs # Get changes for a review Source: https://docs.diversion.dev/api-reference/reviews/get-changes-for-a-review get /repos/{repo_id}/reviews/{review_id}/changes Get the correct ancestor and compare commits for a review. This endpoint uses the merge commit's parent (if merged) to find the original divergence point, solving the issue where squash merges make find_common_ancestor return the feature tip. # Get review Source: https://docs.diversion.dev/api-reference/reviews/get-review get /repos/{repo_id}/reviews/{review_id} Get review details including title, description, and status # List review comments Source: https://docs.diversion.dev/api-reference/reviews/list-review-comments get /repos/{repo_id}/reviews/{review_id}/comments List all comments associated with a review # List reviews Source: https://docs.diversion.dev/api-reference/reviews/list-reviews get /repos/{repo_id}/reviews List all reviews for a repository # Update review Source: https://docs.diversion.dev/api-reference/reviews/update-review patch /repos/{repo_id}/reviews/{review_id} Update review details (title, description, and/or status) # Update reviewer status Source: https://docs.diversion.dev/api-reference/reviews/update-reviewer-status patch /repos/{repo_id}/reviews/{review_id}/reviewers/status Update the current user's reviewer status for a review # Get user information Source: https://docs.diversion.dev/api-reference/user-management/get-user-information get /user Retrieves the authenticated user's profile information including: - User ID - Email - Full name - Avatar URL - Account tier **Use case:** This endpoint provides the current user's details needed for displaying profile information in the client UI. **Returns:** - `404 Not Found` if the user doesn't exist in the database (should not occur for authenticated requests) # Update user information Source: https://docs.diversion.dev/api-reference/user-management/update-user-information patch /user Update user information including display name and email preferences # Access Levels Source: https://docs.diversion.dev/basic/access-levels Understanding the access levels used in granular permissions Diversion uses a hierarchical access level system to control what users can do in a repository. Each level includes all the permissions of the levels below it. ## Access Level Hierarchy ``` Admin > Write > Merge > Read ``` Each higher level includes all permissions from lower levels. For example, a user with Write access can also Merge and Read. ## What Each Level Can Do | Level | Description | Operations | | --------- | ----------------------- | -------------------------------------------------------------------- | | **Read** | View only | Browse files, view commit history, see diffs, download files, review | | **Merge** | Accept incoming changes | Accept non-conflicting changes from others during merge operations | | **Write** | Modify files | Commit changes, resolve merge conflicts | | **Admin** | Full control | | ## Organization-Level Access If a repository belongs to an organization, **organization owners and admins are treated as Admin on every repository in that organization** -- even repositories they were never invited to as a collaborator. This applies to every admin-gated operation, not just managing collaborators: things like obliterating files, editing branch protection, granular permissions, webhooks, and auto-lock / auto-release settings are all available to organization owners and admins on any repo in the org. If their direct repository access is already higher (unusual, since Admin is the top level), it is left as is. See [Organization Management](/basic/organization-management) for how organization roles are assigned. ## Repository-Level vs Path-Level Access **Repository-level access** is set when you invite a collaborator. This determines the maximum access level the user can have in the repository. **Granular permissions access** uses [granular permissions](/basic/granular-permissions) to control access for specific files or folders. For example, you can give someone Write access to the repository but restrict them to Read-only on sensitive paths. Granular permissions only restrict access - they cannot grant higher access than the user's repository-level permission. Once any granular permission rule exists in the repository, users without matching rules are denied all access by default. ## Choosing the Right Level | Use Case | Recommended Level | | ---------------------------------------------------------------- | ----------------- | | External reviewers or auditors | Read | | Team members who receive updates but don't directly modify files | Merge | | Active team members who commit code | Write | | Team leads and repository owners | Admin | Start with the minimum access level needed. You can always grant additional access later. # Branch Protection Source: https://docs.diversion.dev/basic/branch-protection Prevent direct commits to important branches and require changes to be merged in Branch protection lets you safeguard important branches—such as your main branch or release branches—by blocking direct commits. Once a branch is protected, changes can no longer be committed to it directly; they must be made on another branch and merged in. Branch protection is available to all users at no additional cost. Branch protection settings page with the Add branch protection form ## What Protection Does When a branch is protected: * **Direct commits are blocked.** Users cannot commit changes straight to the protected branch. * **Changes must be merged in.** To update a protected branch, make your changes on a separate branch and merge that branch into the protected one. * **Admins can optionally bypass.** You can allow administrators—or a specific list of users—to commit directly, bypassing the protection. Branch protection currently enforces that changes arrive through a merge. A requirement that merges first pass review or approval is on the roadmap and is **not yet enforced**. This page will be updated when that capability ships. ## Adding a Protection Rule Check the repository dropdown in the **top-right** of the window and make sure the correct repository is selected before continuing. Go to **Settings → Branch protection**. Under **Add branch protection**, open the **Branch** dropdown and choose the branch you want to protect. Selecting a branch from the Branch dropdown Choose who, if anyone, is allowed to commit directly to the protected branch: * **Allow admins to bypass** — toggle this on to let repository administrators commit directly. When off, the helper text reads *"Admins cannot bypass protection."* * **Bypass restrictions (optional)** — use the **Select users…** dropdown to add specific users who can bypass protection and commit directly to this branch. Leave both options untouched to enforce protection for everyone, including admins. Add branch protection form showing the Allow admins to bypass toggle and Bypass restrictions Click **Add protection**. The branch is now protected. ## Managing Existing Rules Each existing rule lists the protected branch, its bypass status (for example, *"No bypass allowed"*), and any **Allowed users** who can commit directly. Use the **pencil** icon to edit a rule or the **trash** icon to delete it. ### Removing a Protection Rule To stop protecting a branch, go to **Settings → Branch protection**, find the rule for that branch, and click the **trash** icon to delete it. Direct commits to the branch are allowed again immediately. An existing branch protection rule for main, with edit (pencil) and delete (trash) controls # Changing the past Source: https://docs.diversion.dev/basic/changing-the-past How to undo, cherry-pick, edit, or copy details from a previous commit ## Undoing a commit Committed something and wish you hadn't? No worries, you can undo a previous commit with a `revert`. This will create changes that are the opposite of the commit you want to undo. Open the workspace of the repo where your changes are. Make sure that you have no pending changes. In the left navigation rail, click **Commits**. Click on the menu icon next to the commit you want to revert, and select "Undo this commit". In the modal window, click "Undo changes". It's possible you'll have to resolve a merge conflict, see below. Undo commit You'll see new changes in your workspace that undo the changes for your commit. In this example, this is the commit I chose to undo: Reverted commit And this is the resulting change in my workspace: Workspace after commit revert If you try to revert a commit that affects a file that was also affected by a later commit, it will result in a merge conflict. You'll have to resolve the conflict before you can commit the changes. Earlier, I reverted a file that was edited. Now, instead, I'll try to revert an earlier commit - the one where the file was created. Workspace after commit revert This will result in a merge conflict, which you'll have to resolve before you can commit the changes. Workspace after commit revert ## Editing a commit message Made a typo in your commit message, or want to add more detail? You can edit the message of any commit you authored directly from the Commits view. Editing commit messages is only available for the commit author, and is not supported for repositories synced with Git. In the Commits view, click on the menu icon next to the commit whose message you want to change, and select "Edit commit message". Edit commit message menu option An "Edit commit message" dialog will appear, showing the commit ID for reference and a text area with the current message. Edit the message as you like, then click "Update" to save it. Edit commit message dialog ## Cherry-picking a commit Cherry-picking lets you take a specific commit from the history and re-apply its changes into your current workspace. This is useful when you want to bring in a particular change without merging an entire branch. Your workspace must have no uncommitted changes before cherry-picking. Cherry-picking is not available for the initial commit of a repository. In the Desktop App: Open the Commits view and find the commit you want to cherry-pick. Right-click on the commit and select "Cherry-pick into workspace". Cherry-pick context menu option If the cherry-picked changes conflict with your current workspace, you'll be taken to the merge conflict resolution view. See [merge conflicts](/basic/working-in-parallel#merge-conflicts) for details on resolving them. Via the CLI, see the [cherry-pick command](/cmd-ref/cherry-pick) for details. ## Copying commit details Need to reference a specific commit in a conversation or a script? You can quickly copy a commit's ID or message straight from the Commits view. In the Commits view, click on the menu icon next to a commit and select "Copy commit ID". The ID is copied to your clipboard right away -- you'll see a "Copied commit ID" notification confirming it. Copy commit ID menu option Similarly, you can select "Copy commit message" from the same menu to copy the full commit message text to your clipboard. # Draft Commits Source: https://docs.diversion.dev/basic/draft-commits Request feedback on your changes before committing them ## What are Draft Commits? Draft commits let you request feedback on your changes **before** they're committed to your active branch. You can create a review directly from your uncommitted workspace changes. This keeps your commit history clean while still getting the code review you need. ## Why Use Draft Commits? Draft commits are ideal when you: * **Work on a single branch** and want a simpler review workflow * **Want early feedback** on work-in-progress changes before finalizing them * **Keep your history clean** by only committing approved changes * **Experiment with ideas** and want team input before making them permanent Draft commits are optional. You can still use the regular commit workflow if you prefer to commit first and review later. ## Draft Commits vs Reviews Here's a quick comparison to help you choose the right workflow: | | Draft Commits | Reviews | | ------------------ | ------------------------------------------- | --------------------------------------------- | | **When to use** | Get feedback before committing | Get feedback on existing commits/branches | | **Starting point** | Uncommitted workspace changes | Committed changes in a branch | | **Commit history** | Changes only committed after approval | Changes already in branch history | | **Workflow** | Edit → Send to review → Approve → Commit | Commit → Create review → Approve → Merge | | **Best for** | Single-branch workflow, work-in-progress | Multi-branch workflow, feature branches | | **Commit history** | Only approved changes committed | May include intermediate/experimental commits | | **Flexibility** | Easy to discard or modify before committing | Requires reverting or amending commits | Both features create the same review experience with comments, approvals, and notifications. The main difference is **when** you commit your changes - before or after getting feedback. ## Creating a Draft Commit **Step-by-Step Instructions:** 1. **Make changes in your workspace** * Edit files as you normally would * Your changes remain uncommitted in your workspace 2. **Open your repository** * Open your repository in the Diversion web app * Your workspace's pending changes appear in the **Files** view 3. **Click the dropdown arrow next to "Commit..."** * The commit button has a dropdown arrow (▼) on the right side * Click the arrow to open the dropdown menu * Select **"Send to review\..."** Commit button dropdown with Send to review option 4. **Confirm the files to send** * A confirmation dialog shows the files that will be sent to review * Review the file list and click **"Send to review"** to proceed Send to review confirmation dialog 5. **Fill in the review details** * **Title** (required): Brief description of your changes * Example: "Add user authentication endpoints" * **Description** (optional): Detailed explanation for reviewers * Explain what you changed and why * Mention any areas where you need specific feedback * **Reviewers** (optional): Select teammates who should review your changes * You can add reviewers now or later 6. **Click "Send to Review"** * A review is automatically created with your uncommitted changes * Your workspace is automatically cleared so you can immediately continue working on other changes (the changes are safely stored in the draft) * Assigned reviewers receive email notifications Create draft commit form ## Managing Your Draft Commits ### Viewing Your Drafts 1. **Open the branch selector** * Open the branch selector (top-left, showing the current branch and commit), then click the **Drafts** tab. 2. **Find your drafts** * Your draft commits appear under the **Drafts** tab * Each draft shows its title and source branch 3. **Access draft actions** * Click the **...** (more options) menu next to a draft to see available actions: * **View Review**: Open the associated review to see feedback and comments * **Update**: Switch to the draft to continue working on it * **Close**: Discard the draft commit Draft commits in the branch selector You can have multiple draft commits open simultaneously, allowing you to work on different changes and get feedback on each independently. ## Updating a Draft Commit If you need to make changes to your draft after creating it: **Step-by-Step Instructions:** 1. **Find your draft** * Open the branch selector and switch to the **Drafts** tab. Locate your draft in the list. 2. **Click "Update"** * Click the **...** (more options) menu next to your draft * Select **"Update"** from the menu * Confirm by clicking **"Switch to draft"** in the dialog * This switches your workspace to the draft branch and loads the draft changes * You can now continue editing 3. **Make additional changes** * Edit files to address reviewer feedback 4. **Update the draft** * Commit your changes * The review updates automatically with your new changes * Reviewers see the updated diff ## After Review Approval Once your reviewers have approved your draft: 1. **Review the feedback** * Read through all comments and approvals * Make sure all concerns are addressed 2. **Finalize your changes** * Switch back to the draft if needed to make final adjustments * Ensure everything is ready to commit 3. **Commit the changes** * The approved changes can now be committed to your branch * Your commit history stays clean with only reviewed, approved changes 4. **The draft closes automatically** * Once merged or committed, the draft status changes to closed ## Closing a Draft Commit If you decide you don't want to proceed with a draft: **Step-by-Step Instructions:** 1. **Find your draft** * Open the branch selector and switch to the **Drafts** tab. Locate your draft in the list. 2. **Click "Close"** * Click the **...** (more options) menu next to your draft * Select **"Close"** from the menu 3. **Confirm closing** * Click **"Close draft"** in the confirmation dialog * This action cannot be undone 4. **Draft is removed** * The draft is deleted from your active drafts list * If you were on the draft branch, you are switched back to the source branch * Changes are discarded ## Working with Draft Reviews ### Review Process Draft commits create reviews automatically, so the review process works the same: * **Reviewers can comment** on specific lines or files * **Reviewers can approve or request changes** * **You receive notifications** when reviewers respond * **Discussion happens in the review** just like regular reviews For detailed review instructions, see the [Reviews documentation](/basic/reviews). ### Notifications You'll receive email notifications for: * When reviewers comment on your draft * When reviewers approve or request changes * When the review is closed/merged # The .dvignore file Source: https://docs.diversion.dev/basic/dvignore Safely ignore files not needed in your repository The `.dvignore` file is used by Diversion to specify files and directories that should be ignored when tracking changes. This helps keep the repository clean by excluding unnecessary or automatically generated files, such as build artifacts, temporary files, and cached data. ### Purpose Using a `.dvignore` file ensures that only relevant files are committed to the repository. This helps: * Prevent clutter from unnecessary files. * Improve performance by avoiding tracking large or frequently changing temporary files. * Avoid committing sensitive or auto-generated files. While `.dvignore` decides what the repository **tracks and stores**, [Selective Sync](../advanced/selective-sync) controls which of those already‑tracked files your workspace actually downloads. ### File Structure The `.dvignore` file consists of patterns defining which files or directories to exclude. It typically follows these rules: * A line starting with `#` serves as a comment. Put a backslash `\` in front of the first hash for patterns that begin with a hash. * Don’t mix comments and patterns on the same line. **Mixing them will cause the pattern to not have any effect.** * Wildcard `*` matches any sequence of characters (but does **not** cross `/` boundaries, unlike `**`). * Directories ending with `/` ignore all contents inside. * Negations `(!)` explicitly include files that might otherwise be ignored. #### Advanced rule semantics * **Root‑anchored `/`** – a leading slash matches from the repository root; without it, the pattern can match anywhere. * **Double asterisk `**`** – matches across directory boundaries (e.g., `Assets/**/config.ini`). * **Negation precedence** – a `!pattern` only re‑includes a path if one of its ancestors was ignored by a prior rule. ```text theme={null} Saved/* !Content/** ``` `Saved/Windows/Content/file.txt` -> still ignored * **Nested `.dvignore` files** – rules in nested directories override rules from parent directories. > **Git compatibility**: Diversion implements the same pattern‑matching semantics as Git’s `.gitignore`—including support for nested ignore files—so a source tree copied from Git will behave identically out of the box. IMPORTANT NOTE: Diversion treats existing .gitignore files (both root and nested) similarly to .dvignore files, so when a Git repository is transferred into Diversion its original ignore rules are preserved.
When both .dvignore and .gitignore exist in the same directory, their patterns are merged and .dvignore takes precedence (last-match-wins). This lets you override .gitignore rules without editing the .gitignore itself.
In some cases, such as transferring the Unreal Engine source repository from Git, you may want to remove the existing .gitignore files and replace them with a custom ignore file tailored to your needs.
#### Enabling the V1 matcher Ignore-file matching in Diversion is versioned. The default works well for most projects, and **V1** is an opt-in upgrade whose pattern matching follows Git's `.gitignore` rules even more closely — last-matching-rule-wins precedence, negations that re-include paths, root-anchored patterns, `**` across directory boundaries, and nested ignore files. To turn it on, add this directive as the **first non-empty line** of your repository-root `.dvignore`, before any patterns (leading blank lines are fine): ``` # dv-ignore-version: 1 ``` If the directive is missing or isn't on the first non-empty line, Diversion keeps using the default matcher. For game‑engine projects Diversion ships a default **.dvignore** tailored to each engine. The snippets below are high‑level illustrations; check the actual **.dvignore** generated in your repo for the authoritative rules. #### Unreal ``` # Unreal Engine build files Build/* # Saved game states and config files Saved/* # Compiled intermediate files Intermediate/* # Editor cache files DerivedDataCache/* ``` #### Unity ``` # Unity temp folder .utmp/ # Unity Library /[Ll]ibrary/ # Temporary files /[Tt]emp/ # Object files /[Oo]bj/ # Build directories /[Bb]uild/ /[Bb]uilds/ # Log files /[Ll]ogs/ # User-specific settings /[Uu]ser[Ss]ettings/ # Memory captures /[Mm]emoryCaptures/ # Recordings /[Rr]ecordings/ ``` For the complete Unity `.dvignore` with IDE files, Addressables, Visual Scripting, and more, see [Unity Best Practices](/unity/unity-best-practices). #### Godot ``` # Godot internal directory .godot/ # Import cache folder .import/ # Export settings export.cfg # Export presets export_presets.cfg # Auto-generated translation files *.translation ``` You can modify the `.dvignore` file based on your project needs. If you work with additional tools or frameworks, consider adding their cache or temporary directories to improve repository management. For example, if you use a custom build system, you might add: ``` /build_output/ /temp_build_files/ ``` ### Ignoring already committed files IMPORTANT NOTE: Files and directories that are already committed, will NOT be ignored by .dvignore. 1. If you wish to ignore a committed path, you need to first delete it and commit the deletion. If the content of that path can’t be auto-generated, you should back it up somewhere else and copy back after committing the deletion. 2. Notify your collaborators to backup their copies before committing the deletion, because updating with that commit will delete their copies too. 3. Example of auto-generated paths: build artifacts and intermediates, auto-generated code. 4. Example of non-auto-generated paths: credentials files, local configuration files. An empty directory will NOT be ignored if there is a **negation** rule for one of its descendants. When a directory has a **negation** rule for one of its descendants, Diversion keeps that directory **tracked**, even if the descendant file doesn’t exist yet. ``` Build/* !Build/app.dll ``` Because `!Build/app.dll` re-includes a possible future file, the `Build/` directory itself is tracked (and will show up empty until `app.dll` appears). If you really want to ignore `Build/` altogether, remove the negation line (`!Build/app.dll`). # Get an existing project Source: https://docs.diversion.dev/basic/get-existing-project Clone a repo and manage files in your workspace A team member has [set up Diversion](/basic/start-using-diversion) for your project and [invited you to join](/basic/manage-project-access), or maybe you want to get your own project that you created on another computer. Let's get you set up: Remote repositories tab Open the repo's `...` menu and select `Clone repo`. A new folder with the repo's name will be created in it (here - `DiversionExample`). Clone a repo Click `Clone`. The project should start downloading right away. When it's done, you can open it and start working! ## File operations Diversion gives you quick access to common file operations right from the Files view. Right-click any file to see the available actions, or use the file title bar when viewing a file. Right-click context menu showing file operations ### Delete a file In the Files view, right-click on the file you want to delete and select **Delete**. You'll see a confirmation dialog asking "Are you sure you want to delete the file '\[file-path]'?" Click the red **Delete** button to confirm, or cancel if you changed your mind. The deleted file will appear in your pending changes in **red** with an **x** icon, indicating it has been deleted. Deleted file shown in red with x icon For CLI usage, see the [rm command](/cmd-ref/rm). ### Rename a file In the Files view, right-click on the file you want to rename and select **Rename**. A dialog appears with the current file name pre-filled. Type the new name for your file. Click **Rename** to apply the new name. Don't forget to include the file extension in the new name (e.g. `.txt`, `.cpp`, `.uasset`). Omitting it may cause the file to become unrecognized by your OS or game engine. File names cannot contain any of these characters: `< > : " / \ | ? *` The renamed file will appear in your pending changes in **green** with a **double arrow (>>)** icon, indicating a move/rename operation. Renamed file shown in green with double arrow icon For CLI usage, see the [mv command](/cmd-ref/mv). ### Move a file In the Files view, right-click on the file you want to move and select **Move**. A directory picker dialog opens. Browse to the folder where you want to move the file. Click **Move** to move the file to the selected folder. The file keeps its original name. The moved file will appear in your pending changes in **green** with a **double arrow (>>)** icon, indicating a move/rename operation. Moved file shown in green with double arrow icon For CLI usage, see the [mv command](/cmd-ref/mv). ### View file history In the Files view, right-click on the file and select **History**. The file history page shows all commits that changed this file, including the operation type (added, modified, moved), commit message, author, and date for each change. Click on any commit to see the diff for that version. File history page showing commits ### Restore a previous version When viewing a file at a specific commit, you can send that version to your workspace. This replaces the current file contents with the selected version, and the change appears in your pending changes. You can get there in two ways: * From the **file history**: right-click a file, select **History**, then click on the commit you want. * From the **branch history**: open a commit, then click on the file you want to restore. In the file title bar, click the **Send this version to workspace** button (arrow icon). Send this version to workspace button in file title bar The restored file will appear in your pending changes as a modification. You can review the changes and commit when ready. For CLI usage, see the [restore command](/cmd-ref/restore). ### Annotate (blame) The **Annotate** view shows who last modified each line of a file, along with the commit message and date. This is useful for understanding how a file evolved and who is responsible for specific changes. Annotate is only available for text files. Binary files are not supported. Right-click a file in the Files view and select **History**. Click the **Annotate** tab at the top of the file history view. Annotate view showing line-by-line commit attribution The left panel shows a color-coded dot, how long ago the change was made, the author name, and the commit message for each line range. The right panel shows the file contents with line numbers. Hover over any entry in the left panel to see full commit details: author avatar and name, date, full commit message, and commit ID. Click **View commit** to navigate to that commit. Annotate tooltip showing commit details on hover For CLI usage, see the [annotate command](/cmd-ref/annotate). ### Download a file When you click on a file in the workspace or commit view, a download icon button appears in the file title bar. Click it to download the file to your computer. Download button in file title bar ### Open in Explorer (Desktop only) Right-click a file in the Files view and select **Show in Explorer** (Windows) or **Reveal in Finder** (macOS) to open the containing folder in your system file explorer. Show in Explorer option in context menu This option is only available for locally cloned workspaces. Make sure the Diversion agent is running. This is also useful for opening project files directly. For example, you can use **Show in Explorer** to navigate to your Unreal Engine `.uproject` file and open it from there. ### Open with default app (Desktop only) When viewing a file, click the **Open with default app** icon in the file title bar to open the file with whatever application your OS associates with that file type. Open with default app button in file title bar This option is only available for locally cloned workspaces. Make sure the Diversion agent is running. You can also use this to open project files directly -- for example, opening a `.uproject` file will launch it in Unreal Engine. Keep in mind that you may need to have previously opened the project with the correct engine version for this to work as expected. # Going back in time Source: https://docs.diversion.dev/basic/going-back-in-time Reverting to or branching from a previous commit You've been working on your project for a while, and you realize that you made a mistake a few commits ago. Or maybe you want to start a new feature based on an older version of your project. No worries! You can go back in time to a previous commit. ## Reverting to a previous commit One way to go back in time is to revert to a previous commit. This will create changes in your workspace that undo all of the commits from the commit you've chosen to revert to up to the current commit. This does not create a new commit! Since this action will automatically create changes in your workspace, it must be clean beforehand. Undo or commit any changes you have. In the **Commits** view, click the menu for the commit you want to revert to and select `Revert to this commit`. The button to revert to a previous commit You'll be taken to the **Files** view where you'll see the changes that will be made. ## Branching from a previous commit Another way to go back in time is to create a new branch from a previous commit. This will create a new branch with the commit you've chosen as the base. The button to create a branch from a previous commit Follow the steps to create a new branch, as described in [Working in parallel](/basic/working-in-parallel#creating-a-new-branch). # Granular Permissions Source: https://docs.diversion.dev/basic/granular-permissions Control access to specific paths within your repository Granular permissions allow you to set fine-grained access control for specific files and folders within a repository. Instead of giving users full repository access, you can restrict what they can read, write, merge, or administrate at the path level. ## When to Use Granular Permissions Granular permissions are useful when you need to: * **Protect sensitive paths**: Prevent team members from modifying security-critical code, configuration files, or production assets * **Restrict by role**: Allow designers to only modify assets while developers work on code * **Isolate components**: Let teams work on specific parts of the repository without accessing others ## Access Levels Diversion uses four hierarchical access levels: | Level | Description | | --------- | ----------------------------------- | | **Admin** | Full control | | **Write** | Can modify files | | **Merge** | Can participate in merge operations | | **Read** | Can view files only | Access levels are hierarchical: Admin includes all privileges of Write, which includes Merge, which includes Read. See [Access Levels](/basic/access-levels) for details on what each level can do. ## Permission Types Each rule uses one of four permission types that control how access is granted or denied: | Type | Behavior | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Allow (Hierarchical)** | Grants the specified level **and all lower levels**. Example: Allow (Hierarchical) + Write grants Write and Read access. | | **Allow (Exact)** | Grants **only the exact level** specified. Example: Allow (Exact) + Write grants Write but not Read. | | **Deny (All Above)** | Stops rule evaluation and denies all access levels (the level field is ignored). Any permissions already granted by higher-priority rules (lower in table) are kept. | | **Deny (Exact)** | Denies **only the exact level** specified. Example: Deny (Exact) + Write denies Write but allows Read. | Use **Allow (Hierarchical)** for most cases since it grants natural permission inheritance. Use **Exact** types when you need to grant or deny a specific level without affecting others (e.g., deny Write but keep Read). ## Path Patterns Path patterns specify which files a rule applies to. Patterns always start with `/` representing the repository root. | Wildcard | Behavior | | -------- | --------------------------------------------- | | `*` | Matches within a single directory only | | `...` | Matches recursively across all subdirectories | Here are some common patterns: | Pattern | Matches | | ------------------- | --------------------------------------------------- | | `/path/to/file.txt` | Exact file match | | `/path/...` | All files under `/path/` recursively | | `/path/....py` | All `.py` files under `/path/` recursively | | `/path/*` | All files directly in `/path/` (not subdirectories) | | `/path/prefix*` | Files in `/path/` starting with "prefix" | ## Rule Priority Rules are evaluated from the **bottom of the table to the top**. When multiple rules match, the **highest permission wins** - unless a Deny rule stops evaluation. Rules lower in the table have **higher priority**. Deny rules can override Allow rules above them. ### Example: Multiple Allow Rules | # | User | Path | Level | Type | | - | ----- | --------------- | ----- | -------------------- | | 1 | alice | /src/... | Write | Allow (Hierarchical) | | 2 | alice | /src/secret/... | Read | Allow (Hierarchical) | When Alice accesses `/src/secret/config.json`: * Both rules match * The highest permission (Write) is granted * **Result: Alice can Write** to files in `/src/secret/` ### Example: Using Deny to Restrict Access | # | User | Path | Level | Type | | - | ----- | --------------- | ----- | -------------------- | | 1 | alice | /src/... | Write | Allow (Hierarchical) | | 2 | alice | /src/secret/... | Write | Deny (All Above) | When Alice tries to access `/src/secret/config.json`: 1. Rule 2 matches first (bottom, highest priority) - stops evaluation and denies all access 2. Rule 1 is never evaluated 3. **Result: Alice has no access** to files in `/src/secret/` **Deny (All Above)** is a terminal rule. When it matches, evaluation stops immediately - no more rules above it are checked. Any permissions already granted by higher-priority rules (lower in the table) are kept. You can reorder rules in the UI by dragging them to change their priority. ## Assigning Permissions Permissions can be assigned to: * **Individual users** - Apply rules to specific team members * **Groups** - Apply rules to all members of a group (requires an organization). Prefer groups over individual users - it keeps permissions easier to maintain as your team grows. Each rule must target either a user or a group, not both. Create separate rules if you need to apply the same pattern to both. ## Setting Up Granular Permissions Click your **profile avatar** in the top navigation and select **Your profile**. Select **Permission Rules** under the Repositories section in the sidebar. Select the repository you want to configure. Click "Edit Table" to enable editing mode. Granular permissions table showing rule list Click "Add Rule" and configure: * **User or Group**: Who this rule applies to * **Path Pattern**: Which files are affected * **Access Level**: Admin, Write, Merge, or Read * **Permission Type**: How to apply the access level Adding a new permission rule You can reorder rules by dragging them (rules at the bottom have higher priority), edit any field, or delete rules you no longer need. ## Evaluation Logic When a user tries to access a file: 1. Find all rules matching the file path for the user (including their groups) 2. Evaluate rules from bottom to top (highest priority first) 3. For each rule: * If **Deny (All Above)** matches the requested level: Stop evaluating (previously granted permissions are kept) * If **Deny (Exact)** matches exactly: Mark exact level as denied, continue evaluating * If **Allow (Hierarchical)** or **Allow (Exact)** matches: Mark as granted, continue 4. Final decision: The highest granted permission wins, unless a deny was recorded **Default behavior:** * If there are **no granular permission rules** in the repository, users get their repository-level permission. * Once **any rule exists** for any user, users without matching rules are **denied all access**. Make sure to add rules for all users who need access. ## API Access You can manage granular permissions programmatically using the [Granular Permissions API](/api-reference/repository-granular-permissions/list-granular-permissions). # Import from Git Source: https://docs.diversion.dev/basic/import-from-git How to get an existing repo from Git into Diversion Importing an existing repo from Git can get you quickly up and running with Diversion. You can also enable bi-directional sync between your Git repo and Diversion, so that changes made in either place are reflected in the other. This is a great way to take Diversion for a test drive with no commitment. To import a repo using the Web UI, follow these steps: Go to the [Diversion Sync GitHub App page](https://github.com/apps/diversion-sync) and follow the instructions to install it. Go to [your Dashboard](https://app.diversion.dev/dashboard), open the repo selector dropdown (top-left), and choose **Import Git repository** from its footer (alongside **Create new repository** and **Import from Perforce**). Import repo button Import repo options modal Choose whether you want to import your entire repo and keep all of its history, or just the latest commit from a specific branch. If you choose to `Import all branches with history`, you'll have the option to `Enable continuous bi-directional sync`. If you need bi-directional sync, please contact us at [support@diversion.dev](mailto:support@diversion.dev). This happens in the background, and depending on the size of your Git repo can take a few minutes. You will receive an email when the import is complete. To import a repo using the CLI, follow these steps: Go to the [Diversion Sync GitHub App page](https://github.com/apps/diversion-sync) and follow the instructions to install it. Open your terminal of choice. If you want an interactive shell with nicer UI, open your terminal of choice and run the `dv` command. It works the same as your regular terminal, and you can use any of the `dv` commands (`commit`, `init`, etc...) directly without prefacing them with `dv`. Run the following command: ```bash theme={null} dv import [git_url] ``` This will start importing your repo into Diversion with the default name - the same as the repo's name in Git. There are several optional arguments for the `import` command. You can always run `dv help import` to see them in the terminal. Passing a repo name to the `import command` will save the repo to Diversion with that name, instead of the repo's name in Git. ```bash theme={null} dv import [git_url] [repo-name] ``` Enables bi-directional sync between your new Diverson repo and your Git repo. This means that any change you make to one repo will be reflected in the other. This is useful for testing Diversion or for keeping any Git-based pipelines you have in place. ```bash theme={null} dv import [git_url] --with-sync ``` If you need bi-directional sync, please contact us at [support@diversion.dev](mailto:support@diversion.dev). By default, Diversion will import the latest commit from the default branch of your Git repo. If you want to import the latest commit from a different branch, you can use the `--git-branch` flag. ```bash theme={null} dv import [git_url] --git-branch [branch-name] ``` By default, Diversion will only import the latest commit from the default branch of your Git repo. If you want to import the entire repo with all of its history, you can use the `--with-history` flag. ```bash theme={null} dv import [git_url] --with-history ``` This happens in the background, and depending on the size of your Git repo can take a few minutes. You will receive an email when the import is complete. # Import from Git LFS Source: https://docs.diversion.dev/basic/import-from-git-lfs How to get an existing repo that uses Git LFS into Diversion Importing an existing repo from Git with LFS configured is very similar to importing a regular Git repo, with a few small differences that will be explained below. ## Importing a Git LFS repo The basic steps to import a Git LFS repo are the same as importing a regular Git repo. See the [Import from Git](/basic/import-from-git) page for more information. ## Considerations for Git LFS When importing a Git LFS repo, there are a few things to keep in mind: ### Supported storage backend Diversion currently only supports Github as a storage backend for Git LFS. If your files are hosted on a different Git LFS storage backend, please [contact us](https://www.diversion.dev/contact-us), drop in our [Discord server](https://discord.com/invite/HDAGJvgkuT) or [email us](mailto:hi@diversion.dev). ### Export to Git LFS When bidirectional sync is turned on, all files will be pushed to your Git repo, including files that are configured to be stored in Git LFS. This means that if you have a large number of files in your Diversion repo, you might hit the storage limits of your Git repo provider. To avoid this, consider importing without bidirectional sync. ### Cost considerations for initial import When importing a Git LFS repo, the files in the LFS storage will be downloaded to your Diversion repo. This might be counted against your LFS bandwidth quota, depending on your Git LFS storage provider. ### Cost considerations for bidirectional sync If you choose to continuously sync your Diversion repo with your Git LFS repo, keep in mind that your Git storage costs might increase, as you add more files to your Diversion repo. Consult with your Git repo provider's pricing for cost estimation. To minimize costs, consider disabling bidirectional sync. ### Performance considerations for bidirectional sync There is a key difference between how Diversion works and how Git LFS works. Diversion continuously syncs your files to the cloud, while Git uploads files only when you push changes. This means that if you have a large number of files to commit in your Diversion repo, with bidirectional sync turned OFF the operation is usually instantaneous - the files are usually already in the cloud by the time you commit them. With bidirectional sync turned ON, the files will have to be pushed to your Git repo first, which might take a while. This is a server-to-server operation, so it might still be faster than pushing the files from your local machine, but it's something to keep in mind. # Invoices and billing Source: https://docs.diversion.dev/basic/invoices Access your invoices, update payment methods, and manage your subscription All billing and invoicing in Diversion is managed through our billing portal. From there you can view and download invoices, update your payment method, and adjust your subscription. Only organization owners can access the billing portal. If you're a team member, ask your organization owner for invoice copies. ## Accessing the billing portal Click on your avatar in the top navigation and select **Plan & Billing**. Plan and Billing menu option in the user dropdown You'll be redirected to the billing portal where you can: * View and download past invoices and receipts * Update your payment method * View your current subscription details * Adjust user seats and storage The billing portal showing invoices and subscription details ## Downloading an invoice In the billing portal, locate the invoice you need in the invoice history section. Click on the invoice to view its details, then use the download or print option to save a copy. Downloading an invoice from the billing portal ## Managing your payment methods In the billing portal, find the payment method section and click **Add payment method** to add your credit card or other payment method. You cannot remove your default payment method while you have an active plan. To change it, add a new payment method and set it as default first, then remove the old one. ## Canceling your subscription Click on your avatar in the top navigation and select **Plan & Billing** to open the billing portal. Plan and Billing menu option in the user dropdown Under **Current subscription**, click **Cancel subscription**. The Cancel subscription button in the billing portal Cancellation takes effect at the end of your current billing period, so you keep access to your plan until then. You can re-subscribe at any time from **Plan & Billing**. ## Need help? If you have questions about billing, need a refund, or require a custom invoice, [contact our billing team](mailto:billing@diversion.dev). For information about available plans and pricing, see [choosing your plan](/choosing-your-plan) or visit our [pricing page](https://www.diversion.dev/pricing). # Manage project access Source: https://docs.diversion.dev/basic/manage-project-access Manage repo collaborators: add, remove, and leave repositories ## Add people to your project You have a project set up, and want to add your team members? Here's how: Open the repository's **...** menu - in its row on either the **Local Workspaces** or **Remote Repositories** tab of the dashboard, or from the open repository's actions menu - and select **Collaborators**. Open the repo menu If you don't have a repo yet, [create one first](/basic/start-using-diversion). Also choose the access level you want to grant. Admins can invite other members. Enter email That's it! Your team members will receive invitation emails to join the project. If they don't have Diversion installed yet, they'll be prompted to do so. They can accept the invitation and start working with you. The repo appears on the **Remote Repositories** tab in the app -- they open its `...` menu and select `Clone repo` to get started. If they need any help, [send them here](/basic/get-existing-project). ## Remove people from your project Open the repository's **...** menu - in its row on either the **Local Workspaces** or **Remote Repositories** tab of the dashboard, or from the open repository's actions menu - and select **Collaborators**. Open the repo menu Click on the user's permission level and select **Delete**. Remove user from repo Only repo owners and admins can remove members. The repo owner cannot be removed. Review and confirm your action. Confirm removal of a user from repo **Good to know:** * Removing a member from a repo doesn't remove them from the organization (if applicable) * You can re-invite removed members at any time * Removed members will immediately lose access to the repo and its contents * Their local files on disk are not deleted ## Leave a repository **Good to know:** * Leaving a repo doesn't remove you from the organization (if applicable) * You can be re-invited at any time * You will immediately lose access to the repo and its contents upon leaving * Your local files on disk are not deleted * You cannot leave a repo you own There are two ways to leave a repository: ### Option 1: From the repository's collaborators dialog Open the repository's **...** menu - in its row on either the **Local Workspaces** or **Remote Repositories** tab of the dashboard, or from the open repository's actions menu - and select **Collaborators**. Open the repo menu Click on your permission level and select **Delete**. Remove user from repo Confirm leaving a repo ### Option 2: From the remote repo Leave repo from the remote repo Review and confirm your action. Confirm leaving a repo ## Transfer repository ownership To transfer repository ownership, the repository must be associated with an organization. For detailed instructions, see [transferring repository ownership](/basic/organization-management#transferring-repository-ownership) within the same organization, or [transferring a repository to another organization](/basic/organization-management#transferring-a-repository-to-another-organization) across organizations. ## FAQs ### Why am I receiving system messages about exceeding my user limit when my repository has fewer users? If you're seeing [system messages](/system-messages) like this: User Plan Limit Notification Even after removing excess users from all your repositories, check your organization members. The excess users may still be part of your organization and need to be removed there as well. See [removing users from your organization](/basic/organization-management#removing-users) for detailed instructions. # Organization management Source: https://docs.diversion.dev/basic/organization-management Managing your organization, its members, and repositories In Diversion, an organization is a group of users who share repositories, making it easier to collaborate and manage projects. You can find your organizations under `Your organizations` in the user menu. Profile button ## Creating an organization You can only create one organization per account, but you can be a member of many organizations. ### Creating your first organization **If you don't own or belong to any organization:** 1. Click on your avatar in the top navigation and select `Create organization`. Create org from profile 2. Choose a name for your organization and click `Create organization`. Create organization page **If you already belong to one or more organizations:** Create the new organization from the New Repository dialog: click the `Parent organization` dropdown and select `+ Create New Organization`, then enter your organization name. See [Creating an organization while creating a repository](#creating-an-organization-while-creating-a-repository) below. ### Creating an organization while creating a repository Alternatively, you can create an organization while creating a new repository: 1. When creating a new repository, click the `Parent organization` dropdown and select `+ Create New Organization`. 2. Enter your organization name to create both the repository and organization simultaneously. Create org from repo **Note:** As an organization owner, you are responsible for all billing, including storage usage and organization member seats. When you upgrade to a paid tier, an organization may be created automatically for you depending on your tier (Indie/Educational/Professional). ## Managing an organization Each organization has an owner. The owner can invite other users to join the organization. When you add a user to your organization, they won't have access to all of your repositories and you can still manage access on a per-repo basis. When inviting a user, the owner can decide if the user should have admin privileges. Admins can also manage users, same as the owner. The difference between the owner and an admin is that billing for the organization is managed through the owner's Diversion account. Invite user modal window If you send an invite to someone who doesn't have a Diversion account, they will be prompted to create one. ### Removing users The owner or admins can also remove users from the organization. When removing a user, you'll be prompted with the list of repositories the user can access. These are all of the repositories that the user will no longer have access to. This means that the Diversion agent will no longer sync these repositories with the user's workspace. This also means that the user will keep stale copies of the repositories that were previously cloned locally. Remove user confirmation modal window Removing a user that owns repositories is currently not supported through the app. You'll have to contact support to transfer ownership of those repositories before removing the user. Unable to remove user who owns repos ## Working in an organization Every repository belongs to an organization. When you create a new repository, you set its `Parent organization` in the create dialog: if you belong to a single organization it is used automatically, and if you belong to more than one you choose which one to use. If you don't belong to any organization yet, a personal organization is created for you automatically and the repository is placed in it. This ensures that all repositories are properly organized and accessible to the relevant team members. Other than that, working as part of an organization is exactly the same as working as an individual user. ## Attaching a repository to an organization If you own a repository that isn't part of any organization, you can attach it to an organization you own at any time, directly from the dashboard, without contacting support. (New repositories are always created within an organization, so this applies to older repositories that predate that behavior.) The `Attach to Organization` action is available when all of the following are true: * You are the **owner** of the repository. * The repository is **not** already part of an organization. On your dashboard, open the **Remote Repositories** tab and look under **Personal** -- repositories that aren't part of an organization appear there, not under **Local Workspaces**. Find the repository's row, click its **...** menu, and select `Attach to Organization`. Attach to Organization menu item on a repository row In the `Attach Repository to Organization` dialog, choose the destination organization from the `Select Organization` dropdown. Only organizations you own are listed. The dialog then previews which repository collaborators (and pending invitees) are not yet members of the selected organization. Attaching the repository will add them as members of the organization, counting toward its user quota. If everyone is already a member, the dialog confirms that no users will be added. Attach Repository to Organization dialog with the organization selected and a preview of users to be added Click `Attach to Organization` (or `Attach and Add N Users` when collaborators will be added) to complete the action. The repository, along with its storage usage, now belongs to the organization. You must be the owner of an organization to attach a repository to it. If you don't own any organization, [create one first](#creating-an-organization). ## Organization repository management Organization owners and admins can view and manage all repositories associated with the organization, including repositories they are not personally collaborating on. This includes managing collaborators and transferring ownership. ### Viewing organization repositories Click on your avatar in the top navigation and select `Your organizations`. The organization whose settings you see is controlled by the organization selector in the top-left of the global bar; use it to pick the organization you want. Profile button In the left sidebar, click `Repositories` to view all repositories in the organization. Organization repositories sidebar navigation You will see a table listing all repositories in the organization, including their name, creation date, size, auto-update status, and collaborators. As an organization owner or admin, you can see repositories that you are not personally collaborating on. Organization repositories table If you belong to multiple organizations, use the organization selector in the top-left of the global bar to switch between organizations. ### Managing repository collaborators Organization owners and admins can manage collaborators for any repository in the organization, even if they are not a collaborator on that repository themselves. Go to your organization's Repositories page as described above. Find the desired repository in the table and click the menu icon on the right side. Repository actions menu Click `Manage Collaborators` to open the collaborators dialog. Manage collaborators dialog From the collaborators dialog, you can: * View all current collaborators and their permission levels * Invite new collaborators by entering their email address and selecting an access level * Change a collaborator's permission level * Remove a collaborator from the repository * Add yourself to the repository by entering your own email address — even if you're not currently a collaborator on that repo ### Transferring repository ownership You can transfer repository ownership to another member of the organization. The user performing the transfer must be both the repository owner and an organization admin or owner. Go to the `Repositories` page in your organization page (accessible from the left sidebar). Repositories page Find the desired repository. Click on the menu icon on the right side and select `Transfer ownership`. Transfer ownership Choose the member you wish to transfer ownership to from the dropdown and confirm the transfer. This action cannot be undone. The new owner will have full control over the repository, and you will lose ownership privileges. ### Transferring a repository to another organization You can transfer a repository from your organization to another organization. Only the **owner of the source organization** can initiate the transfer. The destination organization owner must approve the request before the repository moves. If you are a repository owner but not the source organization's owner, ask your organization owner to initiate the transfer on your behalf. Open the source organization's `Repositories` page. If you belong to multiple organizations, use the organization selector in the top-left of the global bar to switch to the source organization first. Find the desired repository, click the menu icon on the right side, and select `Transfer Organization`. Transfer Organization menu item Type the email address of the destination organization's owner and click `Send Request`. A transfer request is sent to that email and appears on the destination owner's dashboard. Transfer request dialog The destination organization owner has **14 days** to accept or decline the request. You will be notified by email when they respond. If the request is not approved within 14 days, it expires automatically and the repository remains in your organization. Transfer request sent confirmation This action is irreversible. Once accepted, the repository is permanently moved out of your organization. All repository members who are not already members of the destination organization will be added to it — counting toward the destination organization's user quota — and the repository's storage will count toward the destination organization's storage quota. If you need to remove a repository from your organization but there is no destination organization to send it to — for example, the repository's owner is no longer active and you simply want the repository gone — [contact support](mailto:support@diversion.dev). #### Reviewing an incoming transfer request If another organization's owner sends you a transfer request, you will be notified by email and an `Incoming repository transfer` card will appear on your dashboard. Find the `Transfer of [repository name]` card in the pending invites section of your dashboard and click `Review...`. Incoming transfer request card on the dashboard The review dialog shows the source organization, the repository's storage size, the members that will be added to your organization, and when the request expires. Review repository transfer dialog Click `Accept Transfer` to move the repository into your organization, or `Decline` to reject the request. The initiator is notified by email either way. Transfer requests expire after 14 days. Expired requests cannot be accepted — the source organization owner must send a new request. ## Leaving an organization Only non-owner members can leave an organization. Switch to the organization you wish to leave using the organization selector in the top-left of the global bar, then open its settings and click "Leave organization". **Note:** Leaving an organization will result in losing access to all repositories associated with it. You can always be invited back to the organization later. Access to org repos will be lost after leaving an org If you own one or more repositories that are associated with the organization, you won't be able to leave the organization. You must either [transfer the repository ownership](#transferring-repository-ownership) to another member of the organization or delete the repositories first. ## Organization deletion Deleting an organization is not possible. If you no longer need an organization, you can remove all members and repositories from it. ## FAQs ### What happens to my repositories if I'm a member of multiple organizations? Every repository is created within an organization. If you belong to more than one organization, you choose its `Parent organization` in the create dialog; if you belong to a single organization, that one is used; and if you don't belong to any, a personal organization is created for you automatically. A repository is therefore never left unassigned at creation time. Older repositories that aren't part of any organization can be [attached to one](#attaching-a-repository-to-an-organization) you own. ### How do I transfer organization ownership to another user? Ownership transfer is currently handled by our support team. If you're an organization owner and want to transfer ownership: 1. Ensure the new owner is already a member of your organization. If not, invite them first as explained above. 2. Email our support team with your request, including the new owner's email address, and our team will complete the transfer. 3. The new owner should select their desired tier, storage capacity, and seats, then add a payment method to avoid subscription breach [system messages](/system-messages). 4. Once the new owner has set up their subscription, cancel your old subscription from **Plan & Billing** to avoid double payment. ### How do I become the owner of an organization I am a member of? Ask your organization owner to contact our support team and request the ownership transfer to your account. The owner should follow the steps outlined in the question above. ### Why am I receiving system messages about exceeding my user limit? If you're seeing [system messages](/system-messages) like this: User Plan Owner Notification This means your organization has more members than your current plan allows. To resolve this, you have two options: 1. **Upgrade your plan** - Purchase additional user seats to accommodate your current team size. 2. **Remove users from your organization** - See the [removing users](#removing-users) section above for step-by-step instructions. If you're seeing [system messages](/system-messages) like this: Trial Ended Notification This means you haven't selected a plan yet. To resolve this: **Select a plan** - See [choosing your plan](/choosing-your-plan) for guidance, or visit our [pricing page](https://www.diversion.dev/pricing) to view available options. ### How do I move repositories out of my organization? As the organization's owner, you can transfer any repository in your organization — even ones you don't personally own or collaborate on — using the [Transfer Organization](#transferring-a-repository-to-another-organization) action. Send each request to the email of the owner of the destination organization. ### How do I move my repositories from another organization to my own? Ask the current organization's owner to use the [Transfer Organization](#transferring-a-repository-to-another-organization) action on the repository and submit the request to your email address. Once you accept the request from your dashboard, the repository moves into your organization. # Repository management Source: https://docs.diversion.dev/basic/repo-management Rename, delete, and manage your Diversion repositories and workspaces ## Renaming a repository Only the repository owner can rename a repository. Go to the **Remote Repositories** tab on the dashboard (not from a local workspace). Locate the repository you want to rename. Click the **...** menu on the repo's row and select **Rename**. Rename option in repo row menu In the **Rename Repository** dialog, type the new name for your repository and click **Rename**. Rename repository dialog ## Deleting a repository Deleting a repository is permanent and cannot be undone. All branches, commits, and history will be lost. Go to the **Remote Repositories** tab on the dashboard (not from a local workspace). Locate the repository you want to delete. Click the **...** menu on the repo's row and select **Delete**. Delete option in repo row menu To prevent accidental deletion, you must type the exact repository name to confirm. Then click **Delete**. Delete repository confirmation dialog Via the CLI, run `dv repo -d `. See the [repo command](/cmd-ref/repo) for details. Your local files on disk are not deleted -- only the cloud repository is removed. The local folder stops syncing and can be moved or deleted manually. ## Viewing workspaces If you are an owner or admin of a repository, you can view and manage all workspaces in that repository, including those belonging to other collaborators. This is useful for debugging issues or managing changes on behalf of a team member. Click on your avatar in the top navigation and select **Your profile**. In the left sidebar under **Repositories**, click **Workspaces**. If you are an owner or admin of multiple repositories, use the repository selector dropdown to pick the repository you want to inspect. Workspaces list showing all workspaces The table lists all workspaces with their name, auto-update status, and owner. Click the actions menu on a workspace and select **Open** to view its contents and pending changes. You can also **Rename** or **Delete** workspaces from this menu. Opening a workspace When you open a workspace you don't own, any operations you perform will affect the workspace owner. A confirmation dialog will appear before you proceed. # Reviews Source: https://docs.diversion.dev/basic/reviews Code reviews in Diversion ## What are Reviews? Code reviews in Diversion let you request feedback on your changes before merging them into your main branch. Team members can review your code, leave comments, approve changes, or request modifications. ## How Reviews Work A review compares two refs (branches or commits) in your repository: * Base ref: The target where changes will be merged (usually main) * Compare ref: The branch or commit containing your changes When you create a review, Diversion calculates the differences between these two refs and presents them to your team for feedback. ## Creating a Review There are two ways to create a review in Diversion: ### Method 1: Create Review from Branch (Most Common) Use this when you want to compare two branches and get feedback before merging. **Step-by-Step Instructions:** 1. **Navigate to Reviews section** * Open your repository in Diversion web app * Click on the **"Reviews"** icon in the left navigation rail Click Reviews in the left navigation rail 2. **Click "Create new review" button** Click Create new review button 3. **Select branches to compare** * **Base branch**: Select the branch you want to merge INTO (usually main) * Click the dropdown under "Base branch" * Choose your target branch (e.g., `master`, `main`, `develop`) * **Compare branch**: Select the branch WITH your changes * Click the dropdown under "Compare branch", or start typing to search for a branch * Choose your feature branch (e.g., `feature/user-dashboard`) 4. **Fill in review details** * **Title** (required): Short description of your changes * Example: "Add user authentication system" * **Description** (optional): Detailed explanation * Explain WHY you made these changes * Mention any important context 5. **Add reviewers** (optional) * Click the "Reviewers" dropdown * Select one or more teammates who should review your changes * You can skip this and add reviewers later 6. **Click "Create review"** * The review will be created immediately * Assigned reviewers will receive email notifications * You'll be taken to the review page Review form before submitting ### Method 2: Create Review from Merge Dialog Use this when you're ready to merge but need approval first **Step-by-Step Instructions:** 1. **Navigate to the branch you want to merge** * Go to the **"Branches"** section in Diversion web app * Find your feature branch (the one WITH your changes) in the Branches list * Click on that branch and choose the merge direction * Notes: You cannot merge the branch you're currently on. You must click on a different branch to see merge options Click on that branch and choose the merge direction 2. **Choose "Create review request"** * A dialog appears asking how you want to proceed * You'll see several options, including: * **"Create review request"**: Request review before merging * **"Preview merge"**: See merge diff without creating review * (The dialog also offers **"Merge now"** and **"Cancel"**.) * Click **"Create review request"** Create review request * If a review already exists for these branches, click "Go to review requests" Go to review request 3. **Fill in review details** * If a review already exists for these branches, it will take you there * Otherwise, you'll see the review creation form * The base and compare branches are already filled in * Add title, description, and reviewers * Click **"Create review"** ### What You Need for All Methods Every review requires: * **Base branch**: Where you want to merge your changes (e.g., `master`) * **Compare branch**: The branch with your changes * **Title**: A clear, concise description (required) * **Description**: More detailed explanation (optional but recommended) * **Reviewers**: Teammates who should review (optional, can add later) ## Reviewing Someone's Changes ### When You're Asked to Review You'll get an email notification when someone requests your review. **Step-by-Step Instructions:** 1. **Open the review** * Click the link in your email notification, OR * Go to Diversion web app → **"Reviews"** section Reviews section in the left navigation rail * Find the review in the list (you'll see your name as a reviewer) * You can filter reviews by status (Open, Closed) and by whether they're your reviews Review list * Click on the review to open 2. **Look at the review details** * At the top, you'll see: * Review title and description * Who created the review * Which branches/commits are being compared * Current status and other reviewers 3. **Review the changes** * You'll see two tabs: * **"Conversation"**: Shows all comments and discussion * **"Files Changed"**: Shows the code diff * Click **"Files Changed"** to see what code changed Files changed tab showing code diff 4. **Leave comments** (explained below) * Add general comments about the overall changes * Add inline comments on specific lines of code Conversation tab with comments 5. **Make your decision** * Go to the **"Files Changed"** tab * Click **"Review changes"** Review changes * Choose one of these options: * **"Approve"**: Changes look good, ready to merge * **"Request Changes"**: Something needs to be fixed Review actions * Add an optional comment to explain your decision * Click the **"Submit review"** to submit your decision 6. **Done!** * The review author receives notification of your decision * Your review status will be updated and appear both in the conversation and on your avatar under the "Reviewers" section ### Adding Comments #### General Comments Use general comments for big-picture feedback about the whole review. **How to add a general comment:** 1. Open the review page 2. Go to the **"Conversation"** tab 3. Scroll to the comment box at the bottom 4. Type your comment 5. Click **"Comment"** button **How to reply to a comment:** 1. Find the comment you want to reply to in the **"Conversation"** tab 2. Type your response 3. Click **"Reply"** to post your reply Adding and replying to comments **Examples of general comments:** * "The overall approach looks great!" * "Have you considered how this handles edge cases?" * "This needs unit tests before we can merge" * "Great work on the error handling!" #### Inline Comments Use inline comments to point out specific issues in particular lines of code. **How to add an inline comment:** 1. Open the review page 2. Go to the **"Files Changed"** tab 3. Find the file you want to comment on 4. **Click the line number** in the diff view 5. A comment box appears on the right side of the screen 6. Type your comment about that specific line 7. Click **"Comment"** button **How to add a file-level comment:** 1. Open the review page 2. Go to the **"Files Changed"** tab 3. Find the file you want to comment on 4. Click the **"+"** button above the changed version of the file 5. A comment box appears on the right side of the screen 6. Type your comment about the entire file 7. Click **"Comment"** button Adding inline and file-level comments **Examples of inline comments:** * "This function should handle the case where user is null" * "Consider using a constant here instead of magic number" * "Great improvement over the previous version!" * "This could cause a race condition if called concurrently" ### Viewing Review Status **Your status as a reviewer:** * **REQUESTED**: You haven't responded yet - review is waiting for you * **APPROVED**: You approved the changes * **CHANGES REQUESTED**: You requested modifications **The review's overall status:** * **OPEN** (blue): Review is active, may still need approvals * **MERGED** (purple): Changes were approved and merged * **CLOSED** (gray): Review was closed without merging Review status indicators ## Editing Review Details After creating a review, you can edit the title and description by clicking the pencil icon next to them, or edit reviewers by clicking the settings icon next to the reviewers section. ## Working with Review Feedback ### When Changes Are Requested 1. Read through all the comments carefully 2. Make the requested changes on your branch 3. Commit the fixes (they'll automatically show up in the review) 4. Reply to comments to explain what you changed 5. Ask reviewers to take another look ### Updating Your Branch If you're using a branch review, any new commits you push will automatically appear in the review. Reviewers will see: * All your original changes * Any new commits you added to address feedback * The complete, updated diff ### When You Get Approvals Once all reviewers have approved (or enough approvals based on your team's policy): 1. Do a final check that everything looks good 2. Click the **"Merge review"** button on the review page to merge the changes 3. The review status will automatically change to MERGED ## Notifications You'll get email notifications for: * When someone requests your review * When someone comments on your review * When reviewers approve or request changes * When a review is merged or closed All notifications include a link to view the review in Diversion. # Shelves Source: https://docs.diversion.dev/basic/shelves Save workspace changes temporarily and manage your shelves In Diversion, you can shelve your current work and apply it later when switching back to the original branch. This works similarly to the "stash" mechanism in Git. ## When to use shelves * **Switching context:** Save work-in-progress before switching to another branch * **Experimenting:** Try out changes without committing, easily revert if the experiment doesn't work * **Working across machines:** Shelve changes on one computer and apply them on another. Shelves are stored in the cloud per repository, so they are available from any workspace on the same repo. ## Creating a shelf Use the shelf button in your workspace to create a shelf. 1. Select the files you want to shelve in your workspace 2. Click **Shelve...** to open the naming dialog: shelf button 3. [Name](#naming-your-shelf) your shelf 4. Click **Create shelf** ### Automatic shelves When switching branches with uncommitted changes, a popup menu will ask what to do with them. uncommitted changes branch switch menu Select **Save changes for later use** to create an automatic shelf. ### Naming your shelf When creating a shelf, you can: * Enter a custom name (max 60 characters) * Click **Generate name** generate name button to create a name like `my_branch (2025-01-13 13:00:00)` Shelf names must be unique within your repository. ## Managing shelves Open the branch selector and switch to the **Shelves** tab to view and manage your shelves. shelves list ### Preview Click on a shelf to preview its contents before applying. ### Apply Click **Apply** to restore the shelved changes to your workspace. If the shelved changes conflict with your current workspace, you'll need to resolve the conflicts before continuing. ### Rename Click **Rename** to change the shelf name. ### Delete Click **Delete** to permanently remove a shelf. This action cannot be undone. *** For CLI usage, see the [shelf](../cmd-ref/shelf) command reference. # Start using Diversion in your project Source: https://docs.diversion.dev/basic/start-using-diversion Create a new Diversion repo for a completely new project or an existing one You're working on a project. How exciting! What you want is a Diversion repository. Let's get you set up: You can do this with [our Unreal Engine plugin](/unreal/unreal-engine-plugin)! In the desktop app, click on the `New repository` button on the top right. Initialize a new repo You can create a new folder or use an existing one. If you have a game-engine project, you probably want to choose its root folder. For this example I'll create a new folder, but the other steps work the same either way. I'll select `Create New Folder`and call it `CreatingNewRepo`. Create a folder for the repo A new repo is created in the folder you specified! The workspace's **Sync** toggle shows it's syncing - the status text reads something like "Syncing: Scan in progress" while it uploads the folder's content to our cloud. In this example it's an empty folder so it should only take a moment. If you create a new repo for an existing project, it might take a bit longer. Repo is still syncing Once the sync status shows the workspace is fully synced, you're all set! Repo is ready And that's it! You have a new repository. Anything you do in the directory will be tracked by Diversion. If there are files you don't want tracked (e.g. build artifacts, temporary files), you can use a [.dvignore file](/basic/dvignore) to exclude them. ## What's next? * [Manage project access](/basic/manage-project-access) — invite collaborators to your repo # Pause/Resume sync Source: https://docs.diversion.dev/basic/sync-pause-resume Pause and resume your background sync Diversion's agent keeps you up to date with the latest changes in your repos by syncing them in the background. Whenever you save a change, it's automatically uploaded to your workspace and you're always backed-up. ### Auto-pause In some error cases, such as network issues, the agent will automatically pause syncing. You can continue working normally. When committing, make sure your sync is active so you commit the most recent changes. To resume the sync through the desktop app, turn the **Sync** toggle back on for the workspace -- on its row in the dashboard's **Local Workspaces** tab, or via the sync status pill in the repo sub-header ("Sync paused / click here to resume"). You can also run the `dv workspace resume` command in the repo's folder through the CLI. Resume sync ### Manual Pause/Resume You might not want to be auto-synced, for example if you're making many small changes in a very large file, or if you're on a slow network connection. In order to pause sync for a workspace, you first need to have it fully synced, like in the image below. Turn off the **Sync** toggle on the workspace row to pause. Resuming the sync is done in the same way mentioned above. Pause sync # Undo pending changes Source: https://docs.diversion.dev/basic/undo-pending-changes Undo changes you haven't committed yet Changed your mind? Are you unhappy with your most recent work? Let's undo changes you haven't committed yet. In Diversion, this is called `reset`, and will return the files to state they were in the last commit. Open the workspace of the repo where your changes are. In the **Files** view, you'll see a list of files with changes. Use the checkboxes next to the files, or can select all with the checkbox at the top. Once you have selected the files, click the red **Reset** button at the top right of the file list. Changes to undo You'll see a confirmation dialog. Keep in mind that by default, this only undoes changes to existing files and does not delete new files. If you want to delete new files, click on the "Delete new files" checkbox. Changes to undo modal # What to do with your changes Source: https://docs.diversion.dev/basic/what-to-do-with-your-changes Commit or reset changes in your repo You've made some changes to your project - created new files, modified existing ones, or deleted some. Now what? You can do this with [our Unreal Engine plugin](/unreal/unreal-engine-plugin)! ## Review your changes In the desktop app, go to your repo. In the **Files** view, you should see the files you've changed. View changes in workspace Each change is marked with an icon and a color. You can always hover over the icon to see what change was made - added, modified, deleted, or moved (which includes renaming). The buttons on the top let you change the way you see your list of changes. Choose one you like. Change view buttons When you click on a file you changed, if it's in a supported format, it will open in the main panel. Right now Diversion supports text files and images. Use the button on the top to switch to `Diff View` to see the changes you made. Diff view in the main panel ## Commit your changes If you like your changes and want to keep them, you should `Commit` them. A commit is like a snapshot of your project at a certain point in time. It's an encapsulated unit of change in your repository. When you commit your changes, any collaborators you have in your project will be able to see them. If your collaborators are on the same branch as your are, assuming they have no conflicting changes, the changes you commit will be automatically synced to their workspaces. For more info, check out the [Branches](/concepts/repo-branch-workspace) page. To commit your changes, choose which files you want to include in the commit, write an informative commit message, and click `Commit`. You can choose to commit all changes, using the checkbox above the list, or only some of them. Choose files to commit You should try to keep your commits small and focused, and your commit messages should be descriptive and informative. Remember, even if you're working alone - Future You will thank you for it. When you're ready, hit the commit button! Your changes are now saved in your repository. The `Commit...` button also has a split dropdown that offers `Send to review...` and `Shelve...` if you'd rather request feedback or set the changes aside instead. ## Undo your changes If you don't like your changes and want to undo them, you can `Reset` them. This will revert the files to the state they were in when you last committed them. You can reset files using the red `Reset` button on the top right. Using this method you can reset multiple files at once. Reset files with the red button Alternatively, you can reset individual files using the file's context menu. Reset individual files with the context menu By default, when resetting changes, any new files you've added won't be deleted. If you want to delete new files, make sure to check the `Delete new files` checkbox in the confirmation dialog. Discard new files when resetting # Working in parallel Source: https://docs.diversion.dev/basic/working-in-parallel Branching and merging You want to work on a project with your team, but you don't want to step on each other's toes. No worries! There's a way to work on your project in parallel without interfering with each other's work, and then recombine it all together when you're done. It's called branching and merging. ## Branching You can think of a branch as a separate version of your project. When you create a branch, you're creating a copy of your project at that point in time. ### Creating a new branch In the Desktop App: Open the branch selector at the top-left of the repo view and click **+ New branch**. The new branch button Give your branch a name that describes what you're working on. Also, pay attention to the commit you're branching from - this will be the base for our new branch. You can automatically switch to the new branch after creating it by leaving the checkbox checked, it's checked by default. The new branch modal window Via the CLI, see the [branch command](/cmd-ref/branch) for creating branches and more options. ### Switching branches In the Desktop App, the branch selector at the top-left shows your current branch. Click it to see all branches in the repository under the **Branches** tab (the default branch is marked with a home icon). Clicking on another branch lets you view it in read-only mode without switching. To switch, click the menu for the branch you want and select "Switch to branch". Switch branch If you have any changes in your workspace that you haven't committed, you can choose to discard them, [shelve](/basic/shelves) them for later, or take them with you to the new branch, if possible (see [Merge conflicts](#merge-conflicts) below). Via the CLI, see the [checkout command](/cmd-ref/checkout) for switching branches. Switching a branch changes the files on your computer. For some game engines, like Unreal Engine, you might need to restart the editor to see the changes. ### Branch graph You can see a visual graph of all your branches and commits in the Desktop App. Click **Graph** in the left navigation rail. The branch graph view The graph shows an interactive visualization of all branches and commits. You can pan and zoom to navigate around the graph. Branch graph Right-click on any commit or branch in the graph to open its context menu. From here you can access the same actions available elsewhere -- create a branch, cherry-pick a commit, merge, and more. Branch graph context menu If you have a lot of branches, this is a great way to understand how they relate to each other. ### Important things to remember 1. Working on any branch is just like working on your main branch. Making changes, committing, syncing - it's all the same. 2. Branches are visible to anyone in your repo, and anyone can switch to any branch. 3. The committed changes on the branch are only available to team members who are on the same branch. 4. There is no need to pull or fetch. When a teammate commits to a branch you're on, your workspace is updated automatically. See [syncing](/concepts/syncing) for more details on how auto-update works and how to control it. ### Managing branches #### Delete a branch If you no longer need a branch, you can delete it. Note that you cannot delete the default branch. In the Desktop App, in the branch list, right-click (or click the menu icon) on the branch you want to delete and select "Delete". Delete branch menu option **What happens when you delete the branch you're currently on?** If you delete the branch you are currently viewing, you will be redirected to the repository's main page. Any workspaces that were checked out to the deleted branch will remain in a **detached state** -- they keep their current files and uncommitted changes, but are no longer associated with any branch. To continue working, switch to another branch from the workspace. Via the CLI, see the [branch command](/cmd-ref/branch) for deleting branches and more options. #### Rename a branch You can rename a branch from the Desktop App. This is not supported for repositories synced with Git. In the branch list, right-click (or click the menu icon) on the branch you want to rename and select "Rename". Type the new name and click "Rename". Via the CLI, see the [branch command](/cmd-ref/branch) for renaming branches. #### Set the default branch The default branch is the branch that new workspaces are based on when they are created. Only admins can change the default branch, and this option is only available in the Desktop App. In the branch list, right-click (or click the menu icon) on the branch you want to set as default and select "Set as default branch". This option is only visible if you are an admin of the repository. There is no CLI equivalent for this action. ## Merging When you're done working on your branch, you can merge it back into your main branch. Merging takes all of the changes from one branch and applies them to another. ### How to merge In the Desktop App, open the branch selector, find the branch you want to merge on the **Branches** tab, and choose the merge option from its menu. Merge branches If there are no conflicts, you should see a new merge commit in your branch history. A successful merge commit Via the CLI, see the [merge command](/cmd-ref/merge) for merging branches. ### Merge conflicts Sometimes, the changes you made on your branch conflict with the changes someone else made on another branch. When you try to merge these branches together, you'll have to decide how to handle these conflicting changes. In the Desktop App, if you have conflicting changes and follow the steps in [How to merge](#how-to-merge), you'll see a screen that shows you the conflicting files instead of the successful merge commit. The merge conflict window The conflict window has 4 parts: 1. A list of files with conflicting changes. 2. For each file on the list: 1. The incoming file. This is a readonly version of the file that's on the branch you're trying to merge from. 2. The current file. This is a readonly version of the file that's on the branch you're trying to merge into. 3. The outcome file. This is what the file will look like after you resolve the conflict. This is editable. To resolve a conflict, you need to decide which changes to keep and which to discard. You can choose either the incoming version, the current version, or a combination of both. And, as mentioned above, you can edit the outcome file directly. If you want to make the same choice for many files, you can select them using their checkboxes and use the buttons at the bottom. When you're done, type a commit message and hit 'Commit'. For resolving merge conflicts via the CLI, see [Handling Merge Conflicts (CLI)](/core-concepts/branching-merging#handling-merge-conflicts). #### Merging non-text files Non-text files, like images, 3d models, spritesheets, animations, etc., can't be merged. This merge process works because text files are human-readable and can be compared line by line. If you have a merge conflict with a non-text file you have 2 options: 1. If you have a specific tool that can merge these files, you can use it to resolve the conflict. One example is [Unreal Engine's built-in merge tool](/unreal/ue-plugin-merge-conflicts) which you can use if you have [our plugin](/unreal/unreal-engine-plugin). 2. Choose one version to keep and discard the other. ### Merge conflict warning Diversion has a feature that warns you about files that are being edited by other team members, and might cause a merge conflict. If you see the merge warning icon on a file, you can click on it and get info about who's editing the file. Be sure to communicate before working on it to prevent merge conflicts. As mentioned above, this is crucial when working on non-text files. The merge warning icon #### Why is the warning icon showing on many files? The warning icon reflects files that are currently modified (uncommitted) in any workspace on the repo, not just the one you are looking at -- whether it belongs to a collaborator or is another one of your own. If you see it on a large number of files at once, the usual cause is that one of those workspaces is holding a lot of uncommitted changes. Every modified file there gets flagged for everyone on the branch. The warning does not name the workspace that holds the changes, but clicking the icon shows which user is editing the file. To track it down, that user should review each of their own [workspaces](/basic/workspace-management) for uncommitted changes, or a repository owner/admin can review all workspaces in the repo owned by that user (see [Viewing workspaces](/basic/repo-management#viewing-workspaces)). Once found, commit or revert the changes in that workspace, or delete it if it is no longer needed. # Workspace management Source: https://docs.diversion.dev/basic/workspace-management Create, rename, delete, and clone workspaces Every collaborator on a repository gets their own workspace -- a private space where you can make changes without affecting anyone else. Workspaces keep your uncommitted work separate and synced to the cloud automatically. If you're not familiar with the concept, check out the [Repositories, Branches, and Workspaces](/concepts/repo-branch-workspace) page first. We recommend using a separate workspace for each machine. Cloning the same workspace on multiple machines may lead to sync issues and data loss. ## Cloned vs. non-cloned workspaces A workspace can be either **cloned** (local) or **non-cloned** (cloud-only). Understanding the difference helps you decide how to set up your workflow. | | Cloned (local) | Non-cloned (cloud-only) | | ----------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | **Where files live** | On your machine, synced with the cloud | Only on the Diversion cloud | | **How to edit files** | Use any local editor, IDE, or game engine | Upload files through the web or desktop app | | **Auto-sync** | Changes sync bidirectionally -- local edits upload automatically, and remote changes download automatically | No local sync needed -- everything is already in the cloud | | **Show in Explorer / Finder** | Available -- opens the file's location on disk | Not available | | **Open with default app** | Available -- opens the file with your OS's associated application | Not available | | **Disk usage** | Uses local disk space for the full working copy | No local disk space used | **When to use a cloned workspace:** Most of the time. If you're actively developing -- writing code, editing assets in a game engine, or using any local tools -- you need a cloned workspace so those tools can access the files on disk. **When to use a non-cloned workspace:** When you only need to browse files, review changes, or manage branches without editing locally. This is useful for lightweight access from a machine where you don't want to download the full project, or for managing multiple workspaces without duplicating large repositories on disk. You can clone a non-cloned workspace at any time -- see [Cloning a workspace locally](#cloning-a-workspace-locally-desktop-only) below. ## Creating a new workspace In the Desktop App: Open the workspace selector at the top-right of the repo view. The new workspace button in the workspace selector This opens the **Create New Workspace** dialog. The create new workspace dialog Give your workspace a descriptive name. This is required. In the desktop app, you can also check the **Clone this workspace locally** option to immediately create a local copy. If you choose to clone, you'll need to pick a folder name and a directory on your machine. The workspace is created from the repository's default branch. Once it's ready, you'll be navigated to the new workspace automatically. For CLI usage, see [clone command](/cmd-ref/clone). ## Working from multiple computers You can work on the same project from several machines -- a desktop and a laptop, for example. Set up a separate workspace on each machine rather than sharing one. Your machines stay in sync through commits. **Uncommitted local changes stay on the machine where they were saved** -- they are not uploaded to the cloud or visible from any other computer until you commit them. Once committed, every workspace tracking that branch picks them up automatically. To move *uncommitted* work between machines without committing, use [Shelves](/basic/shelves), which are stored in the cloud and available from any workspace on the same repository. Don't share a single workspace between machines via a cloud-synced folder (Dropbox, OneDrive, iCloud, Google Drive), a network drive, or by copying the `.diversion` directory. Each machine's agent will fight over the workspace's state, which can cause files to be deleted, sync loops, or repeated `dv reset` recoveries. ### Set up a second machine Sign in with the same account you use on your primary machine. Follow the [Creating a new workspace](#creating-a-new-workspace) steps and clone it locally. Give it a name that identifies the machine (e.g., `main-laptop`) so you can tell your workspaces apart. Your new workspace syncs automatically. See [Moving work between your machines](#moving-work-between-your-machines) below for how changes travel from one machine to the other. ### Moving work between your machines Work travels between your machines through commits: * **Commit on the machine you're working on.** Only committed changes upload to the cloud, and only while sync is active -- so commit your work (`dv commit -a -m "message"` or the desktop app) and make sure sync isn't paused. * **Find the changes on the branch they were committed to.** Each commit lands on a branch, and a workspace shows only the commits on the branch it's currently on. To see changes you made on another machine, open the **branch selector** in the desktop app (or run `dv checkout `) and switch to the branch they were committed to. * **Let the workspace update.** With [auto-update](/concepts/syncing#workspace-automatic-update) on, the workspace pulls new commits automatically -- just like a teammate's workspace would. With it off, the sync status shows **Pending workspace updates** -- click it, or run `dv update`. * **Selective Sync decides what lands on disk.** A folder left unchecked under **Settings -> Selective Sync** won't download locally even when its files are committed. See [Selective Sync](/advanced/selective-sync). ## Workspaces on external storage You can keep a cloned workspace on a USB drive, external SSD, or other detachable drive that mounts as a regular local disk. This lets you carry a workspace between machines without re-cloning, as long as each machine has Diversion installed and you're signed in with the same account. When cloning, pick a folder on the external drive as the local location. With the drive connected and the Diversion agent running, the workspace syncs normally. If the workspace doesn't appear after you plug the drive back in -- or after you connect it to a different machine -- use [Attach workspace](#attaching-a-workspace-desktop-only) to point Diversion at the workspace folder on the drive. ## Renaming a workspace Click your avatar and select **Your profile** (or **Your organizations**), then under **Repositories** in the left sidebar click **Workspaces**. Find the workspace, click the actions menu at the end of its row, and select **Rename**. Workspace row actions menu with Rename option The **Rename Workspace** dialog shows the current name pre-filled. Type in the new name you'd like. The rename workspace dialog The button is disabled if the name is empty or unchanged, so make sure you've actually typed something different. You can also rename a workspace from the workspace selector on the repo view: open the selector, click the **...** (more options) menu next to the workspace, and select **Rename**. For CLI usage, see [workspace command](/cmd-ref/workspace). ## Deleting a workspace Click your avatar and select **Your profile** (or **Your organizations**), then under **Repositories** in the left sidebar click **Workspaces**. Find the workspace, click the actions menu at the end of its row, and select **Delete**. Workspace row actions menu with Delete option The **Delete Workspace** dialog asks you to confirm. Keep in mind that all uncommitted changes in the workspace will be lost. If the workspace is cloned locally, you'll see an additional warning that your local files will remain on disk but will no longer sync with Diversion. You'll need to check a confirmation checkbox before proceeding. The delete workspace confirmation dialog This action is permanent -- the workspace and any uncommitted changes are gone for good. You can also delete a workspace from the workspace selector on the repo view: open the selector, click the **...** (more options) menu next to the workspace, and select **Delete**. For CLI usage, see [workspace command](/cmd-ref/workspace). ## Cloning a workspace locally (Desktop only) If you have a workspace that isn't cloned to your machine yet, you can set up a local synced copy at any time. Open the workspace selector at the top-right of the repo view. Workspaces that aren't cloned on this machine appear under **Remote**. Select the one you want to clone locally. Workspace selector with local and remote workspaces A directory picker opens -- choose where you want the local copy to live on your machine. Diversion creates a local copy and keeps it synced automatically. Any changes you make locally will be reflected in the cloud workspace, and vice versa. For CLI usage, see [clone command](/cmd-ref/clone). ## Attaching a workspace (Desktop only) If you moved a repository to a different path on your machine, or if a workspace is not showing up after detaching a portable drive, you can re-attach it to Diversion. On the dashboard, click the **Attach workspace** button in the toolbar. Attach workspace button on the dashboard A directory picker opens. Navigate to the folder containing your workspace (the folder with a `.diversion` directory inside it). Diversion will look up the workspace on the server and reconnect it. You'll see a confirmation message once the workspace is successfully re-attached. The workspace folder contains a hidden `.diversion` directory that Diversion uses to track workspace state. This folder must remain in place and should not be modified or deleted. To verify it exists, enable hidden files in your file explorer (on Windows: View > Show > Hidden items; on macOS: press Cmd+Shift+.). If it is missing, or if the workspace was deleted from the server or you don't have permission to access it, you'll see an error message. ## Change the folder name without re-cloning You can change the folder name without re-cloning by following these steps: This is the workspace we will use for the example: Diversion Dashboard Right-click the Diversion icon in your system tray and select *Quit*, or end the dv.exe task in the Task Manager. Option a: System Tray Quit Option b: Diversion End Task Change the folder name directly in your file explorer. Rename Local Folder Run the command dv in your command line and verify it starts successfully. Alternatively, open the desktop app and click "start agent" when prompted. Option a: DV Command Prompt Verify: DV CLI Option b: Start Agent Noti Since the folder was renamed, the workspace will not be displayed. Click *Attach workspace*. Attach workspace Navigate to the path with the new folder name and click *Connect*. Connect Workspace You should now be able to see your workspace: Change Folder Finished # Choosing Your Plan Source: https://docs.diversion.dev/choosing-your-plan Choose and manage Diversion's subscription plans For detailed information about Diversion's available plans, visit our [pricing page](https://www.diversion.dev/pricing). ## How do I select a tier? You can select a tier if you haven't yet selected one and meet one of the following criteria: * You are an organization owner * You are not a member of any organization **Note:** If you are an organization member but not the owner and wish to select a tier, you can [create an organization](/basic/organization-management). ### Steps to select a tier 1. Click on your avatar and select **Plan & Billing** Plan and billing 2. Select your desired tier. For Educational and Indie tiers, you'll be directed to a form to verify your eligibility. Tier types 3. After selecting your tier, navigate back to **Plan & Billing** to add users and storage space. You'll be redirected to the billing page where you can adjust these settings. ## How do I change my tier? To change your tier, contact our [support team](mailto:support@diversion.dev) with your request: * **Professional tier:** Our support team will assist you with the upgrade process. * **Educational tier:** Provide an updated enrollment letter from your educational institution. * **Indie tier:** Provide a short description of your project along with your request. Once your request is approved, you can select the new tier following the steps above. For Indie and Educational tiers, you'll need to complete an eligibility form. ## My trial has ended, what's next? Trial Ended Notification After your trial ends, you need to select a tier. Until you do: * You and your team can continue using Professional tier features * You'll receive [system messages](/system-messages) about plan limitations * Eventually, you'll lose write access to your resources (unable to commit) To maintain full access, select a tier as soon as possible. ## I'm not the organization owner, but I keep receiving plan [system messages](/system-messages). What should I do? User Plan Limit Notification Only organization owners can select tiers and manage subscriptions. Contact your organization owner and ask them to: * Select an appropriate tier for the organization * Update the current subscription if needed ## I submitted an Indie/Educational tier application. When will it be approved? The approval process typically takes about one week. During this period: * You can use the tier you selected * Ensure all required files and information are uploaded * If your request is denied, our team will contact you within a week If you don't hear from us after a week, your request has been approved. Our team may move users to a different tier if they no longer meet the Indie/Educational terms agreed to in the form. We'll always notify you before making any changes. ## Indie form FAQ ### Company No worries — just state your current work status. For example: Unemployed, Freelance, or Part-time at \[Name of Company]. That's completely fine, just state it as-is. Your current occupation won't affect your submission or its approval. This helps us confirm the Indie plan is the right fit. It's designed for independent creators and small teams, so we use this context to keep it fair for everyone. ### LinkedIn URL No problem — you can submit a link to any social profile related to your game development project instead (e.g., Twitter/X, itch.io, GitHub, etc.). We use it to verify that the details you've provided match your profile. It's a quick check on our end to ensure everything is accurate before approving your submission. ### Game / Studio Name You can use a temporary name, or simply describe the genre of your project — for example: "1st-person roguelite shooter". Something is better than nothing! Submit "N/A" or "Solo Developer" — whichever best describes your situation. Unfortunately, your submission won't be approved. The Indie subscription is specifically for active game development projects. Video projects, "for hire" dev work, and training simulations are not eligible. ## Can I replace collaborators on Diversion without upgrading my plan? Yes, as long as the total number of collaborators stays within your plan's limits, there's no need to upgrade. Simply remove the old collaborators and add the new ones to maintain access under your current plan. # CI/CD Source: https://docs.diversion.dev/ci-cd Configure your CI/CD platform to use diversion ## Generate an API Token Click on your avatar and select *Integrations*. Drop Down Menu A new window will open. Click the *Generate a new API token* button. Generate Token Provide your login credentials, if prompted. You'll be redirected to your new API Token. Generate Token Use the *Copy* icon to copy the token and store it in a secure place. This is the only time you'll see the token here and there will be no way to retrieve it later. If you lose it, you will have to revoke all your API tokens and regenerate new ones. ## Set up your CI/CD platform Store it as an environment variable named `USER_POOL_CLIENT_ID` with the value `j084768v4hd6j1pf8df4h4c47`.
It will be read and used by the `dv` client in the workflow. Here are some relevant docs for storing environment variables in popular CI/CD platforms: * [Jenkins ](https://www.jenkins.io/doc/pipeline/tour/environment/) * [CircleCI ](https://circleci.com/docs/set-environment-variable/#set-an-environment-variable-in-a-project) * [TravisCI ](https://docs.travis-ci.com/user/environment-variables/) * [TeamCity ](https://www.jetbrains.com/help/teamcity/typed-parameters.html#How+to+Create+a+New+Parameter) * [Bitrise ](https://devcenter.bitrise.io/en/builds/environment-variables.html)
Don't store the API Token as a plain environment variable! If your CI/CD platform provides a secure secret storage, use it. Here are some relevant docs for storing secrets in popular CI/CD platforms: * [Jenkins ](https://www.jenkins.io/doc/developer/security/secrets/#storing-secrets-on-disk) * [CircleCI ](https://circleci.com/docs/security-recommendations/) * [TravisCI ](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings) * [TeamCity ](https://www.jetbrains.com/help/teamcity/hashicorp-vault.html) * [Bitrise ](https://devcenter.bitrise.io/en/builds/secrets.html) If your platform doesn't support secure secrets handling, you can use external secret handling tools: * [Hashicorp Vault ](https://www.vaultproject.io/) (has a plugin for TeamCity) * [Akeyless ](https://docs.akeyless.io/docs/akeyless-overview) (has a plugin for TeamCity) * [Azure Key Vault ](https://azure.microsoft.com/en-us/products/key-vault) (has a plugin for TeamCity) * [Google Secret Manager ](https://cloud.google.com/security/products/secret-manager) * [AWS Secrets Manager ](https://aws.amazon.com/secrets-manager/)
## Create a build step in your CI/CD workflow ### Install the Diversion client, authenticate it and clone your repo In your CI/CD step editor or `yml` file, create a new *Shell* build step with the following content: ```bash Mac/Linux theme={null} # Download Diversion client curl -sL https://get.diversion.dev/unix | bash ; export PATH="$HOME/.diversion/bin:$PATH" # Start the Diversion agent in the background and wait for it to start dv --agent --bkg sleep 2 # Authenticate Diversion dv authenticate $API_TOKEN # Clone your repository and wait for sync to complete dv clone -new-workspace my-repository cd my-repository dv status ``` ```powershell Windows theme={null} # Download Diversion client . ([Scriptblock]::Create((([System.Text.Encoding]::ASCII).getString((Invoke-WebRequest -Uri "https://get.diversion.dev/win-ci").Content)))) # Start the Diversion agent in the background and wait for it to start dv --agent --bkg Start-Sleep -Seconds 2 # Authenticate Diversion dv authenticate $API_TOKEN # Clone your repository and wait for sync to complete dv clone -new-workspace my-repository cd my-repository dv status ``` Replace `$API_TOKEN` with the appropriate way to reference your secret from the secure storage. Consult your platform's docs and the secure storage docs. Replace `my-repository` with the name of your repository. `dv status` will block until all the files are downloaded. This is important before starting to work. It will also output the workspace ID if you want to reuse it for the next runs or view it in the web app. `-new-workspace` will create a new workspace for each run of the CI/CD workflow. Passing a workspace argument here is important, or else the clone command will prompt for user input and block. See `dv help clone` for details. ## Add the rest of your CI/CD workflow That's it. You're all set to use your Diversion repo in your CI/CD workflow. You can also use any CLI commands you would use with `dv` when running locally. ## A Jenkins example Be sure to replace the placeholders with your actual values. Also note that this syntax is for a Windows node, so you may need to adjust it for your specific setup. ```groovy theme={null} pipeline { agent { any } environment { USER_POOL_CLIENT_ID = "j084768v4hd6j1pf8df4h4c47" DV_WORKSPACE = "" //Found in Diversion using 'dv workspace' command DV_REPO = "" //Your repository name } stages { stage('Sync Repository') { steps { script { // Checking if Diversion CLI is installed and installing from API if not if (!fileExists("${USERPROFILE}\\.diversion\\bin\\dv.exe")) { echo "Diversion not installed at ${USERPROFILE}\\.diversion\\bin\\dv.exe, installing..." powershell 'iwr https://get.diversion.dev/win-ci | iex' } //Authenticating Diversion CLI withCredentials([string(credentialsId: '', variable: 'API_TOKEN')]) //Insert your credential ID found in Jenkins Credentials { echo "Diversion CLI installed, authenticating..." bat "dv authenticate %API_TOKEN%" } //Cloning repository if it is not already cloned if (!fileExists("${WORKSPACE}\\${DV_REPO}\\.diversion")) { echo "Diversion authenticated, empty folder found, cloning repository..." bat "dv clone ${DV_REPO} -workspace ${DV_WORKSPACE}" } //Pulling latest changes if repository is already cloned else { echo "Diversion repository already cloned, pulling latest changes..." bat "cd ${WORKSPACE}\\${DV_REPO} && dv update" } //Displaying status of repository until tasks complete (so we do not start more tasks until it is done) bat "cd ${WORKSPACE}\\${DV_REPO} && dv status" } } } } } ``` # Overview Source: https://docs.diversion.dev/cmd-ref/about-cmd Learn how Diversion's command-line interface (CMD) works and simplify your version control workflow. This section is the reference for Diversion's CLI commands. For in-CLI help, check the [help command](/cmd-ref/help). To run Diversion on your computer, follow our [Getting Started Guide](../quickstart). You can type the commands directly into your terminal or shell; append `dv` followed by the command, parameter, and flags. ```bash theme={null} dv status ``` We recommend using the interactive CLI to get autocompletion and avoid typing `dv` every time. To start the interactive CLI, you just need to type `dv`. This will open the interactive CLI; from now on, you just need to enter the commands followed by parameters and flags. ```bash theme={null} clone ``` If you have questions or feedback about this reference, please contact us at our [Discord Server](https://discord.com/invite/HDAGJvgkuT). # annotate Source: https://docs.diversion.dev/cmd-ref/annotate Show line-by-line commit attribution for a file The `annotate` command shows who last modified each line of a file, along with the commit ID and date. `dv blame` is an alias for this command. ```bash theme={null} dv annotate [-L ] ``` `` is the file to show annotation information for. `[-L ]` limits the output to a specific line range. For example, `-L 10,20` shows only lines 10 through 20. For each line, the output includes: * **Commit ID** - the commit that last changed the line * **Author** - who made the change * **Date** - when the change was made * **Line number and content** - the current line text For example, to see who last modified each line in a file: ```bash theme={null} dv annotate src/main.py ``` To see annotation for a specific range of lines: ```bash theme={null} dv annotate src/main.py -L 10,20 ``` # branch Source: https://docs.diversion.dev/cmd-ref/branch Manage branches in the current repo The branch command allows you to manipulate branches: creating, deleting, and renaming. ## Create a branch To create a new branch, run: ```bash theme={null} dv branch -c [-no-checkout] ``` A new branch `branch-name` will be created. If the flag `-no-checkout` is *not* passed, the new branch will be checked out. The branch\_name has to be a unique identifier, not named after any other existing branch. Uncommitted changes will be transferred to the newly created branch. ## Delete a branch To delete a branch, run: ```bash theme={null} dv branch -d ``` For convenient autocompletion of the branch name, run the CLI in interactive mode. This command deletes the branch with the given id as parameter, the ID in this case is the branch’s name. The `–f` flag is optional and suppresses the confirmation dialog for deleting the branch. ## Rename a branch ```bash theme={null} dv branch -r ``` The new name parameter has to be a unique identifier, not previously used for any other branch. # branch-name Source: https://docs.diversion.dev/cmd-ref/branch-name Show the current branch name The `branch-name` command prints the name of the currently checked-out branch. ```bash theme={null} dv branch-name ``` This is useful for scripting and CI/CD pipelines where you need to retrieve the current branch name programmatically. # cd Source: https://docs.diversion.dev/cmd-ref/cd Change current working directory for an interactive CLI session ## Change working directory Similarly to your OS' terminal, `cd` allows you to switch the working directory for the Diversion CLI. ```bash theme={null} dv cd ``` The `` parameter is the path you want to move to. For example, if you want to move to your Documents directory, you would type: ```bash theme={null} dv cd /Users/Sloth/Documents/ ``` # checkout Source: https://docs.diversion.dev/cmd-ref/checkout Switch branches and manage versions efficiently with Diversion's checkout command reference. Checkout a branch, commit, or tag to your current workspace. ```bash theme={null} dv checkout [--take-changes] [--shelve-changes] [--discard-changes] [--apply-shelf] [--ignore-shelf] ``` `` is the only mandatory parameter and the options are: ``, or `` if you want to checkout a branch. `` or ``, if you're checking either of them. When checking out, there might be some local pending changes or incoming shelved changes. You can specify what to do in each case: `[--take-changes]` If your worskpace contains any changes, take them with you to the checked out target. `[--shelve-changes]` If your workspace contains any changes, shelve them for later use. `[--discard-changes]` Discard any changes in the workspace. `[--apply-shelf]` If the branch to be checked out contains any previously shelved changes, un-shelve them after check out. `[--ignore-shelf]` If the branch to be checked out contains any previously shelved changes, ignore them and don't prompt to apply them. # cherry-pick Source: https://docs.diversion.dev/cmd-ref/cherry-pick Apply changes from a specific commit to your current workspace The `cherry-pick` command allows you to apply the changes from a specific commit into your current workspace without merging the entire branch. ```bash theme={null} dv cherry-pick ``` The `` parameter is the ID of the commit to cherry-pick. This is useful when you want to apply specific changes from another branch without merging everything. An example of cherry-picking a commit: ```bash theme={null} dv cherry-pick abc123def456 ``` The changes from commit `abc123def456` will be applied to your current workspace. You'll need to commit these changes to save them to your branch. If there are conflicts between the cherry-picked commit and your current workspace, you'll need to resolve them manually. # clean Source: https://docs.diversion.dev/cmd-ref/clean Remove ignored and untracked files from the workspace The `clean` command removes ignored and untracked files from your workspace, similar to `git clean`. ```bash theme={null} dv clean [-f] ``` The `-f` flag forces the removal of files without confirmation. This command is useful for removing build artifacts, temporary files, and other untracked content that you don't want to keep. This command permanently deletes files. Make sure you don't have any important untracked files before running it. An example of cleaning the workspace: ```bash theme={null} dv clean -f ``` This will remove all ignored and untracked files without asking for confirmation. Files listed in your `.dvignore` file are considered ignored files and will be removed by this command. # clone Source: https://docs.diversion.dev/cmd-ref/clone Clone a repository into your local drive ```bash theme={null} dv clone [path] [--workspace ] [--new-workspace] [--ref ] ``` If no path is provided, the cloned repository will be cloned under the current directory in a new folder with the same name as the repository. The `` has to be the id that starts with ws., not the name. `[--workspace ]` specifies an existing workspace to use after cloning. `[--new-workspace]` forces creating a new workspace rather than prompting. `[--ref ]` checks out a specific branch name, branch ID, commit ID, or tag ID after cloning. If unspecified, the default branch is checked out. # commit Source: https://docs.diversion.dev/cmd-ref/commit Add changes to your active branch In Diversion, you call the commit command to add the changes in your active workspace to the active branch. ```bash theme={null} dv commit [files...] [-a] -m [--no-verify] ``` You can specify which files to commit individually or use the `[-a]` parameter to commit all the changes. A commit message is required preceded by the `-m` flag. The commit message needs to be "surrounded by quotes." `[--no-verify]` skips pre-commit hooks. An example on how to add all the files to a commit would be: ```bash theme={null} dv commit -a -m "Implemented running animations." ``` Once committed, the changes will be replicated across all users on the same branch. Use the `--no-verify` flag to skip [pre-commit hooks](/advanced/pre-commit-hooks) for a single commit: ```bash theme={null} dv commit -a -m "quick fix" --no-verify ``` # diff Source: https://docs.diversion.dev/cmd-ref/diff Compare changes between branches or commits with Diversion's diff command for clear version insights. The `diff` command allows you to compare changes between your current workspace, branches, commits, or tags. ```bash theme={null} dv diff [paths...] [--base ] [--compare ] [--name-status] [--color ] ``` `[paths...]` is a file or directory to compare. If omitted, Diversion compares the entire repository. `[--base ]` sets the base reference to compare from (branch name, commit ID, or tag). Defaults to the workspace's base commit. `[--compare ]` sets the reference to compare to (branch name, commit ID, or tag). Defaults to the current workspace. `[--name-status]` shows only names and status of changed files (A=added, M=modified, D=deleted, R=renamed). `[--color ]` controls color output. Defaults to `auto`. For example, to see what changed between two branches: ```bash theme={null} dv diff --base main --compare feature-branch ``` To see just a summary of changed files: ```bash theme={null} dv diff --name-status ``` # feedback Source: https://docs.diversion.dev/cmd-ref/feedback Provide your feedback to Diversion devs We love and appreciate your feedback; this command will open up a browser window with a form you can use to send your comments. ```bash theme={null} dv feedback ``` Additionally, you can visit our [Discord Server](https://discord.com/invite/HDAGJvgkuT) for support. # help Source: https://docs.diversion.dev/cmd-ref/help Get more information about Diversion's commands To get in-CLI help about working with Diversion CLI, you can use the help command, followed by any other command in this guide. ```bash theme={null} dv help [command] ``` For example, if you want to get more information about how the `clone` command works, you would input the following: ```bash theme={null} dv help clone ``` # import Source: https://docs.diversion.dev/cmd-ref/import Bring your Git repository to Diversion This command allows you to import your Git project (currently, only GitHub over HTTPS URL is supported). ```bash theme={null} dv import [repo_name] [--with-sync] [--with-history] [--git_branch ] ``` The `` is the URL from your GitHub repository. Optionally, you can provide a `[repo_name]` if you want Diversion to name it differently than the repository you are importing. You can tell Diversion to keep your repository synced with the Git repository (changes in either will be propagated to the other). Use the `[--with-sync]` parameter if you need this. You can tell Diversion to import either the repository's head (the latest commit) or the entire repository's history. Specify this using the `[--with-history]` parameter. You can also indicate which branch you want to import or all the branches. By default, Diversion will import the default branch. # init Source: https://docs.diversion.dev/cmd-ref/init Initialize a repository The init command initializes a Diversion repository from your local drive. Diversion will create a cloud project with the provided parameters. ```bash theme={null} dv init [--f] ``` The path is the location where you want Diversion to initialize your project. If you want to initialize in the current directory, provide `.` as the parameter. You can define the repository's name (which will appear in the web dashboard). If no name is specified, Diversion will take the last path component of the directory. # invite Source: https://docs.diversion.dev/cmd-ref/invite Invite collaborators To add contributors to your repository, you use the invite command: ```bash theme={null} dv invite --access ``` `--access ` defines the level of access you want to provide to this collaborator; the options for `` are: * `READ` * `WRITE` * `ADMIN` * `OWNER` The collaborators need a Diversion account before they can access the repository. ## accept To accept a pending repository invitation: ```bash theme={null} dv invite accept ``` # log Source: https://docs.diversion.dev/cmd-ref/log Get the latest commits You use the log command to get the list of commits in your repository. ```bash theme={null} dv log [path] [-n ] [--oneline] [--since ] [--until ] [--date ] ``` `[path]` filters commits to only those affecting a specific file or directory. `[-n ]` limits the number of commits shown (default 20, max 1000). `[--oneline]` shows each commit on a single line. `[--since ]` shows commits after a date (ISO format or relative like `1 week ago`). `[--until ]` shows commits before a date. `[--date ]` sets the output date format. Use `iso` for ISO 8601 UTC. An example of fetching the last ten commits: ```bash theme={null} dv log -n 10 ``` To see commits affecting a specific file: ```bash theme={null} dv log path/to/file.uasset ``` To see recent commits in compact format: ```bash theme={null} dv log --oneline --since "2 weeks ago" ``` # login Source: https://docs.diversion.dev/cmd-ref/login Login to your Diversion account Logs you into your Diversion account via the command line. It will open a browser window for you to enter your credentials. After a successful login, you can return to the command line and start working. ```bash theme={null} dv login ``` # logout Source: https://docs.diversion.dev/cmd-ref/logout Log out securely from Diversion CLI and manage session access with the logout command. To logout from your current signed-in account, you simply use the logout command: ```bash theme={null} dv logout ``` # ls Source: https://docs.diversion.dev/cmd-ref/ls List repository files, branches, and workspaces using the Diversion ls command for quick project overview. ```bash theme={null} dv ls ``` This command lists the file system contents of a: workspace, branch or commit. `` is the ID of the revision to list. The default is list the current workspace revision. `` is an optional file to plot the results to, by default will print to the standard output. # merge Source: https://docs.diversion.dev/cmd-ref/merge Add your changes to the active branch To merge a branch or commit into the current checkout branch, you use the `merge` command: ```bash theme={null} dv merge [--into ] ``` `` is the id of the branch or the commit you want to merge. `[--into ]` specifies the destination branch to merge into. Defaults to the current branch. # merge-preview Source: https://docs.diversion.dev/cmd-ref/merge-preview Preview and validate merges before applying them using Diversion’s merge-preview command. Opens a web browser and display the impending merge differences between branches. ```bash theme={null} dv merge-preview ``` `` is the name of the branch you want to merge from. `--target` the target branch to merge into. The default is the checked out branch. # mkdir Source: https://docs.diversion.dev/cmd-ref/mkdir Create a directory in the workspace The `mkdir` command creates a new directory in your workspace. ```bash theme={null} dv mkdir --path [--workspace_id ] ``` **Required Parameters:** * `--path` - The path to the directory to create **Optional Parameters:** * `--workspace_id` - The ID of the workspace to create the directory in (defaults to current workspace) This command is useful for creating directory structures programmatically or from scripts. An example of creating a directory: ```bash theme={null} dv mkdir --path /game/levels/world1 ``` An example of creating a directory in a specific workspace: ```bash theme={null} dv mkdir --path /assets/textures --workspace_id abc123def456 ``` After using `mkdir`, you'll still need to commit the changes to save the directory structure to your branch. # mv Source: https://docs.diversion.dev/cmd-ref/mv Move or rename a file or directory in the workspace The `mv` command moves or renames a file or directory in your workspace. ```bash theme={null} dv mv --src_path --dst_path [--workspace_id ] ``` **Required Parameters:** * `--src_path` - The path to the file or directory to move * `--dst_path` - The destination path **Optional Parameters:** * `--workspace_id` - The ID of the workspace to perform the move in (defaults to current workspace) This command is useful for reorganizing your workspace structure or renaming files programmatically. An example of moving a file: ```bash theme={null} dv mv --src_path /old/location/file.txt --dst_path /new/location/file.txt ``` An example of renaming a file: ```bash theme={null} dv mv --src_path /assets/old_name.png --dst_path /assets/new_name.png ``` An example of moving a directory: ```bash theme={null} dv mv --src_path /game/old_folder --dst_path /game/new_folder ``` After using `mv`, you'll still need to commit the changes to save the move or rename to your branch. # obliterate Source: https://docs.diversion.dev/cmd-ref/obliterate Permanently delete blob storage for matching file versions (repo-admin only). The `obliterate` command permanently deletes the underlying blob storage for every version of files that match a path pattern, across all branches and commits. This is **destructive and irreversible**. For background, glob syntax, and the underlying model, see the [Obliterate guide](/advanced/obliterate). Obliterate cannot be undone. Always run `preview` first and read the plan before running `execute`. Requirements: * You must be a [**repository admin**](/basic/access-levels#organization-level-access). * Obliterate is not supported on git-synced repositories. ## preview Show what would be obliterated. No state changes. ```bash theme={null} dv obliterate preview [--json] [ ...] ``` `` is a path pattern anchored to the repo root (e.g. `'/assets/*.psd'`). Quote the pattern so your shell does not expand it. The argument is repeatable -- pass multiple globs to plan their combined obliteration in one call. `--json` emits a single JSON document on stdout with the full preview response. Banners and warnings are suppressed in this mode; warnings move into a `warning` string field on the document. The human view shows headline counts, a reclaim estimate, and the top 20 deletable / not-deleted paths sorted by bytes desc. If the full list is longer, a trailing line reads `... and N more (use --json for the full list)`. When more than one glob is passed, a per-glob block prints the files / versions / total bytes each glob matched on its own. Example: ```bash theme={null} dv obliterate preview '/assets/old_textures/*.psd' '/builds/.../*.pak' ``` ```bash theme={null} dv obliterate preview --json '/assets/old_textures/*.psd' | jq '.deletable_paths | length, .per_glob_summary' ``` ## execute Permanently obliterate matching blobs. ```bash theme={null} dv obliterate execute [--yes] [--json] [--nowait] [ ...] ``` `` is the same path pattern as in `preview`, and is repeatable. `--yes` skips the destructive-confirmation prompt (for scripting). Without it, you must type the repository name or ID at the prompt to confirm. `--json` emits a single JSON document instead of the human banner. **Requires `--yes`** -- an interactive prompt would corrupt the JSON stream. `--nowait` enqueues the job and exits immediately without polling. Use `dv obliterate status ` afterwards. By default, `execute` returns a `job_id` and polls the status endpoint every 3 seconds for up to **18 seconds**. The cap is fixed -- use `--nowait` to skip polling, or follow up with `status` for longer runs. Exit codes: | Code | Meaning | | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `0` | Polling reached a terminal state and the job completed without failures. | | `2` | Polling reached a terminal state and the job had one or more failed deletions. | | `101` | The 18s polling cap elapsed with the job still in progress. Lets scripts distinguish "gave up waiting" from "done"; follow up with `dv obliterate status`. | Example: ```bash theme={null} dv obliterate execute --yes '/assets/old_textures/*.psd' ``` ## status Show the state of a previously enqueued obliterate job. ```bash theme={null} dv obliterate status ``` `` is the id returned by `dv obliterate execute` (e.g. `dv.obliterate.593d2b8a8dbf47559bcc73c8bcf54f41`). Output includes the overall status (`queued`, `in_progress`, `succeeded`, `failed`, or `archived`), per-file counts (`pending` / `done` / `failed`), the start time, and -- for terminal states -- the end time. `failed` includes the first 20 errors with a short error message per failure. `archived` means the job has aged out of the queue but its counts are still inspectable. A 404 means there is no obliterate job with that id in this repository. Example: ```bash theme={null} dv obliterate status dv.obliterate.593d2b8a8dbf47559bcc73c8bcf54f41 ``` ## Notes * The server enforces a 60-second time budget on glob resolution. If your glob matches too many files, the call is rejected with an error -- narrow the pattern and split into multiple runs. * The actual deletion runs in the background after the call returns, which is why `execute` returns quickly and why progress is tracked via the status endpoint. * Files in shared (grouped) storage cannot be individually obliterated and are reported as skipped in the response. For the full conceptual guide, glob syntax tables, and worked examples, see [Obliterate](/advanced/obliterate). # preferences Source: https://docs.diversion.dev/cmd-ref/preferences Get or set workspace preferences The `preferences` command allows you to view and modify workspace-specific preferences, such as which folders are synced. ```bash theme={null} dv preferences [-add | -remove ] ``` To view current preferences: ```bash theme={null} dv preferences ``` ## -add Select a folder to be synced: ```bash theme={null} dv preferences -add ``` ## -remove Stop syncing a folder: ```bash theme={null} dv preferences -remove ``` Preferences are workspace-specific and won't affect other workspaces in the same repository. # repo Source: https://docs.diversion.dev/cmd-ref/repo Perform actions on your repository The repo command allows you to list the repositories you have cloned locally and those you’re a collaborator of. This will list your repositories. ```bash theme={null} dv repo ``` To delete a repository: ```bash theme={null} dv repo -d [-f] ``` The `-f` flag will suppress the confirmation message. This command will delete the repository from the cloud and unlink your local directory as a Diversion repository. Be careful with this action; there’s no way to recover deleted repositories. # reset Source: https://docs.diversion.dev/cmd-ref/reset Reset the latest changes It is possible to reset the current changes in the workspace to the latest commit’s state. ```bash theme={null} dv reset [--all] [--f][--clean] ``` The `` parameter is the path for a file or directory you want to reset. You can specify to reset everything using the `[--all]` flag. If you want to remove the added files, provide the `[--clean]` flag. Using the `-f` flag will suppress the confirmation. # restore Source: https://docs.diversion.dev/cmd-ref/restore Restore a file or directory from a commit, branch, or tag The `restore` command restores a file or directory from a previous commit, branch, or tag into your current workspace. ```bash theme={null} dv restore [--source ] ``` `` is the file or directory path to restore. `[--source ]` specifies the source to restore from: a commit ID, branch name, or tag ID. Defaults to the workspace's base commit. For example, to restore a file from the current base commit: ```bash theme={null} dv restore path/to/file.uasset ``` To restore from a specific branch: ```bash theme={null} dv restore path/to/file.uasset --source main ``` # revert Source: https://docs.diversion.dev/cmd-ref/revert Revert the changes made in a commit ```bash theme={null} dv revert [--conflict_resolution ] ``` The `` is the id of the commit you want to revert the changes to. This will create a new commit with the reverted changes. `[--conflict_resolution ]` sets how conflicts are handled: * `manual` — resolve conflicts manually (default) * `keep-current` — keep the current workspace state * `accept-incoming` — accept the reverted state # revert-to-commit Source: https://docs.diversion.dev/cmd-ref/revert-to-commit Revert the workspace to the state of a specified commit The `revert-to-commit` command reverts your workspace to the exact state of a specified commit, discarding all changes made after that commit. ```bash theme={null} dv revert-to-commit ``` The `` parameter is the ID of the commit to which the workspace should be reverted. This command is useful when you want to undo multiple commits and return to a specific point in history. This operation will discard all changes in your workspace that came after the specified commit. Make sure to commit or shelve any work you want to keep before running this command. An example of reverting to a specific commit: ```bash theme={null} dv revert-to-commit abc123def456 ``` After running this command, your workspace will match the state of commit `abc123def456`. # rm Source: https://docs.diversion.dev/cmd-ref/rm Delete a file or directory from the workspace The `rm` command deletes a file or directory from your workspace. ```bash theme={null} dv rm --path [--workspace_id ] ``` **Required Parameters:** * `--path` - The path to the file or directory to delete **Optional Parameters:** * `--workspace_id` - The ID of the workspace to delete from (defaults to current workspace) This command is useful for removing files or directories programmatically or from scripts. This command deletes files from your workspace. Make sure you want to remove the specified path before running this command. An example of deleting a file: ```bash theme={null} dv rm --path /game/old_asset.png ``` An example of deleting a directory: ```bash theme={null} dv rm --path /deprecated/features ``` After using `rm`, you'll still need to commit the changes to save the deletion to your branch. # share Source: https://docs.diversion.dev/cmd-ref/share Not yet supported This commant is not yet supported. # shelf Source: https://docs.diversion.dev/cmd-ref/shelf Manage shelves in the current repo Shelves let you temporarily save workspace changes and restore them later, similar to Git's stash. Shelves belong to a single repository but are not tied to any branch, you can create a shelf on one branch and apply it on another. Shelf names must be unique within the repository for each user and cannot exceed 60 characters. For all commands below, the `` parameter can be either the shelf name or ID. ## list Lists all shelves in the repository. ```bash theme={null} dv shelf ``` ## create Creates a shelf from your current workspace changes. ```bash theme={null} dv shelf create [paths...] [--no-reset] ``` `` is the name for your shelf. `[paths...]` is an optional list of specific files to shelve. If omitted, all changes are shelved. `[--no-reset]` keeps the workspace changes after creating the shelf. By default, changes are reset. ## show Shows the list of files contained in a shelf. ```bash theme={null} dv shelf show ``` ## apply Applies a shelf to your current workspace. ```bash theme={null} dv shelf apply [--keep] [-f] ``` `[--keep]` preserves the shelf after applying. By default, the shelf is deleted. `[-f]` skips the confirmation prompt. If the shelved changes conflict with your current workspace, you'll need to resolve the conflicts before continuing. ## rename Renames an existing shelf. ```bash theme={null} dv shelf rename ``` ## delete Permanently deletes a shelf. ```bash theme={null} dv shelf delete [-f] ``` Use `-f` to skip the confirmation prompt. This action cannot be undone. ## Example: carry changes across machines Because shelves are stored in the cloud, you can use them to move uncommitted work between machines on the same repo: ```bash theme={null} # On Machine A dv shelf create my-wip # On Machine B (same repo, any workspace) dv shelf apply my-wip ``` For more information about shelving in Diversion, visit the [Shelves](../basic/shelves) page. # show Source: https://docs.diversion.dev/cmd-ref/show Show commit details The `show` command displays details for a specific commit. ```bash theme={null} dv show [ref] ``` `[ref]` is a branch name, branch ID, commit ID, or tag ID. If omitted, shows details for the current commit. For example, to view the current commit: ```bash theme={null} dv show ``` To view a specific commit: ```bash theme={null} dv show abc123 ``` # status Source: https://docs.diversion.dev/cmd-ref/status Get the syncing status This command shows your project's syncing status. It also contains the working tree directory, which includes the repository, branch, workspace, and commit you're in. ```bash theme={null} dv status [paths...] [--sync-only] [--nowait] [--commit-id-only] [--no-limit] ``` `[paths...]` when specified, shows the sync status of the given files or directories (implies `--sync-only` and `--nowait`). `[--sync-only]` shows sync status only. `[--nowait]` exits without waiting for the workspace to be synced. `[--commit-id-only]` shows only the commit ID of the workspace. `[--no-limit]` shows the complete changelist without limiting the output size. # support Source: https://docs.diversion.dev/cmd-ref/support Create and upload a support bundle If you ever encounter an issue with Diversion, we'd love to hear about it! ```bash theme={null} dv support [-m ] [-s] [-o ] ``` `[-m ]` provides a description of the issue. If omitted, you'll be prompted interactively. `[-s]` skips uploading the bundle to Diversion — only saves it locally. `[-o ]` sets the directory to write the bundle to. Defaults to your desktop. Running this command creates a support bundle with your issue description and your user info, so we can reach out if necessary. For non-interactive usage (e.g., in scripts): ```bash theme={null} dv support -m "Sync stuck on large binary files" ``` To save the bundle locally without uploading: ```bash theme={null} dv support -m "Issue description" -s -o /path/to/output ``` When describing your issue, please be as specific as you can so we can be as efficient as we can in solving it. Also, you can always reach out to us directly on [Discord](https://discord.com/invite/HDAGJvgkuT). We might ask you to run this command ;) # tag Source: https://docs.diversion.dev/cmd-ref/tag Create, list, or delete tags in Diversion using the tag command for efficient version tracking. In Diversion, you can tag commits for easier reference of particular commits. ```bash theme={null} dv tag [-sub-command] [--json] ``` To create a new tag: ```bash theme={null} dv tag -c [-a ] [--ref ] ``` The above command will create a new tag with the name ``, and optionally, you can add a description `[-a “Tag description”]`. You can also provide the `commit_id` explicitly, or by default, the current commit will be tagged. To delete a tag: ```bash theme={null} dv tag -d [-f] ``` The tag ID must be Diversion's ID, not the tag name. To modify an existing tag: ```bash theme={null} dv tag -m [--name ] [-a ] ``` `[--name ]` changes the tag's name. `[-a ]` updates the tag's description. # unregister Source: https://docs.diversion.dev/cmd-ref/unregister Unregister repositories from Diversion safely with the unregister CLI command. If you want Diversion to stop tracking a directory as part of your repository, you must unregister it. The directory will stay in your local drive, but Diversion won’t track it. ```bash theme={null} dv unregister [--f] ``` # update Source: https://docs.diversion.dev/cmd-ref/update Sync and refresh your workspace with the Diversion update command to stay aligned with repository changes. The update command pulls the latest changes from the current checked-out branch into your current workspace. ```bash theme={null} dv update [--conflict_resolution ] ``` `[--conflict_resolution ]` sets how conflicts are handled: * `manual` — resolve conflicts manually (default) * `keep-current` — keep the workspace's changes * `accept-incoming` — accept the latest changes from the checked-out branch # verify Source: https://docs.diversion.dev/cmd-ref/verify Confirm repository integrity and validate data consistency using the Diversion verify command. Verify the filesystem integrity compared to multiple sources of truth. ```bash theme={null} dv verify [--mirror ] [--intact] ``` `--mirror` is the path to an un-versioned local directory that should reflect the expected contents of the workspace. `--intact` if set, verify all items in tree are intact (without modifications). # version Source: https://docs.diversion.dev/cmd-ref/version Display version information about Diversion The `version` command displays the current version of the Diversion CLI. ```bash theme={null} dv version ``` # view Source: https://docs.diversion.dev/cmd-ref/view View the current workspace in a web browser Run the following command inside of a Diversion repository: ```bash theme={null} dv view ``` This will open Diversion's web UI for the current repository. ## Make sure you're in a repository This command only works when the curret working folder is in a Diversion repository. Running it in any other folder results in the following error: ```bash theme={null} Current directory is not a diversion repository (neither is any of its parent directories). ``` # workspace Source: https://docs.diversion.dev/cmd-ref/workspace Manage your workspace The workspace actions you can take with this command are list, rename, delete, pause, and resume. If you want to list your workspaces, use the following: ```bash theme={null} dv workspace ``` To rename your current workspace: ```bash theme={null} dv workspace rename ``` To delete the specified workspace: ```bash theme={null} dv workspace delete [-f] ``` You cannot delete the current workspace. The `` is not the workspace name but the id that starts with `dv.ws.xxxxx` ## pause Pause syncing of the workspace: ```bash theme={null} dv workspace pause ``` ## resume Resume syncing of the workspace: ```bash theme={null} dv workspace resume ``` To any action, you can add the `-f` flag to avoid getting asked to confirm. For more information about workspaces in Diversion, visit the [Repositories, Branches, and Workspaces](../concepts/repo-branch-workspace) page. # Permission Modes Source: https://docs.diversion.dev/collaboration/permission-modes Understand Diversion's permission modes (READ, WRITE, ADMIN) and how to manage access control for repositories and organizations. # Permission Modes This page is currently under development and will be filled with comprehensive content soon. ## Overview Diversion uses a simple but powerful permission system with three access levels: READ, WRITE, and ADMIN. This guide explains each permission mode and how to manage access. ## Coming Soon This guide will include: * Detailed explanation of each permission mode * What users can do at each level * How to grant and change permissions * Repository-level vs organization-level permissions * Best practices for permission management * Security considerations ## Repository Permission Modes ### READ **What users can do:** * View repository contents * Clone the repository * View commit history * View branches and tags **What users cannot do:** * Commit changes * Create branches * Modify repository settings ### WRITE **What users can do:** * Everything in READ, plus: * Commit changes * Create and merge branches * Participate in code reviews **What users cannot do:** * Change repository settings * Manage collaborators * Delete the repository ### ADMIN **What users can do:** * Everything in WRITE, plus: * Add/remove collaborators * Change collaborator permissions ### OWNER * Everything in ADMIN, plus: * Delete the repository ## Managing Permissions **Organization Level:** * OWNER: What the admin can, plus handle billing * ADMIN: Manage members(except for the owner), and read access to all repositories * MEMBER: Access assigned repositories ## Best Practices **Principle of Least Privilege:** * Grant minimum necessary permissions * Regularly review access levels * Remove access when no longer needed **For Teams:** * Core team members: WRITE access * Project leads: ADMIN access * External contributors: READ access (initially) ## Related Resources * [Manage Project Access](/basic/manage-project-access) * [Organization Management](/basic/organization-management) * [CLI Reference: invite](/cmd-ref/invite) *** **Last updated:** 2025-10-25 # Conflicts Source: https://docs.diversion.dev/concepts/conflicts Learn what types of conflicts can occur and how to resolve them effectively. # Conflict Types When working with Diversion, you may encounter different types of conflicts that can disrupt your workflow. Understanding these conflicts and how to resolve them is crucial for maintaining a smooth development process. ## Merge Conflicts These conflicts occur mostly during branch merges, when changes from different branches affect the same file. However, merge conflicts can also happen inside your workspace in the following scenarios: 1. You have *Auto-Update* turned on, and other team members have made commits to the same branch. 2. You switched branches in your workspace, and your workspace contained uncommitted changes, or you chose to unshelve changes on the target branch. 3. You cherry-picked another commit into your workspace. When a merge conflict occurs, the changes are stored outside your workspace in the cloud, which you can review and resolve in the desktop app. ## Sync Conflicts In Diversion, your work-in-progress workspace is stored both locally and remotely. While file updates usually sync from your local workspace to the remote one, it is also possible that the remote workspace has newer changes that need to be synced down to your local copy. For example, this can happen if your workspace has *Auto-Update* turned on (the default) and other team members have made commits to the same branch. Another example is when you merge changes from another branch into your current branch. Sync conflicts happen when your local changes haven't had a chance to sync to the remote mirror of your workspace, while the latter has received changes from new commits that modify the same files you have edited locally. Having your workspace sync paused or being offline for a while, increases the chances of encountering sync conflicts. On the other hand, working alone on a branch, or turning off *Auto-Update* reduces the chances of sync conflicts. When a sync conflict occurs, Diversion automatically creates a backup of your locally edited file with a `.dv-conflict` suffix, and overwrites the original path with the incoming contents. This helps ensure you don’t lose your work. ## The `.dv-conflict` Files These files are only created to indicate conflicts and are not intended to be committed to the repository. Hence, they are not tracked by Diversion and you can't commit them. When you have local conflicts, your workspace in the Diversion desktop app shows a warning: Local Conflict Warning and you can view the list of backed up conflicting files in the *Flat Changes* tab of the workspace: Flat Changes Selected The conflicting files will have a special icon and color: Conflict File Item In the above example, the file `syncing.mdx` (containing incoming changes) has a conflict with a backup file `syncing.dv-conflict.mdx` (containing the user's local changes that aren't synced). The content of the `.dv-conflict` file is viewable in the app, but with no history. You can safely ignore the `.dv-conflict` files and continue working and committing as usual with the rest of your files, including the original file that was conflicted. However, we recommend resolving conflicts as soon as possible before the differences become too hard to merge. The `.dv-conflict` files are not automatically deleted, so you should delete them yourself once you resolve the conflicts. You can delete them one-by-one in the Diversion desktop app, or in a batch from your file explorer. Use the context menu item *Show in Explorer/Finder* to quickly locate the file and delete it. ## Resolving Sync Conflicts If this is an Unreal Engine resource, such as `uasset`, then it'll be impossible to open both versions inside the editor due to broken redirectors in the backed up file (because its name has changed). Please do the following: 1. Make sure the original file has no changes (if there are, either commit or reset them before dealing with conflicts). 2. Overwrite the original file with the `.dv-conflict` version. 3. After the file is overwritten, you can open it in the editor and review the differences between the two versions. 4. Once you have resolved the differences, you can commit the changes or reset if you don't want them. 5. Delete the `.dv-conflict` file (if you left a copy when overwriting) to clean up your workspace. For other file types, such as text files or images, the process is as follows: 1. Use your preferred local diff tool to compare the versions, such as Meld, WinMerge, VSCode, etc. or open the files side by side. 2. Apply your edits to the original file path, and commit once you’re ready. 3. Delete the `.dv-conflict` file to clean up your workspace. If you don't clean up the `.dv-conflict` file, it will remain in your workspace, which may accumulate several conflict backups, e.g. `file.dv-conflict.txt`, `file.dv-conflict-1.txt`, `file.dv-conflict-2.txt`, etc. # Repositories, Branches, and Workspaces Source: https://docs.diversion.dev/concepts/repo-branch-workspace Understand the basics **Repositories** A repository is your project's container; it hosts all the assets, including art, code, audio, etc. Multiple collaborators can work on the same repository, contributing new assets or modifying existing ones. The repository’s admin and owners can invite collaborators. **Branches** A branch is a mechanism that allows you and your team to experiment, collaborate, test new features, and add fixes without disrupting the main project. Branches allow you to work safely on features, tests, etc., without disrupting the work of your collaborators. The general workflow for branching is as follows: * Create a new branch from the main branch (i.e., gameplay-test). * Work on changes, additions, and deletions and commit them to the branch. * Once ready, merge them into the main branch. * Delete the branch you created. Depending on your branching strategy, multiple collaborators can work on the same branch or even not branch at all (working on the main branch). Workspaces allow everyone to keep their uncommitted work private and synced. **Workspaces** Finally, workspaces. A workspace is a mechanism that allows each team member to keep their work synced across devices and with the cloud. For example, if you modify the script Enemy.cs on your local machine, Diversion will keep that file synced to the cloud (in your workspace), so even if you don’t commit it, the file is already synced. Workspaces are unique to each contributor and, for now, can’t be shared. A cloned workspace is also tied to the machine it was cloned on -- if you work from more than one computer, create a separate workspace on each one. See [Working from multiple computers](/basic/workspace-management#working-from-multiple-computers) for details. A workspace is linked to a branch, but you can switch the branch it is linked to. # Storage Source: https://docs.diversion.dev/concepts/storage How we calculate your storage usage Diversion stores your projects and their histories in the cloud. This is what allows you to access your projects from any device and to collaborate with your team. However, this also means that you need to be aware of how much storage you are using and how it is calculated. Storage is calculated daily. If you've made changes and don't see them reflected in your storage usage, wait until the next day and check again. ## For each file Diversion keeps a history of the files in your repository, one version per commit that includes that file. This means that if you have a file that is 1 MB in size and you have made 10 commits that include that file, it will count as 10 MB of storage usage. If you delete that file, it will still count as 10 MB of storage usage, since the history of that file is still stored in the repository and you can always revert to a previous commit that includes that file, or download it from the history. For the same reason, reverting or rolling back commits, replacing a large file with a smaller one, or adding it to `.dvignore` will not reduce your storage usage. These actions only change your files' current state, while the older versions remain in your history and continue to count. Repository admins can permanently remove older versions to reclaim storage with [obliterate](/advanced/obliterate). Deleting the repository or deleting unmerged branches also reduces storage. New files, or files with changes that are not yet committed, are also counted towards your storage quota, since they are synced to the cloud. These are easier to remove, since you can just `reset` them from your workspace and they will be removed from the cloud as well, and will no longer count towards your storage. ## For each repository For each repository, you can see how much storage you are using on its row in the **Remote Repositories** tab of the dashboard. This is the total size of all the files in the repository, including all the versions of each file. Storage per repository ## For each organization For an organization, all of the repositories assigned to that organization are counted. The storage quota is calculated for the owner of the organization. You can see the organization's total storage on the org settings Repositories page. Storage total for the organization If an owner or admin of an organization invites a new member, and that member has repositories that are not assigned to any organization, those repositories will be automatically added to the inviting user's organization and their storage will be counted towards the storage quota of the organization. Also, if an owner or admin of an organization invites a new collaborator to a repository that is part of an organization, the new collaborator will be added as a member. To avoid either of these, you can create a separate Diversion account to use in the organization. For any help, contact support. ## FAQs ### Can I delete repository history to free up storage space? Yes. Repository admins can permanently remove specific files and their history with [obliterate](/advanced/obliterate). The command takes one or more path patterns and deletes every version of the matching files across all branches and commits. **Going forward**: Use a [.dvignore](/basic/dvignore) file to exclude specific files or folders from future commits. Note that this will not affect items already committed prior to the change. ### Why am I receiving system messages about exceeding my storage limit? If you're seeing [system messages](/system-messages) like this: Storage plan breach notification This means your total repository storage exceeds your plan's storage capacity. To resolve this, you have three options: 1. **Delete unused repositories** - Remove repositories you no longer need to free up space 2. **Upgrade your plan** - Purchase additional storage capacity to accommodate your needs 3. **Move repositories out of your organization** - As the organization's owner, you can transfer any repository in your organization to another organization. See [how to move repositories](/basic/organization-management#how-do-i-move-repositories-out-of-my-organization) for instructions 4. **Delete unmerged branches** - If you have unmerged branches that are no longer needed, deleting them can free up storage # Syncing Source: https://docs.diversion.dev/concepts/syncing Understand how to pause/resume, toggle automatic updates and selectively sync your repositories ## Repositories By default your workspaces are synced in full, but there will be cases when you might want to: * pause temporarily the syncing of your workspace. * just sync a subset of your workspaces. ## Pause workspace sync You can temporarily pause syncing for any workspace through the desktop app: Open the workspace's "THIS WORKSPACE" sync settings, reached via the **... (more options) button** next to the workspace selector Diversion's Desktop App Workspace Sync Settings Button Toggle **Sync** off to pause ("Upload and download file changes with the cloud") Diversion's Desktop App Pause Sync Confirm to pause syncing for the current workspace Diversion's Desktop App Confirm Pause Sync While paused: Your local changes are preserved and you can continue working Remote commits from other team members won't sync to your workspace Your commits won't be pushed to the repository This is useful when you need to work offline or want to prevent interruptions during intensive work sessions. Remember to resume syncing when you're ready to collaborate again. ## Workspace Automatic Update Diversion's Desktop App Workspace's Auto-Update Toggle While sync pause/resume controls the syncing between your local copy to the cloud workspace, auto-update controls the merging of new commits from the shared branch into your cloud workspace. #### How it works Remote commits to the current branch will be automatically merged to the cloud workspace. Remote commits to the current branch will **not** be automatically merged to the cloud workspace. In case of remote commits to the branch, a notification "Pending workspace updates" will be displayed. Toggling auto-update from off to on will trigger an automatic workspace update in case of pending updates.
```mermaid theme={null} flowchart TD G[Local Workspace Updated] --> H{Sync Status} H -->|Resumed| I[Local changes automatically synced with cloud workspace] H -->|Paused| J[No sync to / with cloud workspace] A[Remote Branch Commit] --> B{Auto-Update} B -->|Enabled| C[New commits automatically merged to cloud workspace] B -->|Disabled| K[No sync with cloud workspace] C --> H{Sync Status} ```
#### When should I turn it off? In most cases it is better to be in sync with the remote branch, it allows finding and fixing conflicts fast and to avoid complex merges in the future. Turn it off if you don't want remote branch updates to automatically be synced into your cloud workspace, for example if you think that changes from other teammates might break your current project state. #### Alternative to disabling auto-update It is possible to branch-out to a side branch in order to avoid receiving new commits from the shared branch into your local workspace while you are working on a feature or a fix. The advantages of this approach are: * You can commit in more granular steps, and retain fine-grained control over your project history. * When you are ready to merge your changes into the shared branch, you can create a Review Request to have your changes reviewed by your team members. * Whenever you start working on a new feature, you can be sure that you are working on the latest version of the shared branch. #### Default automatic update setting Diversion's Desktop App Workspace's Auto-Update Toggle Repo admins and owners can set the default auto-update value of new workspaces created in the selected repo. To change the setting, open the settings sidebar (via your avatar -> `Your organizations`) and go to `Organization` -> `Repositories`. This will **not** affect existing workspaces' settings. Users can control the auto-update setting for their individual workspaces regardless of the default setting for new workspaces. ## Selective sync Control exactly which folders sync to your local workspace through the workspace's "THIS WORKSPACE" sync settings (the **... (more options) menu** next to the workspace selector). Diversion's Desktop App Workspace Sync Settings Button Choose **Selective sync** ("Choose which folders sync to this machine") Diversion's Desktop App Selective Sync Check (for sync) or uncheck (for unsync) the desired directories Diversion's Desktop App Confirm Selective Sync How it works: Checked folders: Contents sync locally, including all subfolders Unchecked folders: Won't sync locally Partially checked folders: Only checked subfolders will sync Previously synced folders: Will be deleted locally if unchecked Important notes: Selective sync settings apply only to the current workspace Settings cannot be changed while you have pending changes—commit or stash first Each workspace can have different selective sync configurations This feature is particularly useful for large repositories where you only need specific assets or code sections for your current task. ### Partially clone a repo with selective sync You can use selective sync to clone only specific folders from a repository, reducing disk space usage and sync time. Find the repository that you want to partially clone. Find your repo Open the workspace selector (top-right of the repo sub-header), click `+ New workspace`, and enter a name for your new workspace. Workspace selector with New workspace In the new workspace settings, select `Selective sync` to configure folder selection. Enable selective sync Choose which folders you want to include in your partial clone. Selective sync select folders Navigate to the desktop app (if not already there) and open the workspace selector. Your new workspace appears under the **Remote** section (workspaces that aren't cloned to this machine yet). Locate it, click the **...** (more options) menu next to it, and select `Clone`. Clone workspace That's it! You've successfully set up a partial clone with only the folders you need. Your workspace is now lighter and faster to sync. # Branching and Merging Source: https://docs.diversion.dev/core-concepts/branching-merging Learn how branching and merging work in Diversion, including creating branches, switching between branches, and resolving merge conflicts. # Branching and Merging Branching and merging in Diversion allows teams to work on multiple features in parallel while maintaining a stable main branch. With lightning-fast branch creation (milliseconds) and smart merging, Diversion makes parallel development effortless. ## What are Branches? A **branch** is an independent line of development in your repository. Branches allow you to: * Work on features without affecting the main codebase * Experiment with changes safely * Collaborate on separate tasks simultaneously * Maintain stable release versions while developing new features **Key characteristics in Diversion:** * Branch creation takes milliseconds, regardless of repository size * Branches are server-side (cloud-based) * All team members can see all branches * No file copying or duplication ## Understanding Branches vs Workspaces Before diving into branching, it's important to understand how branches relate to workspaces: | Concept | Purpose | Visibility | Typical Lifespan | | ------------- | ------------------------------- | ---------------- | ----------------------- | | **Branch** | Independent line of development | All team members | Days to weeks | | **Workspace** | Your local working environment | Only you | Entire project duration | **Think of it this way:** * **Branch** = Where the code lives (like `main`, `feature-ui`, `bugfix-123`) * **Workspace** = Your personal workbench (where you edit files locally) **Example workflow:** ```bash theme={null} # Your workspace points to the 'main' branch dv checkout main # Create a new feature branch dv branch -c feature-ui # Switch your workspace to the new branch dv checkout feature-ui # Make changes in your workspace # ... edit files ... # Commit to the feature-ui branch dv commit -a -m "Add new UI components" ``` [Learn more about workspaces →](/concepts/repo-branch-workspace) *** ## Creating Branches You can also [create branches in the Desktop App](/basic/working-in-parallel#creating-a-new-branch). ### Create a New Branch Create a branch from your current position: ```bash theme={null} dv branch -c feature-name ``` **What happens:** 1. Diversion creates a new branch pointing to your current commit 2. The branch is immediately available to all team members 3. Creation takes \~100ms regardless of repository size **Example:** ```bash theme={null} # Create a branch for a new feature dv branch -c feature-new-level # Create a branch for a bug fix dv branch -c bugfix-character-movement ``` ### Create a Branch from a Specific Commit ```bash theme={null} # First, find the commit ID dv log # Check out commit dv checkout # Create a new branch dv branch -c feature-name ``` ### List All Branches ```bash theme={null} dv branch ``` **Output example:** ``` * main feature-new-level bugfix-character-movement release-v1.0 ``` The `*` indicates your workspace's current branch. *** ## Switching Between Branches You can also [switch branches in the Desktop App](/basic/working-in-parallel#switching-branches). ### Checkout a Branch Switch your workspace to a different branch: ```bash theme={null} dv checkout feature-name ``` **What happens:** 1. Diversion updates your workspace files to match the target branch 2. Your local files change to reflect the branch's state 3. Any new commits will go to this branch **Example workflow:** ```bash theme={null} # Check which branch you're on dv status # Switch to main branch dv checkout main # Switch to feature branch dv checkout feature-new-level # Make changes and commit dv commit -a -m "Add level geometry" ``` **Before switching branches:** * Commit discard or [shelf](/core-concepts/shelving) your current changes * Diversion will warn you if you have uncommitted changes * Use `dv status` to check for pending changes *** ## Merging Branches You can also [merge branches in the Desktop App](/basic/working-in-parallel#how-to-merge). Merging integrates changes from one branch into another. Diversion supports smart merging with automatic conflict detection. ### Basic Merge Workflow **Goal:** Merge `feature-ui` into `main` First, check out the branch you want to merge **into**: ```bash theme={null} dv checkout main ``` Merge the feature branch into main: ```bash theme={null} dv merge feature-ui ``` If there are conflicts, Diversion will guide you through resolution: ```bash theme={null} # View conflicts dv status # After resolving conflicts in your editor dv commit -a -m "Merge feature-ui into main" ``` After merging, you can delete the feature branch: ```bash theme={null} dv branch -d feature-ui ``` ### How Merging Works Diversion uses **3-way merge** with common ancestor detection: ``` A---B---C (main) \ D---E (feature-ui) ``` **When you run `dv merge feature-ui` from main:** 1. Diversion finds the **common ancestor** (commit B) 2. Compares changes from B→C (main's changes) 3. Compares changes from B→E (feature's changes) 4. Intelligently combines both sets of changes 5. Creates a new merge commit: ``` A---B---C---M (main) \ / D---E (feature-ui) ``` **Benefits:** * Preserves history from both branches * Accurately detects conflicts * Maintains complete audit trail ### Merge Strategies **Regular Merge (Default):** * Preserves all commits from both branches * Creates a merge commit * Complete history visible in `dv log` ```bash theme={null} dv merge feature-name ``` **When to merge:** * You want complete history * Feature commits are significant milestones * You need to track who made each change *** ## Handling Merge Conflicts The Desktop App provides a visual conflict resolution tool — see [Merge Conflicts in the Desktop App](/basic/working-in-parallel#merge-conflicts). Merge conflicts occur when the same lines of code are changed in both branches. ### Conflict Detection Diversion prevents conflicts before they happen: **Real-time notifications:** * See who's editing which files * Get notified when teammates modify files you're working on * Coordinate changes before conflicts occur [Learn more about conflict prevention →](/concepts/conflicts) ### Resolving Conflicts When conflicts do occur, Diversion makes resolution straightforward: ```bash theme={null} dv merge feature-ui # Output: Conflict in src/player.cpp dv status # Shows: Conflicted files ``` Conflict markers show both versions: ```cpp theme={null} <<<<<<< HEAD (main) int speed = 100; ======= int speed = 150; >>>>>>> feature-ui ``` Edit the file to resolve the conflict: ```cpp theme={null} // Choose one side int speed = 150; // Or combine int speed = 125; // Compromise between branches ``` Commit the resolved merge: ```bash theme={null} dv commit -a -m "Merge feature-ui: resolve speed conflict" ``` ### Conflict Resolution Options **Accept one side completely:** Via Web UI or API: * Accept "ours" (keep main's version) * Accept "theirs" (use feature branch's version) * Accept all conflicts at once **Manual resolution:** * Edit files to combine changes * Commit when satisfied *** ## Branching Best Practices ### 1. Branch Naming Conventions Use descriptive, consistent names: **Good examples:** ```bash theme={null} feature/new-character-controller bugfix/inventory-crash hotfix/v1.2-save-bug release/v2.0 experimental/ai-pathfinding ``` **Naming patterns:** * `feature/` - New features * `bugfix/` - Bug fixes * `hotfix/` - Urgent production fixes * `release/` - Release branches * `experimental/` - Experimental work ### 2. Keep Branches Short-Lived **Why:** * Reduces merge conflicts * Easier to review changes * Faster integration **How:** * Merge feature branches within days, not weeks * Delete branches after merging * Create small, focused branches ### 3. Merge Frequently Merge `main` into your feature branch regularly: ```bash theme={null} # In your feature branch dv checkout feature-ui dv merge main # This keeps your feature up-to-date with main ``` **Benefits:** * Smaller, easier merges * Catch conflicts early * Feature stays compatible with latest main ### 4. Use Descriptive Commit Messages ```bash theme={null} # Good dv commit -m "Add character jump animation" # Better dv commit -m "Add character jump animation - Implemented 3-frame jump sequence - Added landing state transition - Fixed animation loop bug" ``` ### 5. Delete Merged Branches After merging, clean up: ```bash theme={null} # Delete local reference dv branch -d feature-ui # Branch history is preserved in main ``` *** ## Common Branching Workflows ### Feature Branch Workflow Best for: Teams developing multiple features simultaneously ```bash theme={null} # 1. Create feature branch from main dv checkout main dv branch -c feature/new-weapon # 2. Develop feature dv checkout feature/new-weapon # ... make changes ... dv commit -a -m "Add new weapon model" # 3. Keep feature updated with main dv merge main # 4. When ready, merge to main or create a Review dv checkout main dv merge feature/new-weapon # 5. Delete feature branch dv branch -d feature/new-weapon ``` ### Release Branch Workflow Best for: Managing multiple release versions ```bash theme={null} # Create release branch from main dv checkout main dv branch -c release/v1.0 # Bug fixes go to release branch dv checkout release/v1.0 dv commit -a -m "Fix critical save bug" # Merge fixes back to main dv checkout main dv merge release/v1.0 # Release branch stays for v1.0.x patches ``` ### Hotfix Workflow Best for: Urgent production fixes ```bash theme={null} # Create hotfix from release branch dv checkout release/v1.0 dv branch -c hotfix/save-crash # Fix the bug dv checkout hotfix/save-crash dv commit -a -m "Fix save crash in level 3" # Merge to release dv checkout release/v1.0 dv merge hotfix/save-crash # Also merge to main dv checkout main dv merge hotfix/save-crash # Delete hotfix branch dv branch -d hotfix/save-crash ``` *** ## Troubleshooting ### "Cannot switch branches: uncommitted changes" **Problem:** You have uncommitted changes in your workspace. **Solution:** ```bash theme={null} # Option 1: Commit your changes dv commit -a -m "WIP: save progress" # Option 2: Discard changes dv checkout --force branch-name # Careful: loses changes! # Option 3: Use shelving (save for later) # (Shelving guide coming soon) ``` ### "Merge conflict in multiple files" **Problem:** Many files have conflicts. **Solution:** 1. Resolve conflicts one file at a time 2. Use `dv status` to track progress 3. Consider accepting one side for non-critical files 4. Manually merge important files ### "Branch already exists" **Problem:** Branch name is taken. **Solution:** ```bash theme={null} # Use a different name dv branch -c feature/new-ui-v2 # Or delete the old branch first dv branch -d feature/new-ui dv branch -c feature/new-ui ``` *** ## CLI Reference **Branch Management:** ```bash theme={null} dv branch # List branches dv branch -c # Create branch dv branch -d # Delete branch dv branch -r # Rename branch dv checkout # Switch to branch ``` **Merging:** ```bash theme={null} dv merge # Merge branch ``` **Status:** ```bash theme={null} dv status # Show current branch and changes dv log # Show commit history dv diff # Show uncommitted changes ``` [Full CLI reference](/cmd-ref/branch) *** ## Related Resources **Core Concepts:** * [Repositories, Branches, and Workspaces](/concepts/repo-branch-workspace) * [Understanding Conflicts](/concepts/conflicts) * [How Syncing Works](/concepts/syncing) **Workflows:** * [Working in Parallel](/basic/working-in-parallel) * [Code Review](/basic/reviews) **CLI Reference:** * [branch command](/cmd-ref/branch) * [checkout command](/cmd-ref/checkout) * [merge command](/cmd-ref/merge) * [commit command](/cmd-ref/commit) *** **Last updated:** 2025-10-26 # FAQs Source: https://docs.diversion.dev/faqs Frequently asked questions about Diversion ## How do I transfer my account and resource ownership to a new email address? To transfer account and resource ownership, follow these steps: 1. Create a new account using the new email address. 2. Send [repository](basic/manage-project-access) and [organization](basic/organization-management#managing-an-organization) collaboration invitations to the new account from all relevant resources. 3. [Transfer ownership](basic/organization-management#transferring-repository-ownership) of the relevant repositories to the new account. 4. Once steps 1-3 are completed, contact our support team to request organization ownership transfer to the new account using one of the following methods: * **By email**: Send an email to [support](mailto:support@diversion.dev) from the old email address and CC the new email address. * **By support ticket**: Submit the ticket from the old account and include the new email address in the description. 5. After the transfer, remove the old account from both the repositories and the [organization](basic/organization-management#removing-users). 6. Create a new subscription from the new account, selecting the appropriate tier, storage, and user seats. 7. Cancel the subscription associated with the old account from **Plan & Billing** in the old account. 8. If you are a non-owner member of repositories and organizations, ask the owners to send an invitation to the new account. 9. Create a new local workspace for each repository, as each workspace is bound to an account. You can then delete the old workspace. 10. If you wish to delete your old account, contact our support team. ## How do I delete my account? Deleting your account will permanently delete all repositories you own. 1. If you own an organization, either transfer ownership to another member or remove all members from the organization. 2. If you own repositories with collaborators, transfer ownership to a collaborator or notify them that the repositories will be deleted. 3. Contact our support team to request account deletion. Include your account email address and confirm your approval to lose access and delete your repositories. 4. Your account will be deleted within 72 hours of your request. ## I'm using Mac and suddenly I got permission errors? This is a know macOS permission issue that occurs when a local workspace is located inside the Documents folder. On recent macOS versions, apps can lose access to Documents after system or app updates, resulting in the “permission denied” error. If your local workspace is located under the Documents folder, here are the steps to move the folder to avoid this error. 1. In Finder, create a new folder for your projects, for example:
/Users/your-username/Projects 2. In Diversion Desktop, under **Remote Repositories**, open the repo's **...** menu, select **Clone repo**, and set the target folder to:
/Users/your-username/Projects/ExampleProject 3. Once the clone is complete, ensure Unreal Engine is closed (if applicable) and move your existing project files from the old path into the new cloned workspace folder. 4. Open the project from the new location and verify the sync status in Diversion. It should now be able to scan and sync normally. ## I can't log in with Google / I can't log in with my password Your login method is fixed at sign-up: * If you signed up with **email and password**, you can only log in with email and password -- logging in with Google won't work, even if your Google address matches your account email. * If you signed up with **Google**, you can only log in with Google -- there is no password to reset. Linking a Google account to an existing email/password account (or vice versa) is currently not supported. Not sure which method you used to sign up? Contact our [support team](mailto:support@diversion.dev) and we'll check for you. If you need to switch login methods, the only workaround is to [delete your account](#how-do-i-delete-my-account) and sign up again using the desired method. This will permanently delete any repositories you own, so back up or transfer ownership first. ## Diversion won't open and Windows says "This app can't be run on your PC"? Windows error: This app can't run on your PC If Windows shows **"This app can't be run on your PC"** when you try to launch Diversion, reinstalling the desktop app resolves it. You don't need to uninstall first — just [download the latest installer](https://get.diversion.dev/win) and run it over your existing installation, then relaunch the app. If it still won't open after reinstalling, contact our [support team](mailto:support@diversion.dev). ## How do I suggest a feature or see the roadmap? You can see what we're building, vote on upcoming features, and submit your own feature requests on our [public roadmap](https://portal.productboard.com/diversion/1-diversion-public-roadmap/tabs/4-now). You can also open it from the app via your avatar menu -> **Feature request**. # Hard Locks Source: https://docs.diversion.dev/hard-locks Prevent conflicting edits by exclusively locking files and folders Hard locks give a user exclusive write access to a specific path in a repository. While [soft locks](/coming_from_perforce#soft-locking-vs-hard-locking) are non-blocking indicators that show when someone is editing a file, hard locks **prevent** other users from committing changes to the locked path until the lock is released. Hard locks are especially useful for binary files (such as `.uasset`, `.umap`, or `.fbx`) that cannot be merged and require exclusive editing. Hard locks are available on **Studio** and **Enterprise** plans. ## How Hard Locks Work * A lock is **per-repository** and **per-path** — each lock applies to a specific path in a specific repo. * A lock is tied to the **user** who created it. * Once a path is locked, **only the locking user** can commit changes to that path. * If another user edits a locked file locally, a **warning** is displayed but the edit is saved. However, **committing** those changes will be **blocked**. * Only the **locking user** or a **repository admin/owner** can release the lock. ## Locking and Releasing Paths ### Using the Desktop or Web App To lock a path, right-click the file or folder in the tree view and select **Lock** from the context menu. Lock option in the context menu Once locked, a lock icon appears next to the path in the tree view, indicating who holds the lock. Lock status indicator in the tree view To release a lock, right-click the locked path and select **Unlock** from the context menu. Only the user who created the lock or a repository admin/owner can release it. If the locking user is unavailable, contact a repo admin. ### Using the CLI Lock a path: ```bash theme={null} dv lock ``` Release a lock: ```bash theme={null} dv lock -d ``` List all locked paths in the repository: ```bash theme={null} dv lock ``` ## Auto-Lock Repository admins can configure file patterns (by extension) so that matching files are **automatically locked** when a user begins editing them. This removes the need for manual locking on common binary or unmergeable file types. ### How Auto-Lock Works * When a user edits a file that matches a configured pattern, Diversion automatically locks it for that user. * If the file is **already locked by another user**, auto-lock does not apply — the existing lock is preserved. Auto-lock is particularly useful for binary files like `.uasset`, `.umap`, or `.fbx` that cannot be merged and always require exclusive editing. ### Configuring Auto-Lock Patterns Auto-lock is a per-repository setting configured by a repo admin or owner. 1. Open the repository settings 2. Navigate to the **Hard Locks** settings 3. Add file extension patterns (e.g., `.uasset`, `.umap`, `.fbx`) 4. Save changes Auto-lock configuration in repository settings ## Auto-Release Locks can be automatically released when the locking user commits changes on specific branches. This is configured alongside the auto-lock settings. ### How Auto-Release Works * A repository admin defines which **branches** trigger auto-release (e.g., `main`, `develop`). * When a user commits or merges to one of these branches, their locked files included in the commit are automatically released. Auto-release branch configuration in repository settings ## Viewing Locked Paths * **Desktop or Web App:** Lock icons appear in the tree view next to locked paths. Hover over the icon to see who holds the lock. * **CLI:** Run `dv lock` with no arguments to list all locks in the repository. ## Permissions | Action | Who can do it | | ------------------------------------ | -------------------------------------- | | Lock a path | Any user with write access | | Unlock own lock | The locking user, repo admin, or owner | | Unlock another user's lock | Repo admin or owner | | Configure auto-lock/release settings | Repo admin or owner | # Plugins Source: https://docs.diversion.dev/integrations/overview Official and community-built ## Official Plugins | Plugin | Description | | --------------------------------------------- | ------------------------------------------------------------------------- | | [Unreal Engine](/unreal/unreal-engine-plugin) | First-class source control integration directly within the Unreal Editor. | ## Community Plugins We're grateful to have an amazing community of developers who build and maintain integrations for Diversion. | Plugin | Author | Description | | ------------------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | [Jenkins SCM](https://plugins.jenkins.io/diversion-scm/) | Ian Bain | A unified Jenkins SCM plugin that integrates with Diversion repositories, providing both pipeline checkout and Global Pipeline Library support. | | [TeamCity VCS](https://github.com/midgen/teamcity-diversion) | midgen | TeamCity VCS plugin for Diversion version control system. | Interested in building a Diversion integration? Check out our [API documentation](/api-reference/introduction) and join our [Discord community](https://discord.com/invite/HDAGJvgkuT). # Introduction Source: https://docs.diversion.dev/introduction Version Control for Unreal Scale. Fast. Effortless. Affordable. Diversion - Version Control for Unreal Scale Diversion is a version control system designed for large-scale projects with massive binary files. Changes automatically sync across your team—no manual push or pull required. Built for game development, archviz, virtual production, and other asset-heavy workflows. This documentation covers everything from installation to advanced workflows. Start with the Quickstart if you're new, explore the CLI Reference for command details, or jump into Collaborate to set up your team. } href="/quickstart"> Get up and running with Diversion in minutes. Install, create your first repository, and start working. } href="/unreal/unreal-engine-plugin"> Learn how to use Diversion with Unreal Engine. Plugin setup, merge conflicts, and Horde integration. } href="/basic/reviews"> Work together with your team. Code reviews, branching, permissions, and organization management. } href="/cmd-ref/about-cmd"> Complete command-line reference for power users. All commands, flags, and examples. # Quickstart Source: https://docs.diversion.dev/quickstart Get started with Diversion in 3 simple steps Get up and running with Diversion in just 3 simple steps: install, create an account, and create your first repository. Your changes will automatically sync with your team—no manual push or pull required. For advanced workflows like branching, team collaboration, and conflict resolution, explore our [Basic Workflows](/basic/start-using-diversion) section. This guide uses the Desktop App for Windows and macOS. You can also use the [CLI](/cmd-ref/about-cmd), [Unreal Engine Plugin](https://www.unrealengine.com/marketplace/en-US/product/diversion), or [WebUI](https://app.diversion.dev/). Driving Diversion from an AI coding agent (Claude Code, Cursor, Codex)? See the [Agent Quickstart](/agent-quickstart). [Download the installer](https://get.diversion.dev/win) and follow the instructions. By installing Diversion, you agree to the [Terms of Service](https://www.diversion.dev/terms-of-service) After installing, launch the Diversion desktop application. Create a new account or sign in with Google. Create Repo After creating your account, or if you already have one, log in. Diversion will show you an option to create a new repository if you don't have any. Click on `New repository`. Create Repo You have the option to create a repository from an existing folder or create a new folder. Choose `Create New Folder` and specify the directory on your computer where you want your repository saved. Create Repo Your newly created repository is now listed in both the Local Workspaces and Remote Repositories tabs. A local workspace means it exists on your machine and you can start using it locally. Create Repo Navigate to the folder you created for your repository and add your project files. You can drag and drop files, create new ones, or copy your existing project into this folder. Diversion automatically tracks all changes in the background—no need to manually "add" files like in Git. Open the Diversion desktop app to see your changes tracked in real-time. Once you've made changes you want to save, open the Diversion desktop app and review your modified files. Write a descriptive commit message explaining what you changed, then click the "Commit" button. Your changes are automatically synced to the cloud and shared with your team—no push or pull required! Open a terminal and run: ```bash theme={null} curl -sL https://get.diversion.dev/unix | bash ; export PATH="$HOME/.diversion/bin:$PATH" ``` By installing Diversion, you agree to the [Terms of Service](https://www.diversion.dev/terms-of-service) After installing, launch the Diversion desktop application. Create a new account or sign in with Google. Create Repo After creating your account, or if you already have one, log in. Diversion will show you an option to create a new repository if you don't have any. Click on `New repository`. Create Repo You have the option to create a repository from an existing folder or create a new folder. Choose `Create New Folder` and specify the directory on your computer where you want your repository saved. Create Repo Your newly created repository is now listed in both the Local Workspaces and Remote Repositories tabs. A local workspace means it exists on your machine and you can start using it locally. Create Repo Navigate to the folder you created for your repository and add your project files. You can drag and drop files, create new ones, or copy your existing project into this folder. Diversion automatically tracks all changes in the background—no need to manually "add" files like in Git. Open the Diversion desktop app to see your changes tracked in real-time. Once you've made changes you want to save, open the Diversion desktop app and review your modified files. Write a descriptive commit message explaining what you changed, then click the "Commit" button. Your changes are automatically synced to the cloud and shared with your team—no push or pull required! There is currently no Linux desktop app. The Linux workflow uses the CLI exclusively. You can also use the [WebUI](https://app.diversion.dev/) for browsing repositories, reviewing changes, and managing collaboration. Open a terminal and run: ```bash theme={null} curl -sL https://get.diversion.dev/unix | bash ; export PATH="$HOME/.diversion/bin:$PATH" ``` To make the path permanent, add it to your `.bashrc` or `.zshrc`: ```bash theme={null} echo 'export PATH="$HOME/.diversion/bin:$PATH"' >> ~/.bashrc ``` By installing Diversion, you agree to the [Terms of Service](https://www.diversion.dev/terms-of-service) Run the following command to open the WebUI and create your account: ```bash theme={null} dv login ``` A browser window will open so you can authenticate. Once logged in, you're good to go! Create account Create a new repository using the [init command](/cmd-ref/init), or clone an existing repository you've been added to using the [clone command](/cmd-ref/clone). Make changes to your files as usual. Diversion will track your changes in the background. To check the status of your changes: ```bash theme={null} dv status ``` Once you're ready to save a version of your progress: ```bash theme={null} dv commit -a -m "your commit message" ``` By default, Diversion automatically syncs committed changes across the team. You don't need to push or pull manually, just commit your work and it gets shared. You're now using Diversion on Linux. For the full list of CLI commands, check out the [CLI Reference](/cmd-ref/about-cmd). ## What's Next? Now that you're set up, explore these guides to get the most out of Diversion: Invite collaborators and manage permissions Bring your existing codebase into Diversion Work on features in parallel without conflicts Install the Unreal Engine plugin # SlothBot Source: https://docs.diversion.dev/slothbot Diversion's AI coding assistant - research preview ## What SlothBot Is SlothBot is Diversion's AI agent. Today it's a coding agent built into the Diversion desktop app. Over time SlothBot will grow to cover more AI capabilities; coding is the first. SlothBot is a research preview feature. The feature, pricing, and availability may change based on feedback. If your organization is enrolled in the research preview, the **SlothBot pane** appears in the workspace view of the Diversion desktop app. Don't see it? [Reach out](mailto:hello@diversion.dev?subject=SlothBot%20research%20preview) and we'll enable it for you. ## The Coding Agent The coding agent runs **locally on your machine** as a subprocess of the Diversion agent. It uses a trusted third-party LLM provider for completions, routed through Diversion (no API key needed on your end). The SlothBot pane in the Diversion desktop app The pane shows the active session and a small header toolbar: * **New chat** - start a fresh session * **Session history** - browse past sessions * **Cancel session** - stop the agent mid-run; this terminates the entire session, not the current message (visible while a session is active) * **Full width** - expand the pane across the workspace view * **Collapse** - hide the pane ## What You Can Do With It Prompt examples grouped by intent: "What does `Assets/Scripts/Player/PlayerController.cs` do?" "Show me where damage and health are calculated." "Walk me through how the save system serializes player state." "How does this Blueprint connect to the C++ side?" "Write a coroutine that fades the screen to black over 2 seconds." "Add a damage falloff curve to the AOE spell." "Rename `playerHealth` to `currentHealth` everywhere it's used." "Add null checks to every `GetComponent` call in this file." Drop a file path or class name into your prompt to anchor SlothBot's attention. The more specific you are, the better the answer. ## What It Can Access SlothBot runs as a subprocess on your machine, with the same permissions as your user account. By default, it works inside the current Diversion workspace, but it has the same reach as you do on the host: * **Read, edit, move, and delete files** anywhere your user can - workspace files, but also files outside the workspace if you point it there. * **Run shell commands** on your machine. * **Fetch web pages** (for example, to look up documentation). SlothBot is not sandboxed. Diversion does not restrict the filesystem paths or commands it can touch. Treat SlothBot's actions like commands you'd run yourself. It can install dependencies, modify your environment, and touch files outside the workspace - review prompts that hand it that kind of scope, and review the diff before committing. State-changing actions (commits, branches, file deletes) are covered separately - see [Review and Accept Changes](#review-and-accept-changes). ## Privacy * Prompts, plus the file context SlothBot needs to answer them, are sent to a trusted third-party LLM provider through Diversion. No API key needed on your end. * Diversion does **not** train models on your data, and the LLM provider does not train on prompts sent through this API. * Diversion logs **token counts** (not prompt content) for fair-use accounting. ## Limits and Cost SlothBot is a research preview. There is no published pricing. Fair-use guardrails today: * **Token budget**: each organization has a rolling 6-hour token budget. When it's exhausted, follow-up requests fail with a budget-exceeded error until the rolling window advances. Wait for the budget to refresh, or try a smaller follow-up prompt. * **Research preview access**: SlothBot is enabled per organization. If the pane doesn't appear, your organization isn't enrolled yet - [request access](mailto:hello@diversion.dev?subject=SlothBot%20research%20preview). * **Limits may change** without notice while in research preview. ## Known Limitations * **May make wrong assumptions** about your repo's structure or your intent. Read the diff before you commit. * **No mid-action stop**. You can see chat output and tool calls live, but you can't stop a single tool call mid-execution. If SlothBot is going down the wrong path, cancel the whole session and start a new one. ## Review and Accept Changes SlothBot edits files directly in your workspace as it works, and can run state-changing commands - commits, branch operations, resets, file deletes - if asked. It's prompted to describe its intended action before running it, though that's not guaranteed. Treat every change as your responsibility: * Inspect uncommitted changes with `dv diff` (or the desktop app's change list) before committing. * Land changes yourself with `dv commit -a -m ""` when you're ready, or discard them with `dv reset -f ` (or `dv reset -f --all`). * Approved commits sync to the cloud immediately - there is no separate push step. See [What to do with your changes](/basic/what-to-do-with-your-changes) for the full workflow. ## Disable SlothBot for Your Organization Organization admins can turn SlothBot off for the entire organization. The setting lives in **Preferences** and applies to every member. 1. Open the profile menu and go to **Settings**. 2. In the left sidebar, under **Organization**, select **Preferences**. 3. Pick the organization using the organization selector in the top-left of the global bar (if you manage more than one). 4. Toggle **SlothBot** off. Confirm in the dialog. The SlothBot toggle on the organization Preferences page Only organization admins see this setting. Disabling stops the agent from running for all members on their next session. You can re-enable it any time from the same screen. ## Troubleshooting SlothBot is enabled per organization during the research preview. If your organization isn't enrolled, the pane won't show. [Request access](mailto:hello@diversion.dev?subject=SlothBot%20research%20preview) and we'll enable it for you. If your organization was enrolled but the pane stopped appearing, an admin may have disabled SlothBot in **Preferences** - see [Disable SlothBot for Your Organization](#disable-slothbot-for-your-organization). An organization admin can disable it for everyone under **Settings -> Organization -> Preferences**. See [Disable SlothBot for Your Organization](#disable-slothbot-for-your-organization). Your organization hit the rolling 6-hour token budget. Wait for the budget to refresh, or try a smaller follow-up prompt. The budget resets continuously, not at a fixed time. The LLM provider returned an error. Usually transient - retry the prompt. If it persists for more than a few minutes, the provider may be having an outage. There is no per-tool-call stop today - cancel the whole session and start a new one. A more specific follow-up prompt usually steers the agent back on track. Use the **New chat** button in the pane header. Past sessions remain in the session history. ## Send Feedback SlothBot is actively developed, and your feedback shapes what we build next. When the in-app **Send Feedback** button is available on the SlothBot pane, that's the fastest way to reach us - it auto-attaches your session ID, organization, and version so we don't have to chase context. In the meantime, [email us](mailto:hello@diversion.dev?subject=SlothBot%20feedback). # System Messages Source: https://docs.diversion.dev/system-messages System messages for billing, payment issues, and account status updates. Diversion displays system messages to keep you informed about your account status and subscription. ## Trial Period > "Enjoy Diversion Professional free trial! (X days left). Don't worry—you won't be charged." Free Trial Notification You're currently in your free trial period. You have full access to all Professional tier features. No payment is required during the trial. ## Plan Limits ### User Plan Limit > "Your team has X users, while your current plan includes Y users..." **Team member view:** User Plan Limit Notification **Organization owner view:** User Plan Owner Notification Your organization has exceeded its user allowance. To continue using Diversion: * **Organization owners**: Click on your avatar and select Plan & Billing to purchase additional seats * **Team members**: Contact your organization owner to upgrade the plan ### Storage Plan Limit > "Your team is using X GB, while your current plan includes Y GB of storage..." **Team member view:** Storage Plan Limit Notification **Organization owner view:** Storage Plan Owner Notification Your organization has exceeded its storage. To continue using Diversion: * **Organization owners**: Click on your avatar and select Plan & Billing to purchase additional storage * **Team members**: Contact your organization owner to upgrade the plan ### Storage and User Plan Limit > "Your team is using A GB and has X users, while your current plan includes B GB of storage and Y users..." **Team member view:** Storage and User Plan Limit Notification **Organization owner view:** Storage and User Plan Owner Notification Your organization has exceeded both its storage and user allowance. To continue using Diversion: * **Organization owners**: Click on your avatar and select Plan & Billing to purchase additional storage and seats * **Team members**: Contact your organization owner to upgrade the plan ## Payment Issues > "Your team has a payment issue. To continue using Diversion, please update your payment method." **Team member view:** Payment Notification **Organization owner view:** Payment Owner Notification There's a problem processing payment for your subscription. To continue using Diversion: * **Organization owners**: Click on your avatar and select **Plan & Billing** to update the payment method * **Team members**: Contact your organization owner to update the payment method ## Trial Ended > "Your free trial has ended. To continue using Diversion, please purchase seat(s) for your plan." Trial Ended Notification Your trial period has expired. Click on your avatar and select **Plan & Billing** to choose a plan and continue using Diversion. **Note**: [Contact support](mailto:support@diversion.dev) if you need further assistance. # Unity Best Practices with Diversion Source: https://docs.diversion.dev/unity/unity-best-practices Learn how to use Diversion effectively with Unity for seamless version control Unity works seamlessly with Diversion, providing powerful version control for your game projects without the complexity of traditional VCS systems. You can use the [Diversion Unity Plugin](/unity/unity-plugin) for an integrated experience, or work with the desktop app and CLI. ## Getting Started ### Prerequisites Before setting up Diversion with Unity, ensure you have: * Diversion installed and signed in (see [Quickstart](/quickstart)) * Unity Hub and Unity Editor installed * Your Unity project created or ready to import ### Initial Setup Open your Unity project and navigate to `Edit > Project Settings`: * Set **Version Control Mode** to `Visible Meta Files` * Set **Asset Serialization Mode** to `Force Text` Unity Project Settings Unity Project Settings These settings ensure Unity's meta files are visible to Diversion and that assets are stored in a text-based format for better conflict resolution. Diversion automatically creates a `.dvignore` file with Unity-specific patterns when initializing a Unity project. You typically don't need to modify it. The default `.dvignore` for Unity projects includes common patterns like: ```ini theme={null} # Unity generated folders .utmp/ /[Ll]ibrary/ /[Tt]emp/ /[Oo]bj/ /[Bb]uild/ /[Bb]uilds/ /[Ll]ogs/ /[Uu]ser[Ss]ettings/ /[Mm]emoryCaptures/ /[Rr]ecordings/ # Autogenerated Jetbrains Rider plugin /[Aa]ssets/Plugins/Editor/JetBrains* *.DotSettings.user # Visual Studio cache .vs/ # Gradle cache directory .gradle/ # Autogenerated VS/MD/Consulo solution and project files ExportedObj/ .consulo/ *.csproj *.unityproj *.sln *.suo *.tmp *.user *.userprefs *.pidb *.booproj *.svd *.pdb *.mdb *.opendb *.VC.db # Unity3D generated meta files *.pidb.meta *.pdb.meta *.mdb.meta # Unity3D crash reports sysinfo.txt mono_crash.* # Builds *.apk *.aab *.unitypackage *.unitypackage.meta *.app # Crashlytics generated crashlytics-build.properties # Addressables /ServerData/ /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* /[Aa]ssets/AddressableAssetsData/link.xml* /[Aa]ssets/Addressables_Temp* /[Aa]ssets/[Ss]treamingAssets/aa.meta /[Aa]ssets/[Ss]treamingAssets/aa/* # Visual Scripting generated files /[Aa]ssets/Unity.VisualScripting.Generated/ # Test scenes (Unity Test Framework) /[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity* ``` You can add project-specific patterns if needed, but the defaults cover most Unity use cases. Open the Diversion desktop app and create a new repository from your Unity project folder, or initialize via CLI: ```bash theme={null} cd /path/to/your/unity/project dv init ``` Diversion will automatically recognize your Unity project structure and begin tracking the appropriate files, including the appropriate `.dvignore` patterns. For detailed instructions on creating repositories, see the [Quickstart guide](/quickstart) or [Start using Diversion](/basic/start-using-diversion). After initialization, commit your Unity project: ```bash theme={null} dv commit -m "Initial Unity project setup" ``` Remember: with Diversion, this single command handles everything - no need for separate add, commit, and push commands! Learn more about commits and Diversion's auto-sync workflow in the [What to do with your changes](/basic/what-to-do-with-your-changes). ## Essential Unity-Diversion Workflow ### Meta Files Management Always commit meta files together with their corresponding assets. Missing meta files will break asset references and cause errors for your team. Unity generates `.meta` files for every asset containing crucial information like: * **GUID** (Globally Unique Identifier) for asset references * Import settings and configurations * Platform-specific settings **Best Practices:** * When adding new assets, ensure both the asset AND its `.meta` file are committed together * If you see missing script references or broken prefabs, check if meta files were properly synced * Never manually edit or delete meta files outside Unity ### File Operations Always perform file system operations (move, rename, duplicate, delete) through the Unity Editor, never through your OS file explorer. When Unity moves or renames files, it: * Updates all internal references automatically * Maintains GUID connections in meta files * Ensures project integrity **Correct workflow:** 1. Open Unity Editor 2. Use the Project window to rename/move/delete assets 3. Save the project (`Ctrl+S` or `Cmd+S`) 4. Commit changes with Diversion ## Scene Management & Conflict Prevention ### Leverage Diversion's Conflict Prevention Unlike Git, Diversion proactively prevents conflicts before they happen: Before editing a scene, open the Diversion desktop app and look for the **exclamation mark icon** (!) in the file tree. This warns you when someone else is currently editing the same files. Potential Conflicts Warning If you see a potential conflict warning, coordinate with your teammate before making changes. Diversion's real-time notifications help you avoid stepping on each other's toes. ### Scene Organization Best Practices Break large levels into multiple smaller scenes that load additively: ```csharp theme={null} // Load scenes additively at runtime SceneManager.LoadSceneAsync("Environment", LoadSceneMode.Additive); SceneManager.LoadSceneAsync("Lighting", LoadSceneMode.Additive); SceneManager.LoadSceneAsync("Gameplay", LoadSceneMode.Additive); ``` Benefits: * Multiple team members can work on different aspects simultaneously * Smaller scenes = fewer conflicts * Better performance through selective loading Convert reusable game objects into prefabs: * Use **Prefab Variants** for different configurations of the same object * Leverage **Nested Prefabs** for complex hierarchies * Edit prefabs in isolation using Prefab Mode This reduces scene file changes and makes conflicts easier to resolve when they do occur. ## Daily Workflow Best Practices ### 1. Start Your Day Right Open the Diversion desktop app to: * Check for any uncommitted changes from your previous session * Look for exclamation marks (!) on files you plan to edit (potential conflicts) * See recent commits from your team in the commit history ```bash theme={null} # Or use CLI to check your workspace status dv status ``` ### 2. Commit Frequently With Diversion's instant sync, frequent commits benefit everyone: * **After creating new features**: New scripts, prefabs, or materials * **After scene changes**: Level design updates or lighting adjustments * **Before switching tasks**: Keep work organized and traceable * **End of day**: Never leave uncommitted changes overnight ### 3. Write Meaningful Commit Messages Good examples: * "Add player jump mechanic with double-jump support" * "Update level 3 lighting and post-processing" * "Fix enemy AI pathfinding in narrow corridors" Avoid: * "Updated stuff" * "Bug fix" * "WIP" ### 4. Handle Large Assets Diversion excels at large files, so you can: * **Use higher quality assets**: Keep uncompressed source files alongside compressed versions * **Store multiple texture resolutions**: Maintain 4K/8K textures without worrying about file size * **Include uncompressed audio**: Store both WAV/FLAC masters and compressed formats for different platforms * **Create comprehensive atlases**: Build larger, more efficient texture atlases without VCS limitations * **Version binary files freely**: PSDs, FBX files, and other large assets are handled as efficiently as code ## Team Collaboration ### Branch Strategy Create branches for significant features or experiments: ```bash theme={null} dv branch create feature/new-inventory-system ``` Branches in Diversion are instant and lightweight, regardless of project size. Make your changes without affecting the main branch. Diversion's auto-sync keeps your branch updated. Once your feature is complete and tested, use Diversion's built-in review feature to get feedback from teammates before merging. Open the Diversion desktop app to create a review and merge your branch when approved. Learn more about code reviews and the review workflow in the [Review documentation](/basic/reviews). ## Common Issues & Solutions ### Missing Script References **Problem**: "The associated script cannot be loaded" **Solution**: 1. Check if the script's `.meta` file was committed 2. Verify the GUID in the meta file matches prefab references 3. If missing, have the original creator commit their meta file ### Broken Prefab Connections **Problem**: Prefab shows as disconnected or missing **Solution**: 1. Never modify prefab files outside Unity 2. Use Prefab Mode for all prefab edits 3. If broken, revert the prefab and reapply changes through Unity ### Scene Conflicts **Problem**: Two people edited the same scene **Solution**: 1. Use Diversion's potential conflict warnings to prevent this 2. If it happens, coordinate to manually merge changes 3. Consider breaking the scene into smaller subscenes ## Best Practices Summary * Commit meta files with their assets * Use Unity Editor for all file operations * Check potential conflicts before editing scenes * Commit frequently with clear messages * Use prefabs and multi-scene architecture * Configure project settings for text serialization * Never delete or edit meta files manually * Don't move files outside Unity Editor * Avoid working on the same scene simultaneously * Don't commit Library or Temp folders * Never change asset GUIDs * Don't ignore conflict warnings ## Troubleshooting If you encounter issues, check: 1. Unity project settings (Visible Meta Files, Force Text serialization) 2. `.dvignore` file is properly configured 3. All team members are using the same Unity version 4. Meta files are being tracked and committed For additional support, visit the [Diversion Discord](https://discord.gg/diversion?utm_source=docs\&utm_medium=unity-best-practices) or contact [support@diversion.dev](mailto:support@diversion.dev). # Unity Plugin Source: https://docs.diversion.dev/unity/unity-plugin Use Diversion directly from the Unity Editor The Diversion Unity plugin brings version control directly into the Unity Editor. View file statuses, commit changes, and receive real-time conflict warnings - all without leaving your project. ## Prerequisites Before using the plugin, ensure you have: * **Unity 6** (6000.0.0f1) or later * **Diversion Desktop app** installed, running, and signed in ([Quickstart](/quickstart)) * Your Unity project initialized as a Diversion repository (via Desktop app or CLI) ## Installation The Unity plugin is now in open beta. Get it [here](https://get.diversion.dev/unity-plugin/com.diversion.vcs-0.1.5.tgz). This is an early release, and your feedback will help us continue improving the plugin. We'll update this page regularly as we move toward the official launch. Join our [Discord server](https://discord.gg/S8WZBczKnY) to get early access, provide feedback, and connect with the community. Once you have access to the plugin: Download the plugin package from the link provided in Discord. In Unity, go to `Window > Package Management > Package Manager`. Click the `+` button in the top-left corner and select `Add package from tarball...`. Navigate to your downloaded file and select it. Unity will install the plugin automatically. ## Configuration After installing the plugin, configure it to use Diversion as your version control provider. Go to `Edit > Project Settings > Version Control`. From the `Mode` dropdown, select `Diversion`. Expand the `Diversion` section under Version Control to view the Diversion settings panel. It shows your connection status: * **Connected** - Ready to use * **Agent Not Running** - Start the Diversion Desktop app * **Not a Workspace** - Initialize your project as a Diversion repository via the Desktop app or CLI Once connected, you'll see your repository name, current branch, and workspace ID. ## The Diversion Window Access the main Diversion window via `Window > Diversion`. This is your central hub for version control operations. ### Header Bar The header displays: * **Branch** - The active branch name * **Status** - Sync state (Synced, Syncing, or Paused) * **Refresh button** - Manually refresh the connection and file status * **Settings button** - Opens Version Control settings ### Changes List The changes section shows all modified files in your workspace: * **Select All toggle** - Quickly select or deselect all files * **File count** - Total number of changed files * **View in Desktop** - Open Diversion Desktop to view detailed diffs * **Reset All** - Discard all uncommitted changes Each file row shows its path, status, and a checkbox for selection. ### Commit Panel At the bottom of the window: * **Commit Message** - Enter a description of your changes * **Reset Selected** - Discard changes for selected files only * **Commit** - Commit the selected files with your message ### File Status Icons Files in both the Diversion window and the Project window show status icons: * **Green circle (+)** - Added file * **Orange circle** - Modified file * **Red circle (-)** - Deleted file * **Yellow circle (!)** - Potential conflict with another user's changes ## Conflict Prevention Diversion helps prevent merge conflicts by alerting you when teammates are editing the same files. ### Opening Files When you double-click to open an asset that another team member is currently editing, a warning dialog appears showing: * Who is editing the file * Which branch they're working on * When they last modified it You can choose to **Open Anyway** or **Cancel**. ### Saving Files When saving files with potential conflicts, you'll see a dialog with three options: * **Save Anyway** - Save all files regardless of conflicts * **Cancel** - Don't save any files * **Skip Conflicted** - Save only files without conflicts ### Disabling Warnings If you prefer not to see conflict warnings, you can disable them in the settings: 1. Go to `Edit > Project Settings > Version Control` 2. Expand the `Diversion` section 3. Uncheck **Show Conflict Warnings** Even with warnings disabled, the yellow conflict icons (!) still appear in the Project window to help you identify files being edited by others. ## Auto-Reload Behavior When external changes are detected (such as switching branches, resetting files from the Desktop app, or incoming commits from teammates) the plugin automatically refreshes Unity's Asset Database and reloads open scenes. This ensures your Unity Editor stays in sync with the latest files without manual intervention. If you have unsaved changes in your scenes, Unity will prompt you to save before reloading. Your unsaved work will not be lost. To disable automatic scene reloading, uncheck **Auto-Reload Scenes** in the settings. ## Play Mode Sync The plugin automatically pauses sync when entering Play Mode and resumes when exiting. This prevents file changes from teammates from disrupting your testing session. When you exit Play Mode, sync resumes automatically and any changes that arrived while paused will be applied. ## Settings Configure the plugin via `Edit > Project Settings > Version Control > Diversion`. | Setting | Default | Description | | -------------------------- | ------- | ------------------------------------------------------------------ | | **Auto-Refresh State** | On | Periodically refresh connection and file status | | **Auto-Reload Scenes** | On | Reload open scenes when external changes are detected | | **Show Conflict Warnings** | On | Show dialogs when opening or saving files with potential conflicts | ### Quick Actions The settings panel also provides buttons for common actions: * **Open Diversion Window** - Opens the main plugin window * **Open Diversion Desktop** - Launches the Diversion Desktop app * **Refresh Connection** - Manually refresh the agent connection * **Documentation** - Opens this documentation ## Troubleshooting ### Agent Not Running **Problem**: The plugin shows "Agent Not Running" status. **Solution**: 1. Start the Diversion Desktop app 2. Make sure you're logged in 3. Click **Refresh Connection** in the plugin settings ### Not a Workspace **Problem**: The plugin shows "Not a Workspace" status. **Solution**: 1. Open the Diversion Desktop app 2. Create a new repository from your Unity project folder, or clone an existing repository 3. The plugin will automatically detect the workspace ### Files Not Showing in Changes List **Problem**: Modified files don't appear in the Diversion window. **Solution**: 1. Make sure files are saved (`Ctrl+S` / `Cmd+S`) 2. Click the Refresh button in the Diversion window 3. Check that the files aren't excluded by your `.dvignore` file ### Scene Not Reloading After External Changes **Problem**: Unity doesn't reload scenes after teammates' changes arrive. **Solution**: 1. Check that **Auto-Reload Scenes** is enabled in settings 2. If you have unsaved changes, Unity waits for you to save first 3. Try clicking **Refresh Connection** manually # Set up Horde with Diversion (Windows, UE5 Source) Source: https://docs.diversion.dev/unreal/horde-setup Quickstart for wiring Diversion SCM to Horde and preparing a UE5 source repository for Horde CI. Horde integration is available on the **[Studio](https://www.diversion.dev/pricing)** and **[Enterprise](https://www.diversion.dev/pricing)** plans. Please [contact us](mailto:support@diversion.dev) in order to receive a copy of the Diversion Horde installation files. ## Prerequisites * Admin access to your **Horde Server** and **Horde Agent** machines (Windows). * Access to **UE source on GitHub** via your Epic↔GitHub linked accounts. This is a general Horde requirement, as Horde build steps require access to the engine source and tools such as UAT & UBT. **This guide assumes adept familiarity with Horde and its general setup process.** *** ## 1) Install & sign in to Diversion (Server + Agents) 1. Run the Diversion for Windows installer on the Horde Server and on **every Horde Agent**. 2. Launch Diversion and sign in on both Server and Agents so the integration has proper access to the UE5 source repository. *** ## 2) Prepare a UE5 source repo in Diversion (Windows) ### 2.1 Clone Unreal Engine source Follow Epic’s instructions to gain GitHub access and clone UE: * [UE on GitHub](https://www.unrealengine.com/en-US/ue-on-github) * [Downloading Unreal Engine Source Code](https://dev.epicgames.com/documentation/en-us/unreal-engine/downloading-source-code-in-unreal-engine) ### 2.2 Remove `.gitignore` files from the cloned UE repo Run **from the UE repo root** to avoid Git‑specific ignore behavior interfering with Diversion tracking. ```cmd theme={null} for /r %f in (.gitignore) do @del "%f" ``` You can remove the `.gitignore` files by any method you prefer (File Explorer search + delete, PowerShell, third‑party tools, etc.). The CMD loop above is our recommended approach because it’s recursive, robust, and low‑friction on Windows, it handles nested folders reliably and avoids common globbing quirks. Just make sure you run it from the UE repo root. ### 2.3 Create `.dvignore` (before Diversion init) Create **`.dvignore`** at the UE repo root with this starter (tune for your studio): ```ini theme={null} # Epic's .dvignore file (converted from gitignore) # Note: Diversion tracks directories as well as files # - Uses same glob patterns as gitignore # - ** pattern for recursive directory matching # - Patterns are relative to .dvignore location # Ignore root Visual Studio solution files only *.sln .p4sync.txt # Visual Studio temp files *.suo *.opensdf *.sdf # Engine DerivedDataCache /Engine/DerivedDataCache/* **/DerivedDataCache/Boot.ddc **/DerivedDataCache/**/*.udd # Ignore all Intermediate and Saved directories **/Intermediate/ **/Saved/ # UBT configuration /Engine/Programs/UnrealBuildTool/ *.uatbuildrecord *.tmp # Build output **/obj/ *.csprojAssemblyReference.cache # UBT log files /Engine/Programs/UnrealBuildTool/*.txt # Python cache *.pyc __pycache__/ # JetBrains IDE .idea/ !.idea/runConfigurations/ .gradle/ # HoloLens WMRInterop autogenerated files /Engine/Source/ThirdParty/WindowsMixedRealityInterop/packages/ /Engine/Source/ThirdParty/WindowsMixedRealityInterop/MixedRealityInteropHoloLens/Generated Files/ /Engine/Source/ThirdParty/WindowsMixedRealityInterop/MixedRealityInteropHoloLens/x64/ /Engine/Source/ThirdParty/WindowsMixedRealityInterop/MixedRealityInteropHoloLens/ARM64/ /Engine/Source/ThirdParty/WindowsMixedRealityInterop/MixedRealityInterop/x64/ /Engine/Source/ThirdParty/WindowsMixedRealityInterop/MixedRealityInterop/ARM64/ # macOS Finder files .DS_Store # VS Code workspace files *.code-workspace .vs ``` Create the `.dvignore` **before** you initialize the Diversion repo for easier and faster initial scan. The `.dvignore` must be under the root of the repo. ### 2.4 Run UE setup scripts (Windows) From the UE source root, run: ```cmd theme={null} Setup.bat GenerateProjectFiles.bat ``` ### 2.5 Initialize a Diversion repo for UE 1. Initialize a Diversion repository **at the UE repo root** (Diversion CLI or UI). 2. Verify `.dvignore` is applied (caches/intermediates remain untracked). ### 2.6 Add your UE **project** to this source tree Place your game project (that should compile against this source engine) in the expected path (often the UE repo root or a sibling path your BuildGraph expects). Commit required files to Diversion. *** ## 3) Point your Horde stream at a Diversion repo/branch Do this **after** your UE5 source repository is prepared (Section 2). Edit your stream config (`*.stream.json`) under the Horde config directory: * `C:\\ProgramData\\Epic\\Horde\\Server\\` Ensure the **`name`** field targets your Diversion repo and branch: ```json theme={null} // Diversion‑required: set the repo id and branch name "name": "///" ``` > If your configs are split (globals → project → stream), place `name` in the **stream** JSON that represents your UE source stream. *** ## 4) Configure Horde for your UE source stream 1. Confirm your Horde config files live under `C:\\ProgramData\\Epic\\Horde\\Server\\`. 2. Ensure your project (`*.project.json`) references your stream (`*.stream.json`). 3. In the stream JSON, set the Diversion repo and branch mapping (*see Section 3*), then define the proper job templates (BuildGraph) and other general Horde requirements. 4. Start with a minimal Editor‑only BuildGraph job to validate the pipeline was set correctly. > Horde’s config stack is **Globals → Projects → Streams**. Using the `.project.json`/`.stream.json` extensions enables JSON‑schema tooling. *** ## 5) Smoke test * Restart or hot‑reload Horde after saving configs. * In Horde Dashboard, open your project/stream, queue a small BuildGraph job based on your existing configuration, and confirm agents sync from Diversion and build. *** ## Quick reference (Windows) * **Remove Git ignore files** (from UE repo root): ```cmd theme={null} for /r %f in (.gitignore) do @del "%f" ``` * **UE setup** ```cmd theme={null} Setup.bat GenerateProjectFiles.bat ``` *** ## Further reading * **[UE on GitHub](https://www.unrealengine.com/en-US/ue-on-github)** — linking Epic↔GitHub accounts * **[Download UE Source](https://dev.epicgames.com/documentation/en-us/unreal-engine/downloading-source-code-in-unreal-engine)** — official guide * **[Build UE from Source](https://dev.epicgames.com/documentation/en-us/unreal-engine/building-unreal-engine-from-source)** — Windows notes * **[Horde (Overview)](https://dev.epicgames.com/documentation/en-us/unreal-engine/horde-in-unreal-engine)** — overview documentation * **[Horde Orientation](https://dev.epicgames.com/documentation/en-us/unreal-engine/horde-orientation-for-unreal-engine)** — schema server, configs * **[Horde Build Automation (Overview)](https://dev.epicgames.com/documentation/en-us/unreal-engine/horde-build-automation-for-unreal-engine)** — build automation overview * **[Horde Build Automation (Tutorial)](https://dev.epicgames.com/documentation/en-us/unreal-engine/horde-build-automation-tutorial-for-unreal-engine)** — build automation tutorial # UE Plugin - Solving Merge Conflicts With Diversion Source: https://docs.diversion.dev/unreal/ue-plugin-merge-conflicts When working with a team on a project, it is common to run into merge conflicts. This can happen when two or more people make changes to the same file and try to merge their changes together. Diversion's `merge warnings` help avoid conflicts, but if you run into one anyway, this guide will help you resolve it using our Unreal Engine Plugin. ## Step 1: Create a Merge Conflict To create a merge conflict, you will need to make changes to the same file in two different branches. Here I have `BP_ThirdPersonCharacter` from Unreal's Third Person Template project, which I have initialized as a Diversion repository using the plugin. TPS Character - clean In the Diversion desktop app, I'll create a new branch and call it `notify-jump-apex`. Creating new branch - where the button is Creating new branch - actually creating Let's have our character fire an event when it reaches the apex of a jump. We have to set it in the `BP_ThirdPersonCharacter` blueprint like this: (Yes, this is just a simplified example for the purpose of this guide.) Notifying jump apex Great! Let's commit our changes to the `notify-jump-apex` branch. Committing notifying jump apex Another "feature" we want is to have the character attack. We'll switch back to the `main` branch, create a new branch called `attack` like before, and restart the editor to get the correct version of our blueprint. Let's implement our attack logic, and commit it to the `attack` branch. Stub for attack logic Now, let's merge! Close the editor, switch back to the `main` branch, and merge the `notify-jump-apex` branch into it. Switching back to the main branch Merging notify-jump-apex to main That went smoothly since there were no conflicting changes. That won't be the case when we merge the `attack` branch into the `main` branch: Conflicts detected Whoopsie! We have a merge conflict. Since this is a binary file, a `.uasset`, it's not human-readable and we can't resolve it manually just like that, without any special tools. Luckily for us, Unreal has a special tool! Let's use it. ## Step 2: Resolve the Merge Conflict Open the Unreal editor and open our `BP_ThirdPersonCharacter` blueprint. Notice the icon? It tells us there's a conflict in the file. Conflict in the blueprint Right-click on the file and go to `Revision Control -> Merge`. This will open the merge resolution tool. Revision control - merge Merge window The three columns represent the remote, local, and base versions of the file. The remote version is on the left, and it's the incoming change. In our case, that's the change from the `attack` branch. Notice in the screenshot above the left column says `Revision 12`? Your left column might have a different number, since I messed up when taking the screenshots for this guide and had to do it again. I think yours should say `4`. Let us know in the Discord! The middle column is the local version, which is what you have in your current branch. In our example this is the current state of the `main` branch and should include the changes from the `notify-jump-apex` branch. It's important to have the middle column show your local changes, as it will help us manage the merge conflict better. This seems to be an issue with Unreal's merge tool. The right colum is the base version, which is the common ancestor of the two branches, and is optional. In our case, it's the second commit from the `main` branch, with the original blueprint from the template. To see the base version, open the drop down and select the correct commit to see in that column. If you mouse-over the commit, you'll see the commit message so you can identify the correct one. You can also leave it as it is and the rest of the process should look the same. Base commit for merge Click on `Start Merge` and then on `Event Graph`. You can navigate your changes using the graphs as you normally would, or using the `Next` and `Previous` buttons. Notice that our blueprint opened in the background, and any changes we make to it will be reflected in the middle column. At the top, we have 3 important buttons: `Accept Source`, `Accept Target`, and `Finish Merge`. `Accept Source` will take the changes from the left column, `Accept Target` will take the changes from the middle column, and `Finish Merge` will save the changes and close the window. In our case, neither is what we want! We want to combine the changes from both branches. To do that, we'll have to manually copy the changes from the left column to our blueprint that's open in the background. So just copy-paste as you normally would, and when you're done, click `Finish Merge`. Before: Merge window - before After: Merge window - after And that's it! You've resolved the merge conflict using Unreal's merge tool. Recompile your blueprint and you're good to go. # Unreal Engine Plugin Source: https://docs.diversion.dev/unreal/unreal-engine-plugin Use Diversion without leaving the Unreal Engine editor If you want to use Source Control but don't want the hassle of installing and using multiple software, and you're using Unreal Engine, then this is for you. ## Installation ### Prerequisites Before installing the plugin, you'll need to have the Diversion installed and signed in to. If you haven't done that yet, check out the [Quickstart](/quickstart) guide. ### Installing the plugin [//]: # [//]: # "" [//]: # " " [//]: # " Download the plugin for your Unreal Engine version:" [//]: # " - Unreal Engine 5.3: [https://get.diversion.dev/ue-plugin/Diversion-v0.1.4-ue5.3.zip](https://get.diversion.dev/ue-plugin/Diversion-v0.1.4-ue5.3.zip)." [//]: # " - Unreal Engine 5.4: [https://get.diversion.dev/ue-plugin/Diversion-v0.1.4-ue5.4.zip](https://get.diversion.dev/ue-plugin/Diversion-v0.1.4-ue5.4.zip)." [//]: # " " [//]: # " " [//]: # " Unzip it, and copy the `Diversion` folder (the folder and all of its contents, not just the folder) into the `Marketplace` folder inside Unreal Engine's `Plugins` folder. Depending on your engine's version and where you installed it, it should look something like this: `C:\Program Files\Epic Games\UE_5.3\Engine\Plugins\Marketplace`." [//]: # " Create the `Marketplace` folder in case it doesn't exist." [//]: # " " [//]: # "" [//]: # "The plugin will also be available in the Unreal Engine Marketplace in the near future." Search for `Diversion` in the Fab Marketplace, then click on the `Add to My Library` button to add the plugin to your account. Add plugin to library on FAB Then, click on the `Download` button and click on the `Epic Games Launcher` link to go to your engine assets library. Download and open in Launcher Alternatively, you can simply click here to open the Epic Games Launcher. The plugin is downloaded via FAB but must be **installed from the Epic Games Launcher**. After adding it to your library on FAB, you need to switch to the Launcher to complete the installation (next step). Open the Epic Games Launcher and navigate to your engine assets library (under `Library` > `Fab Library`). At the bottom, locate the Diversion plugin and click `Install to Engine`. Install plugin from Launcher Choose the correct version of the Unreal Engine you want to install the plugin to and click `Install`. Select engine version and install In case you would like to manually add the plugin to your UE project, instead of downloading it from the marketplace, you can get the source code from the following links: * Unreal Engine 5.3: [Diversion-v2.0.17-ue5.3.0.zip](https://get.diversion.dev/ue-plugin/Diversion-v2.0.17-ue5.3.0-nobin.zip) * Unreal Engine 5.4: [Diversion-v2.0.17-ue5.4.0.zip](https://get.diversion.dev/ue-plugin/Diversion-v2.0.17-ue5.4.0-nobin.zip) * Unreal Engine 5.5: [Diversion-v2.0.17-ue5.5.0.zip](https://get.diversion.dev/ue-plugin/Diversion-v2.0.17-ue5.5.0-nobin.zip) * Unreal Engine 5.6: [Diversion-v2.0.17-ue5.6.0.zip](https://get.diversion.dev/ue-plugin/Diversion-v2.0.17-ue5.6.0-nobin.zip) * Unreal Engine 5.7: [Diversion-v2.0.17-ue5.7.0.zip](https://get.diversion.dev/ue-plugin/Diversion-v2.0.17-ue5.7.0-nobin.zip) Choosing this options will require you to build the plugin from source and maintain the versions manually in order to keep up with the latest features and improvements. ## Configuration After installing the plugin, you'll need to configure it for each project to use Diversion as your source control provider. In the editor, go to `Edit` > `Plugins`. Search for `Diversion` and click on the checkbox to activate the plugin. If you're prompted to restart the editor, please do. Enable plugin With the plugin enabled, click on `Revision Control -> Connect to Revision Control` on the bottom-right. Revision control button In the window that appears, choose `Diversion` from the provider drop-down list. Choose Diversion provider The next step won't work if you're not. Check out [Quickstart](/quickstart) if you're not sure how to do that. If your project's folder is not a Diversion repository, you'll be prompted to initialize it. Click on `Initialize project with Diversion` and the plugin will do the rest. If it looks like nothing happened, make sure you're logged in and try re-selecting Diversion from the provider drop-down list. The plugin will recognize the root of the repository and your Diversion installation. Initialize repository After initialization, you'll see this screen, Initialized repository click on `Accept Settings` and you're good to go! If your project is already a Diversion repository, like in the case of cloning a repo, just click on `Accept Settings` and you're good to go! Initialized repository ## Usage Let's go over a common workflow using the plugin. For this, we'll be using a clean Unreal project with the plugin already installed and configured. ### Make a change This project will one day be our Multiplayer Open World Survival RPG With Crafting and Building Mechanics™. For that, we'll need a character. Let's create one. In your `Content Browser`, right-click and choose `Blueprint Class`. In the window that appears, choose `Character` and name it `MyCharacter`. You'll notice that the new file might not be what you're used to - it now has a yellow question mark on it. This is because Unreal Engine just created the file in-memory, and hasn't saved it to the disk yet, so Diversion doesn't know about it. Character created Let's fix that - double-click on the file to open it, and then click on the `Save` button on the top-left. Alternatively, you can press `Ctrl + S` while the file is selected in the Content Browser to save the file. The question mark will now be gone, and instead we have a green plus sign. This means that the file is now being tracked by Diversion, and it recognizes that this is a newly added file. Character saved ### Commit the change We want to save this change to our repository, to have it backed up and to be able to share it with our team. Click again on the `Revision Control` button on the bottom-right, and then click on `Submit Content`. Submit content In the window that appears, you'll see a list of all the files that have changed since the last commit. In this case, you'll see `MyCharacter` with a green plus sign next to it. You will also see your `.uproject` file, since Diversion recognizes this as a new file as well. In the text box labeled `Changelist Description`, write a brief description of the changes you're committing. In this case, you could write `Added MyCharacter`. Changelist description Diversion does not endorse or encourage the use of vague, ambiguous, or laconic commit messages. This is for demonstration purposes only. Please write meaningful commit messages. Click on the `Submit` button, and the green plus on `MyCharacter` will disappear, meaning that Diversion has committed the file. Character committed ### Let's see this in the Web UI Open your browser and go to [your dashboard](https://app.diversion.dev). Select your repository (via the `View` button on the **Remote Repositories** tab, or the top-left repo selector). It should have the same name as your project's folder. You'll see the commit you just made, with the description you wrote, and the file you added. Open the **Commits** view from the left navigation rail to see your commit. Commit list ### Make another change Our character is just an empty collider right now, so let's add a placeholder mesh so that we can see it. In the `MyCharacter` blueprint, click on the `Add Component` button on the top-left, and then search for `Cube` and add it. Now we can see our character. Character cube But our character doesn't do anything. In your character's `Event Graph`, add a `Print String` node and connect it to the `Event Begin Play` node. Now our character has some basic functionality. Character print Compile and save the file. Open your `Content Browser` and you'll see that `MyCharacter` now has a red checkmark next to it. This means that Diversion recognizes that the file has changed. Character modified ### Make another commit Just like before, click on the `Revision Control` button on the bottom-right, and then click on `Submit Content`. You'll see the `MyCharacter` file with a red checkmark next to it. Changelist description 2 Double click the file to see the changes you've made in Unreal's diff tool. In this window, you can see the difference between your revision on the right, and the last committed revision on the left. You should see an entry called `Event Graph` in the list on the left. Clicking it will show you the changes you've made to the blueprint, and you you should see the `Print String` node you added. Blueprint diff tool After reviewing your hard work, again, write a description of the changes you're committing. In this case, you could write `Adding placeholder mesh and basic functionality to MyCharacter`. Click on the `Submit` button and the red checkmark will disappear, meaning that Diversion has committed the file. ### Disable soft lock warnings Diversion's soft lock feature warns you when files are being edited by other team members, helping you avoid potential merge conflicts. When you attempt to open a file that's being worked on by others, you'll see a warning message. If you'd like to disable these warnings, follow these steps: Click on `Edit` in the top menu bar and select `Project Settings`. Select project settings Search for "soft lock" and **uncheck** the field `Enable Diversion Auto Soft Lock Confirmations`. Disable soft lock Close the settings window and restart the editor for the changes to take effect. **Important:** Disabling soft lock warnings modifies your project's configuration file. If you commit this change to your repository, it will affect the entire team. Consider either avoiding committing this configuration file or adding it to your [ignore list](/basic/dvignore) if you want this to be a personal preference rather than a team-wide setting. # Webhooks Source: https://docs.diversion.dev/webhooks Integrate Diversion with external tools using webhooks to automate builds, notifications, and workflows. Diversion supports webhooks to notify external services when events occur in your repositories. This enables integration with CI/CD systems, notification services, and custom automation workflows. ## Overview Webhooks are HTTP callbacks that are triggered by specific repository events. When an event occurs, Diversion sends a POST request to the configured endpoint URL with event details in the request body. ### Key Features * **Event-driven notifications**: Real-time notifications for repository events * **Secure delivery**: HMAC-SHA256 signature verification for request authenticity * **Reliable delivery**: Automatic retries with exponential backoff * **Flexible configuration**: Subscribe to specific event types per webhook * **Admin-only management**: Repository admin access required ## Supported Events Currently, Diversion supports the following webhook events: | Event | Description | Payload | | ---------------- | -------------------------------------- | ---------------------------------------------------------------- | | `commit_created` | Triggered when a new commit is created | Commit details, repository info, author | | `review_created` | Triggered when a new review is created | Review details, repository info, author, reviewers | | `review_merged` | Triggered when a review is merged | Review details, merge commit, repository info, author, reviewers | ## Managing Webhooks Webhooks can be managed through the web application. Access requires repository admin permissions. ### Web Interface Click your **profile avatar** → **Your organizations** → in the settings sidebar, under the **Repositories** section, select **Webhooks**, then choose the repository from the dropdown Webhook Management Interface ### Creating a Webhook 1. Click **"Create Webhook"** 2. Fill in the webhook details: * **Name**: Descriptive name for the webhook * **Description**: Optional description of the webhook's purpose * **Endpoint URL**: HTTPS URL where events will be sent * **Secret**: Webhook secret for signature verification (auto-generated if not provided) * **Events**: Select which events should trigger the webhook 3. Click **"Create"** to save the webhook Create Webhook Form ### Webhook Secret The webhook secret is used to generate HMAC-SHA256 signatures for request verification. Secrets must be: * Between 24-75 characters long * Stored encrypted in the database * Only visible during webhook creation **Auto-generation**: If no secret is provided, Diversion generates a cryptographically secure 32-byte secret in the format: `whsec_` ## Webhook Payload All webhook payloads follow a consistent structure: ```json theme={null} { "id": "evt_1234567890", "timestamp": "2025-01-17T12:34:56.789Z", "type": "v1.repo.commit.created", "data": { // Event-specific data } } ``` ### Commit Created Event Payload ```json theme={null} { "id": "evt_2KtGQeeJhtF5qQ", "timestamp": "2025-01-17T08:23:15.123Z", "type": "v1.repo.commit.created", "data": { "repository_id": "dv.repo.12345678-1234-1234-1234-123456789abc", "repository_name": "my-project", "repository_owner_id": "Google_12345678901234567890", "commit_id": "dv.commit.123456", "commit_url": "https://app.diversion.dev/r/my-project/commit/dv.commit.123456", "correlation_id": "abc123-def456-ghi789", "message": "Add new feature", "commit_time": "2025-01-17T08:23:14.567Z", "branch_id": "dv.branch.42", "branch_name": "feature-branch", "branch_url": "https://app.diversion.dev/r/my-project/branch/dv.branch.42", "author": { "id": "Google_12345678901234567890", "name": "John Doe", "email": "john.doe@example.com", "full_name": "John Doe" }, "parent_commits": [ { "commit_id": "dv.commit.123455", "branch_id": "dv.branch.42" } ], "changes": { "deleted": [ "del1.txt", "del2.txt", "del3.txt" ], "has_more_deleted": false, "modified": [ "mod1.txt", "mod2.txt" ], "has_more_modified": false, "new": [ "new1.txt" ], "has_more_new": false } } } ``` ### Review Created Event Payload ```json theme={null} { "id": "evt_2KtGQeeJhtF5qQ", "timestamp": "2025-01-17T08:23:15.123Z", "type": "v1.repo.review.created", "data": { "repository_id": "dv.repo.12345678-1234-1234-1234-123456789abc", "repository_name": "my-project", "repository_owner_id": "Google_12345678901234567890", "review_id": "dv.review.98765", "review_url": "https://app.diversion.dev/r/my-project/review/dv.review.98765", "title": "Add authentication feature", "description": "This review adds OAuth2 authentication to the API", "status": "open", "created_unix": 1737098594, "draft_commit_id": "dv.commit.123456", "base_branch_id": "dv.branch.1", "base_branch_name": "master", "compare_branch_id": "dv.branch.42", "compare_branch_name": "feature-auth", "author": { "id": "Google_12345678901234567890", "name": "johndoe", "full_name": "John Doe", "email": "john.doe@example.com" }, "reviewers": [ { "id": "Google_98765432109876543210", "name": "janedoe", "full_name": "Jane Doe", "email": "jane.doe@example.com", "status": "requested" }, { "id": "Google_11111111111111111111", "name": "bobsmith", "full_name": "Bob Smith", "email": "bob.smith@example.com", "status": "approved" } ], "correlation_id": "abc123-def456-ghi789" } } ``` ### Review Merged Event Payload ```json theme={null} { "id": "evt_3MuHRffKiuG6rR", "timestamp": "2025-01-17T09:45:30.456Z", "type": "v1.repo.review.merged", "data": { "repository_id": "dv.repo.12345678-1234-1234-1234-123456789abc", "repository_name": "my-project", "repository_owner_id": "Google_12345678901234567890", "review_id": "dv.review.98765", "review_url": "https://app.diversion.dev/r/my-project/review/dv.review.98765", "title": "Add authentication feature", "description": "This review adds OAuth2 authentication to the API", "status": "merged", "created_unix": 1737098594, "updated_unix": 1737103530, "merge_commit_id": "dv.commit.123457", "draft_commit_id": "dv.commit.123456", "base_branch_id": "dv.branch.1", "base_branch_name": "master", "compare_branch_id": "dv.branch.42", "compare_branch_name": "feature-auth", "author": { "id": "Google_12345678901234567890", "name": "johndoe", "full_name": "John Doe", "email": "john.doe@example.com" }, "reviewers": [ { "id": "Google_98765432109876543210", "name": "janedoe", "full_name": "Jane Doe", "email": "jane.doe@example.com", "status": "approved" }, { "id": "Google_11111111111111111111", "name": "bobsmith", "full_name": "Bob Smith", "email": "bob.smith@example.com", "status": "approved" } ], "correlation_id": "xyz789-abc123-def456" } } ``` ## Request Signature Verification All webhook requests include signature headers for verification: * `webhook-id`: Unique message identifier * `webhook-timestamp`: Request timestamp (Unix epoch in seconds) * `webhook-signature`: HMAC-SHA256 signature (format: `v1,base64signature`) ### Signature Verification Example Diversion provides a reference implementation for webhook signature verification. Here's an example in Python: ```python theme={null} import base64 import hashlib import hmac def verify_webhook_signature(webhook_id, webhook_timestamp, sig_header, secret, payload_body): # Svix signature format: v1,base64signature if not sig_header.startswith('v1,'): print(f"Invalid signature format: {sig_header}") return False # Extract the signature part after v1, v1_signature = sig_header[3:] # Skip "v1," # Use raw hex format directly as the signing key try: # Svix uses the literal hex string as UTF-8 bytes for signing signing_key = secret.encode('utf-8') except Exception as e: print(f"Failed to encode secret: {e}") return False # Construct the signed content according to Svix docs # Format: {id}.{timestamp}.{payload} signed_content = f"{webhook_id}.{webhook_timestamp}.{payload_body.decode('utf-8')}" # Compute HMAC-SHA256 computed_hmac = hmac.new( signing_key, # Use the hex string encoded as UTF-8 bytes signed_content.encode('utf-8'), hashlib.sha256 ).digest() # Base64 encode the result expected_sig = base64.b64encode(computed_hmac).decode('utf-8') # Compare signatures is_valid = hmac.compare_digest(expected_sig, v1_signature) if is_valid: print("Svix signature verified successfully") else: print(f"Signature verification failed. Expected: {expected_sig}, Got: {v1_signature}") return is_valid ``` **Note**: A fully tested webhook validation implementation is available as an AWS Lambda function example. [Contact support](mailto:support@diversion.dev) if you need assistance with webhook signature verification. ## Webhook Delivery Diversion ensures reliable webhook delivery with the following features: * **Automatic retries**: Failed deliveries are retried with exponential backoff * **Delivery tracking**: Monitor webhook delivery status * **Rate limiting**: Prevents overwhelming destination servers * **Circuit breaking**: Temporarily disables failing endpoints ### Delivery Guarantees * Webhooks are delivered at least once * Events may arrive out of order * Use the `timestamp` field for event ordering * Implement idempotent handlers using the `id` field ## Testing Webhooks To test your signature verification implementation: 1. Create a test webhook with a known secret 2. Use the example validation code provided above 3. Compare against the reference AWS Lambda implementation ## Best Practices 1. **Use HTTPS endpoints**: HTTP endpoints are not supported for security 2. **Verify signatures**: Always verify webhook signatures in production 3. **Handle retries**: Make webhook handlers idempotent 4. **Respond quickly**: Return 2xx status within 30 seconds 5. **Queue processing**: For long-running tasks, queue work and respond immediately 6. **Monitor failures**: Set up alerts for webhook delivery failures ## Troubleshooting ### Common Issues 1. **Webhook not triggering** * Verify the webhook is active * Check event type subscriptions * Ensure you have admin access to the repository 2. **Signature verification failing** * Confirm you're using the correct secret * Verify timestamp is within tolerance (5 minutes) * Check signature format and parsing 3. **Delivery failures** * Ensure endpoint is publicly accessible * Check for SSL/TLS certificate issues * Verify endpoint returns 2xx status code * Review server logs for errors ### Debugging Tips * Use webhook testing tools like [webhook.site](https://webhook.site) for initial testing * Enable debug logging in your webhook handler * Test with curl using the expected payload format * [Contact support](mailto:support@diversion.dev) if you need help investigating delivery issues ## Security Considerations 1. **Secret management**: Store webhook secrets securely, never in code 2. **Payload validation**: Validate all webhook data before processing 3. **Rate limiting**: Implement rate limiting on webhook endpoints 4. **Authentication**: Use webhook signatures as the only authentication method 5. **HTTPS only**: Always use HTTPS endpoints for webhook delivery ## Discord Webhook Integration At the moment, direct Discord webhook integration is not supported. However, you can still connect Discord using a middleware service such as Zapier or Pipedream, which act as bridges between Discord and our platform. ### Using Pipedream to Integrate Discord Webhooks 1. **Set Up Pipedream** * Create a Pipedream account and a new project * Name your project and click **Create Project** 2. **Create a Workflow** * Click + **New** → choose **Workflow** * Name your workflow, uncheck "Send error notifications", and click **Create Workflow** 3. **Add a Trigger** * Click **Add Trigger** → select **New HTTP / Webhook Requests** * Click **Save and Continue** 4. **Add Discord Action** * Click the **+** symbol below your trigger → search and select **Discord**. * Choose **Send Message** * Select your Discord account * Log in to Discord and select your server and channel * Enter your message (e.g., "New commit!") and close the action * Here is a template for a more detailed message that includes the repo name, author, branch, commit id, commit message and a link to the commit: ``` **New Commit to {{ JSON.parse(JSON.stringify(steps.trigger.event.body)).data?.repository_name || 'Unknown Repo' }}** **Author:** {{ JSON.parse(JSON.stringify(steps.trigger.event.body)).data?.author?.full_name || 'Unknown Author' }} **Branch:** {{ JSON.parse(JSON.stringify(steps.trigger.event.body)).data?.branch_name || 'Unknown Branch' }} **Commit ID:** {{ JSON.parse(JSON.stringify(steps.trigger.event.body)).data?.commit_id || 'Unknown ID' }} **Message:** {{ JSON.parse(JSON.stringify(steps.trigger.event.body)).data?.message || 'No message' }} **Link:** {{ JSON.parse(JSON.stringify(steps.trigger.event.body)).data?.commit_url || 'No URL' }} ``` * You can customize the message further by accessing other available fields from the commit created event payload 5. **Test & Deploy** * Click **Test** to confirm the message appears in Discord * Click on the trigger → copy the webhook URL * Use this URL as the Payload URL when configuring your webhook in the Diversion app * Click **Deploy** to activate the workflow * Go to Diversion and paste this URL into Diversion and add the webhook 6. **Configure the Webhook in Diversion** * Open the Diversion Desktop App or Web UI * Click your **profile avatar** → **Your organizations** → in the settings sidebar, under the **Repositories** section, select **Webhooks**, then choose the repository from the dropdown * Click **Add Webhook** * In the **Payload URL** field, paste the webhook URL you copied from Pipedream * Fill in the other webhook details * Click **Add webhook** to activate the webhook