> ## Documentation Index
> Fetch the complete documentation index at: https://docs.genesiscomputing.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GitLab Connector Tools

> Seamlessly integrate GitLab repositories with Genesis Data Agents for version control, CI/CD automation, and collaborative data workflows.

## **Overview**

### **Tool Name**

```json theme={null}
git_and_file_tools
```

GitLab repositories are worked through the `git_action` and `file` tools of the
`git_and_file_tools` group, over a saved GitLab Connection. There is no separate
GitLab connector tool.

### **Purpose**

The `git_action` and `file` tools enable direct integration between Genesis Data Agents and GitLab repositories. Manage repositories, files, branches, merge requests, and CI/CD pipelines programmatically—all within your data agent conversations. Perfect for automated documentation, code generation, data pipeline versioning, DevOps automation, and collaborative data projects with enterprise-grade features.

#### **Functions Available**

1. **`git_action`**: *`Core Git operations including repository management, branching, committing, and history tracking.`*
2. **`file`**: *`File operations for reading, writing, searching, and managing repository content.`*
3. **`git_action` (GitLab-specific actions)**: *`GitLab platform features including merge requests, remote repository management, and credential storage.`*

### Key Features

<Steps>
  <Step title="Repository Management" icon="folder-tree">
    Clone, create, list, and delete repositories with full version control integration.
  </Step>

  <Step title="Branch Operations" icon="code-branch">
    Create, switch, merge branches and manage parallel development workflows.
  </Step>

  <Step title="Merge Request Automation" icon="code-merge">
    Create, review, merge, and close merge requests programmatically for collaborative workflows.
  </Step>

  <Step title="File Management" icon="file-code">
    Read, write, search, copy, move, and delete files with pattern matching and bulk operations.
  </Step>

  <Step title="Commit History" icon="clock-rotate-left">
    Access commit logs, fetch history, and track changes across repository timelines.
  </Step>

  <Step title="Secure Authentication" icon="shield-check">
    Store GitLab credentials securely with support for Personal Access Tokens (PAT).
  </Step>
</Steps>

<Note>
  Use `git_action` and related GitLab connector workflows for common repository,
  file, branch, merge-request, and review tasks. To read long-tail GitLab REST
  endpoints under `/api/v4/...` that are not covered here, use
  `connection_api_action` from [Web Access Tools](/docs/Genbot-Toolkit/Web-Access-Tools)
  so Genesis can reuse the saved GitLab Connection and handle missing or
  expired authorization correctly. It only reads GitLab: changes go through
  `git_action`, which runs them under Action Review.
</Note>

## **Input Parameters for Each Function**

### **`git_action`**

**Parameters**

| **Name** | **Definition** | **Format** |
| - | - | :-: |
| **action** | Git operation to perform. Values: `commit`, `get_history`, `create_branch`, `switch_branch`, `get_status`, `clone_repo`, `list_repos`, `pull`, `push`, `create_pull_request`, etc. | String (required) |
| **repo\_id** | Repository identifier. Required for most operations except `list_repos` and credential storage. | String |
| **commit\_message** | Message for commit action. | String |
| **co\_authors** | Optional array of strings in `Name <email>` format to add `Co-authored-by:` trailers when `action="commit"`. | Array |
| **branch\_name** | Name of branch for `clone_repo`, create/switch/pull/push operations, or the merge request source (head) branch. | String |
| **target\_branch** | Base/destination branch a `create_pull_request` merges into. Provider-agnostic; defaults to the repository default branch when omitted. Alias: `base_branch`. | String |
| **base\_branch** | Alias for `target_branch`. If both are supplied, `target_branch` wins. | String |
| **url** | Git repository URL for cloning or remote operations. | String |
| **shallow** | For `clone_repo`: perform a shallow clone. Default: `true`. | Boolean |
| **single\_branch** | For `clone_repo`: clone only the selected/default branch. Default: `true`. | Boolean |
| **depth** | For `clone_repo`: number of commits to fetch. `0` requests full history and overrides `shallow`. | Integer |
| **max\_count** | Maximum number of commits to return in history (for `get_history`). | Integer |
| **details** | For `list_repos`: include per-repo details. Default: `false`. Adds `mode`, `has_git_dir`, `has_remote`, `remote_url`, `clone_source`, `scope`, `owner_user_id`, `owner_bot_id`, and `undeletable`. | Boolean |
| **include\_paths** | For `list_repos` with `details=true`: include filesystem path. Default: `false`. | Boolean |
| **include\_orgs** | For `list_remote_repos`: include group/organization projects in addition to personal projects. Default: `true`. Maps to GitLab `membership=true` listing. | Boolean |

### **`file`**

**Parameters**

| **Name** | **Definition** | **Format** |
| - | - | :-: |
| **action** | File operation. Values: `read`, `read_multiple`, `write`, `write_multiple`, `delete`, `list`, `find`, `search`, `copy`, `move`, `commit`, etc. | String (required) |
| **repo\_id** | Repository identifier where files are located. | String (required) |
| **file\_path** | Relative path to file in repository (no leading /). | String |
| **content** | File content. For text, pass the text directly. For binary (zip, image, parquet, sqlite, etc.), pass the base64 string here and set `is_base64=true` so it is decoded before writing. | String |
| **is\_base64** | For `action="write"`: when `true`, `content` is base64-decoded to the original bytes before writing (use this for binary files). For `action="write_multiple"`: ignored at the top level — set `is_base64` inside each `files[]` item instead. Ignored by all other actions. Default: `false`. | Boolean |
| **files** | Bulk files array. For `write`/`write_multiple`: `[{path, content, is_base64}]` (`content` is required). For `read_multiple`: path strings like `["a.sql"]` or objects like `[{"path": "a.sql"}]`. `repo_id` is required for `read_multiple`. | Array |
| **pattern** | Glob pattern for find/search operations (e.g., `*.py`, `**/*.md`). | String |
| **source\_patterns** | List of repo-relative glob patterns or exact file paths for bulk copy/move/delete operations. | Array of Strings |
| **target\_path** | Destination directory for copy/move operations. | String |
| **preserve\_structure** | When copying or moving files, preserve nested paths under the matched pattern scope. Default: `true`. With `source_patterns=["src/**/*"]`, `src/sub/file.txt` becomes `target/sub/file.txt`; with `source_patterns=["src/file.txt"]`, the parent directory is stripped so the result is `target/file.txt`. Set to `false` to flatten files into `target_path`. | Boolean |
| **message** | Commit message (for commit action). | String |

<Tip>
  Use **repo\_id** consistently across git\_action and file operations to work within the same repository context. List available repos with `git_action(action="list_repos")`.
</Tip>

<Note>
  **Transferring existing files.** When the source already lives in a repository,
  use `file(action="copy")` or `file(action="move")` for byte-exact server-side
  transfer — never read a file and write the same bytes back. For inline or
  generated binary content that is not already on disk, write base64 with
  `is_base64=true`. Without `is_base64=true`, the base64 string is written as
  literal ASCII text and the file is corrupt. For `write_multiple`, set
  `is_base64` inside each `files[]` item rather than at the top level. See
  [Git Action Tools](/docs/Genbot-Toolkit/Git-Action-Tools) for examples.
</Note>

<Note>
  With `git_action(action="list_repos", details=True)`, Genesis always returns
  `has_remote` as `true` or `false` so agents can filter cleanly. When a remote
  exists, `remote_url` is credentials-redacted and `clone_source` is set when
  Genesis can infer `github`, `gitlab`, `bitbucket`, or `azure_devops`. Use
  `include_paths=True` to add `path` to each detail row.
</Note>

<Note>
  `file(action="read")` supports partial and targeted reads with `start_line`, `end_line`, `max_lines`, `start_byte`, `max_bytes`, `end_byte`, `tail_bytes`, `max_chars`, `search_pattern`, `context_lines_before`, `context_lines_after`, `max_matches`, `return_line_numbers`, `encoding`, `force_text`, and `return_base64`. `file(action="read_multiple")` forwards the same controls per file entry.
</Note>

<Note>
  Extremely large single-file reads follow the same guardrail as `git_action`: when `git_action(action="read_file")`, `file(action="read")`, or `file(action="inspect_structured_data")` exceeds the file-read inline budget (default `262,144` bytes / 256 KB, configurable with `GENESIS_TOOL_OUTPUT_FILE_READ_BUDGET`), Genesis returns `tool_output_capped`, `preview`, `truncation_info`, `full_output_ref`, and `agent_guidance`. When `full_output_ref` is not `null`, the full text is saved under `truncated_tool_outputs/<thread_id>/...` in the `apps` BotGit repo and can be paged back with `file(action="read", file_path=full_output_ref, repo_id="apps", start_byte=0, max_bytes=N)`, continuing from each response's `continuation.next_start_byte`. The byte range is the shape that returns the saved copy exactly as written; the whole-file and line-window paths read in text mode and rewrite line endings.
</Note>

## **Use Cases**

1. **Automated Documentation**
   Generate and commit data dictionaries, API documentation, or pipeline specifications directly to GitLab repositories with automatic CI/CD triggers.

2. **Code Generation & Versioning**
   Create dbt models, SQL scripts, Terraform configurations, or Python notebooks and version them in GitLab for team collaboration.

3. **CI/CD Pipeline Integration**
   Update configuration files, trigger pipeline runs, and track deployment artifacts through GitLab's integrated DevOps platform.

4. **Collaborative Data Projects**
   Share analysis notebooks, datasets, experiment results, and findings with team members through structured GitLab workflows.

5. **Enterprise Data Governance**
   Maintain audit trails, approval workflows, and compliance documentation with GitLab's advanced merge request and access control features.

## **Workflow/How It Works**

1. **Step 1: Authenticate with GitLab**
   Store GitLab credentials securely using Personal Access Token:
   ```python theme={null}
   git_action(
       action="store_gitlab_credentials",
       gitlab_token="YOUR_GITLAB_PAT"
   )
   ```

2. **Step 2: Create or Clone Repository**
   Start with a new repository or clone an existing one:
   ```python theme={null}
   # Create new repository
   git_action(
       action="create_repo",
       repo_id="my_data_project"
   )

   # Or clone from GitLab
   git_action(
       action="clone_repo",
       repo_id="analytics_pipeline",
       url="https://gitlab.com/organization/analytics-pipeline.git"
   )
   ```

<Note>
  Add `branch_name="release/2026.05"` to clone and check out a non-default
  branch in one call. Unless you override them, `shallow` and
  `single_branch` both default to `true`; set `depth=0` for full history.
</Note>

3. **Step 3: Manage Files**
   Create, read, and organize files within the repository:
   ```python theme={null}
   # Write documentation
   file(
       action="write",
       repo_id="my_data_project",
       file_path="docs/data_dictionary.md",
       content="# Data Dictionary\n\n## Customer Table\n..."
   )

   # Search for configuration files
   file(
       action="find",
       repo_id="my_data_project",
       pattern="*.yml"
   )
   ```

4. **Step 4: Commit Changes**
   Track changes with descriptive commit messages:
   ```python theme={null}
   git_action(
       action="commit",
       repo_id="my_data_project",
       commit_message="docs: Add customer data dictionary and ETL specifications"
   )
   ```

<Note>
  `git_action(action="commit")` also accepts optional `co_authors`, for
  example `["Jane Doe <jane@example.com>"]`, to append explicit
  `Co-authored-by:` trailers. This is separate from the primary author chosen
  through the saved GitLab connection.
</Note>

5. **Step 5: Create Merge Request**
   Collaborate with team through merge requests:
   ```python theme={null}
   git_action(
       action="create_pull_request",  # Same action works for GitLab MRs
       repo_id="my_data_project",
       branch_name="feature/new-pipeline",
       title="Add new customer segmentation pipeline",
       body="This MR introduces customer segmentation logic with dbt models and CI/CD integration."
   )
   ```

6. **Step 6: Push to GitLab**
   Sync local changes to remote repository:
   ```python theme={null}
   git_action(
       action="push",
       repo_id="my_data_project"
   )
   ```

### **Managed GitLab API Commits**

Use `git_action(action="commit_files_via_api")` to land one or more prepared
file changes on a managed GitLab branch through the GitLab Commits API. This
is useful when a GitLab installation blocks raw `git push` on WIP branches or
when you want an optimistic-concurrency check before committing.

| **Name** | **Definition** | **Format** |
| - | - | :-: |
| **action** | Must be `commit_files_via_api`. | String (required) |
| **repo\_id** | Managed repository identifier. | String (required) |
| **branch\_name** | Target remote branch to update. | String (required) |
| **commit\_message** | Commit message for the API commit. | String (required) |
| **files** | Array of file entries such as `[{path, source_path}]` or, for very small files only, `[{path, content, is_base64}]`. Per-file `action` defaults to `auto`; supported values are `create`, `update`, `delete`, `move`, and `auto`. `move` also requires `previous_path`. | Array (required) |
| **start\_branch** | Base ref used only when `branch_name` does not yet exist on the remote. Defaults to the repository default branch when omitted. Ignored when `branch_name` already exists. | String |
| **author\_name** | Optional commit author name override. When omitted, Genesis uses the saved GitLab connection author settings when available. | String |
| **author\_email** | Optional commit author email override. When omitted, Genesis uses the saved GitLab connection author settings when available. | String |
| **expected\_branch\_head\_sha** | Optional optimistic-concurrency token for an existing remote branch. Genesis checks that the remote branch tip still matches this SHA before committing. If the branch has moved, the response returns `error_code="STALE_REMOTE_HEAD"` plus `expected_sha` and `actual_sha`. Ignored when `branch_name` does not yet exist. | String |

```python theme={null}
git_action(
    action="commit_files_via_api",
    repo_id="customer_analytics",
    branch_name="wip/alice/churn-docs",
    start_branch="main",
    expected_branch_head_sha="abc123def4567890",
    commit_message="docs: refresh churn methodology",
    files=[
        {
            "path": "docs/churn_model_methodology.md",
            "source_path": "/workspace/customer_analytics/docs/churn_model_methodology.md",
        }
    ],
)
```

<Note>
  Use `source_path` for non-trivial content so Genesis reads the file from disk
  when preparing the commit and again immediately before submission. Genesis
  binds the file's exact content and refuses the whole commit if the content
  changed. `source_path` must stay inside the prepared managed repo or
  worktree for that commit. Genesis rejects symlinks and paths that escape
  that root. Inline `content` is intended only for very small files and is
  also bound to the approval.
</Note>

<Note>
  The approval also freezes the commit base. For an existing `branch_name`,
  Genesis binds its current tip; for a new branch, it binds the commit that
  `start_branch` currently points to. If the target branch moves, appears,
  disappears, or cannot be read before approval is submitted, nothing is sent
  and the action must be proposed again. `expected_branch_head_sha` still
  provides the optional caller-side check for an existing branch; when it does
  not match, the response includes `error_code="STALE_REMOTE_HEAD"`,
  `expected_sha`, and `actual_sha`.
</Note>

<Note>
  After approval, `action_review.status="not_applied"` means GitLab refused the
  commit and `detail` explains why; nothing was written. If the status is
  `reconciliation_required`, the remote result is uncertain and you must not
  retry, because the commit may already exist. The Git transport cannot
  currently prove that a read-back uses the same credential as the approved
  write, so Genesis does not automatically confirm an uncertain commit by
  reading the target branch; the result remains inconclusive.
</Note>

## **Integration Relevance**

* **project\_manager\_tools** to track data projects and link GitLab repositories to missions.
* **data\_connector\_tools** to export analysis results and commit them to version control.
* **dbt\_action** to manage dbt projects in GitLab with full version control and CI/CD.
* **file\_manager\_tools** to organize artifacts before committing to repositories.
* **slack\_tools** to notify teams when merge requests are created or commits are pushed.
* **scheduler\_tools** to automate regular commits, syncs, or pipeline triggers.

## **Configuration Details**

* **Personal Access Token**: Generate from GitLab Settings → Access Tokens. Required scopes: `api`, `read_repository`, `write_repository`. Include `read_api` when you need `list_remote_repos` (and Context Graph **Select repos**) to list group/organization projects, not only personal ones.
* **Git Commit Author** (`git_author_mode`): Optional select field on the saved GitLab connection. Default: `genesis_bot`. Supported values: `genesis_bot`, `authenticated_git_user`, `custom`.
* **Git Author Name** (`git_author_name`) and **Git Author Email** (`git_author_email`): Optional string fields on the saved GitLab connection. Genesis shows them only when `git_author_mode="custom"`, and both are required together in that mode.
* **Repository Naming**: Use lowercase with hyphens (e.g., `data-pipeline-prod`) for consistency.
* **Branch Strategy**: Use feature branches (`feature/`, `bugfix/`, `hotfix/`) for changes; protect `main` and `develop` branches.
* **Commit Messages**: Follow conventional commits format: `feat:`, `fix:`, `docs:`, `ci:`, `refactor:`.
* **File Paths**: Always use forward slashes (/) and relative paths without leading slash.
* **Large Files**: GitLab has 10GB repository size limit; use Git LFS for files over 100MB.
* **CI/CD Integration**: Merge requests can automatically trigger GitLab CI/CD pipelines defined in `.gitlab-ci.yml`.

<Warning>
  Never commit sensitive credentials, API keys, or passwords to GitLab repositories. Use GitLab CI/CD variables or HashiCorp Vault integration for secrets management.
</Warning>

## **Limitations or Notes**

1. **Repository Size**: GitLab recommends keeping repositories under 10GB; large repos may have performance issues.
2. **API Rate Limits**: GitLab has rate limits (varies by tier—Free: 300/min, Premium: 1000/min); batch operations when possible.
3. **Private Repository Access**: Requires appropriate permissions and PAT scopes for private/internal repos.
4. **Binary Files**: Git is optimized for text files; large binary files can slow repository performance.
5. **Merge Conflicts**: Automatic merging may fail with conflicts; manual resolution required.
6. **Branch Protection**: Protected branches prevent direct pushes; use merge requests instead.
7. **Network Dependency**: All operations require internet connectivity to GitLab servers.
8. **GitLab Version**: Some features may require specific GitLab versions (especially self-hosted instances).

### **Supported Actions**

✅ **clone\_repo** - Clone repository from GitLab URL\
✅ **create\_repo** - Create new local repository\
✅ **list\_repos** - Show all available repositories\
✅ **commit** - Commit staged changes\
✅ **push** - Push commits to remote\
✅ **pull** - Pull changes from remote\
✅ **create\_branch** - Create new branch\
✅ **switch\_branch** - Switch to different branch\
✅ **get\_status** - Show repository status\
✅ **get\_history** - View commit history\
✅ **create\_pull\_request** - Create MR on GitLab (auto-detected)\
✅ **merge\_pull\_request** - Merge MR\
✅ **close\_pull\_request** - Close MR without merging\
✅ **get\_pull\_request\_info** - Get MR details\
✅ **store\_gitlab\_credentials** - Save authentication\
✅ **list\_remote\_repos** - List repos on GitLab\
✅ **file operations** - Full CRUD on repository files, including batch reads with `file(action="read_multiple")`

### **Not Supported**

❌ Git submodules or subtrees\
❌ Git LFS direct management (files can be committed but not managed)\
❌ GitLab CI/CD pipeline creation or modification\
❌ GitLab Issues, Epics, or Boards management\
❌ Repository webhooks configuration\
❌ GitLab Pages deployment configuration\
❌ Repository transfer or namespace changes\
❌ Advanced merge strategies from tool (squash/rebase configurable in GitLab UI)\
❌ GitLab Container Registry operations

### **Output**

* **clone\_repo**: Confirmation with repository path and clone details.
* **commit**: Commit hash, files changed, and commit message confirmation.
* **push**: Push status, branch name, and remote URL.
* **get\_history**: List of commits with hash, author, date, and message.
* **get\_status**: Current branch, staged/unstaged files, and sync status.
* **create\_pull\_request**: MR number, URL (IID), and creation confirmation.
* **get\_pull\_request\_info**: MR details including status, approvals, pipeline status, and discussion threads.
* **file operations**: Success confirmation, file paths, content previews, batch read results with per-file success or error details plus `content` and `size` for successful reads. Batch reads can also surface per-file `truncated`, `truncation_info`, `continuation`, `encoding`, `file_type`, `total_size`, `returned_size`, `returned_lines`, `total_lines`, `start_line`, `end_line`, `start_byte`, and `end_byte`, plus top-level `warnings`, `files_truncated`, `files_skipped`, `skipped_preview`, and `continuation_hint` when the response is cut short.
* **Large path and archive previews**: `file(action="list")` and `file(action="find")` can return `files_preview`, `files_truncated`, `files_omitted_count`, `total_files`, `files_continuation_hint`, `note`, and `narrowing_hint` when many paths match. `file(action="unzip")` can similarly preview `extracted_files` and `download_links` with fields such as `extracted_files_preview`, `extracted_files_truncated`, `extracted_files_omitted_count`, `total_extracted_files`, `extracted_files_continuation_hint`, `download_links_preview`, `download_links_truncated`, `download_links_omitted_count`, `total_download_links`, and `download_links_continuation_hint`.
* **Zero-result repo search warning**: `git_action(action="search")`, `git_action(action="grep")`, `file(action="search")`, and `file(action="fast_search")` can include `_branch_warning` when a repo on a non-default branch returns `0` matches. The object includes `current_branch`, `default_branch`, and `message`, which directs you to switch to the default branch, run `git_action(action="pull")`, and retry the search.
* **list\_repos**: Repository ids by default. With `details=true`, each detail row includes `mode`, `has_git_dir`, `has_remote`, `scope`, `owner_user_id`, `owner_bot_id`, and `undeletable`, plus credentials-redacted `remote_url` when present, `clone_source` when Genesis can infer the remote platform, and `path` when `include_paths=true`.
* **list\_remote\_repos**: `personal_repos` (flat list of user-namespace projects) and `organization_repos` (list of `{org, org_url, repos}` buckets per GitLab namespace, matching the GitHub `list_remote_repos` shape so UIs can `flatMap` group repos the same way for both providers). Each repo entry includes `name`, `full_name`, `url`, `ssh_url`, `private`, `description`, `default_branch`, `created_at`, and `updated_at`. Optional `warnings` (array of strings) when group listing partially fails—for example membership scope returns HTTP 403 because the PAT lacks `read_api`, or a listing reaches the 10,000-project cap. Genesis caps each owned and membership listing independently at 10,000 projects; `truncated: true` and a warning report when a listing reaches the cap.
* **Errors**: Detailed error messages with resolution guidance (e.g., authentication failures, merge conflicts, API limits).

## **Best Practices**

<CardGroup cols={2}>
  <Card title="Commit Often" icon="floppy-disk">
    Make small, focused commits with clear messages. Easier to review, revert, and understand history.
  </Card>

  <Card title="Branch Strategy" icon="diagram-project">
    Use feature branches for development. Keep main/develop stable and use protected branch rules.
  </Card>

  <Card title="Pull Before Push" icon="arrows-rotate">
    Always pull latest changes before pushing to avoid conflicts and ensure smooth integration.
  </Card>

  <Card title="Meaningful Messages" icon="message">
    Write descriptive commit messages. GitLab supports linking to issues with #123 notation.
  </Card>

  <Card title="Use Merge Requests" icon="code-merge">
    Always use MRs for code review and CI/CD validation, even for small changes.
  </Card>

  <Card title="Leverage CI/CD" icon="rocket">
    Define `.gitlab-ci.yml` to automate testing, validation, and deployment on every commit.
  </Card>
</CardGroup>

## **Example: Complete Data Project Workflow**

```python theme={null}
# 1. Store GitLab credentials (one-time setup)
git_action(
    action="store_gitlab_credentials",
    gitlab_token="glpat-abc123xyz..."
)

# 2. Clone existing project repository
git_action(
    action="clone_repo",
    repo_id="customer_analytics",
    url="https://gitlab.com/company/customer-analytics.git"
)

# 3. Create feature branch for new analysis
git_action(
    action="create_branch",
    repo_id="customer_analytics",
    branch_name="feature/churn-prediction"
)

git_action(
    action="switch_branch",
    repo_id="customer_analytics",
    branch_name="feature/churn-prediction"
)

# 4. Create analysis notebook
file(
    action="write",
    repo_id="customer_analytics",
    file_path="notebooks/churn_prediction.py",
    content="""
# Customer Churn Prediction Model
import pandas as pd
from sklearn.ensemble import RandomForestClassifier

# Load and prepare data
customers = pd.read_csv('data/customers.csv')

# Model training logic...
"""
)

# 5. Create CI/CD configuration
file(
    action="write",
    repo_id="customer_analytics",
    file_path=".gitlab-ci.yml",
    content="""
stages:
  - test
  - deploy

test_notebook:
  stage: test
  script:
    - python -m pytest tests/
    - python notebooks/churn_prediction.py --validate

deploy_model:
  stage: deploy
  script:
    - python deploy_model.py
  only:
    - main
"""
)

# 6. Create documentation
file(
    action="write",
    repo_id="customer_analytics",
    file_path="docs/churn_model_methodology.md",
    content="# Churn Prediction Methodology\n\n## Overview\n\nThis model predicts customer churn using..."
)

# 7. Commit changes
git_action(
    action="commit",
    repo_id="customer_analytics",
    commit_message="feat: Add churn prediction model with CI/CD pipeline"
)

# 8. Push to GitLab
git_action(
    action="push",
    repo_id="customer_analytics",
    branch_name="feature/churn-prediction"
)

# 9. Create merge request for review
git_action(
    action="create_pull_request",
    repo_id="customer_analytics",
    branch_name="feature/churn-prediction",
    title="Add Customer Churn Prediction Model",
    body="""## Changes
- Churn prediction model using Random Forest
- Automated testing in CI/CD pipeline
- Comprehensive documentation

## Testing
- Unit tests passing
- Model accuracy: 87%
- Performance benchmarks included

Closes #42"""
)

# 10. Check merge request status
git_action(
    action="get_pull_request_info",
    repo_id="customer_analytics",
    pull_request_number=15
)

# 11. Check repository status
git_action(
    action="get_status",
    repo_id="customer_analytics"
)
```

## **Advanced Features**

### **Bulk File Operations**

Copy multiple files matching patterns:

```python theme={null}
file(
    action="copy",
    repo_id="customer_analytics",
    source_patterns=["*.sql", "*.py", "*.yml"],
    target_path="archive/v1/",
    preserve_structure=True
)
```

Copy or move a repo-relative exact file path into a directory:

```python theme={null}
file(
    action="copy",
    repo_id="customer_analytics",
    source_patterns=["reports/monthly/summary.md"],
    target_path="archive/",
    preserve_structure=True
)
# Writes archive/summary.md
```

<Note>
  `preserve_structure` defaults to `true` for `file(action="copy")` and `file(action="move")`. Glob patterns preserve the path below the matched parent scope. Exact file paths use their parent directory as the matched scope, so `source_patterns=["reports/monthly/summary.md"]` writes `archive/summary.md` instead of recreating `archive/reports/monthly/summary.md`.
</Note>

Read multiple repository files in one call:

```python theme={null}
file(
    action="read_multiple",
    repo_id="customer_analytics",
    files=[
        "ddl/customers.sql",
        {"path": "ddl/orders.sql"},
        "models/product_dim.sql",
    ]
)
```

<Note>
  `file(action="read_multiple")` accepts a recommended maximum of 20 files per call and a hard limit of 100. Total returned content is capped at 200 KB; when that limit is reached, remaining files are reported in `skipped`, `skipped_preview`, and `files_skipped`, and the top-level response adds `continuation_hint`. Large files are automatically truncated to about 20 KB. Successful reads include per-file `content` and `size`; truncated entries are marked with `truncated: true` and can also include `truncation_info`, `continuation`, `encoding`, `file_type`, `total_size`, `returned_size`, `returned_lines`, `total_lines`, `start_line`, `end_line`, `start_byte`, and `end_byte`. If any entry is truncated, the batch response adds a warning explaining how to continue from the correct byte or line offset, and the top-level response includes `files_truncated` with the count of truncated files. Use `file(action="read")` for binary or Excel files.
</Note>

<Note>
  Very large `list`, `find`, and `unzip` responses are previewed instead of returned in full. `files` and `extracted_files` previews are trimmed to the first `50` paths, and `download_links` previews are trimmed to the first `20` links. Use fields such as `files_preview`, `files_truncated`, `files_omitted_count`, `total_files`, `files_continuation_hint`, `note`, and `narrowing_hint` to narrow `list` or `find` queries, or `extracted_files_preview` and `download_links_preview` to inspect the extracted directory.
</Note>

### **Search Across Files**

Find specific content in repository:

```python theme={null}
file(
    action="search",
    repo_id="customer_analytics",
    pattern="SELECT.*FROM customers",
    regex=True
)
```

<Note>
  When `git_action(action="search")`, `git_action(action="grep")`, `file(action="search")`, or `file(action="fast_search")` returns zero matches for a repo on a non-default branch, the response can include `_branch_warning` with `current_branch`, `default_branch`, and `message`. Follow `_branch_warning.message` to switch to the default branch, run `git_action(action="pull")`, and retry the search.
</Note>

### **Fetch Deep History**

Get more commit history for analysis:

```python theme={null}
git_action(
    action="fetch_more_history",
    repo_id="customer_analytics",
    depth=100
)

git_action(
    action="get_history",
    repo_id="customer_analytics",
    max_count=50
)
```

### **List Remote Repositories**

Discover available GitLab projects across your personal namespace and, by
default, groups you belong to:

```python theme={null}
git_action(
    action="list_remote_repos",
    include_orgs=True
)
```

<Note>
  `include_orgs` is optional and defaults to `true`. The response mirrors
  GitHub `list_remote_repos`: `personal_repos` is a flat list;
  `organization_repos` is `[{org, org_url, repos}, ...]` keyed by GitLab
  namespace `full_path`. Check `warnings` when group projects are missing—a
  common case is a PAT without the `read_api` scope for membership listing.
</Note>

## **GitLab-Specific Features**

### **Merge Request Workflow**

Unlike GitHub's Pull Requests, GitLab uses Merge Requests (MRs) with additional features:

* **Approval Rules**: MRs can require specific approvers before merging
* **Pipeline Integration**: CI/CD pipelines run automatically on MR creation
* **Discussion Threads**: Threaded comments that can be resolved
* **Draft MRs**: Prefix title with "Draft:" or "WIP:" to prevent premature merging
* **Squash Commits**: Option to squash all commits when merging

```python theme={null}
# Create draft merge request
git_action(
    action="create_pull_request",
    repo_id="customer_analytics",
    branch_name="feature/experimental",
    title="Draft: Experimental feature testing",
    body="This is a work in progress - do not merge yet"
)
```

### **Self-Hosted GitLab Support**

For self-hosted GitLab instances:

```python theme={null}
# Store credentials for custom GitLab instance
git_action(
    action="store_gitlab_credentials",
    gitlab_token="glpat-abc123...",
    # Platform will auto-detect from URL during clone
)

# Clone from self-hosted instance
git_action(
    action="clone_repo",
    repo_id="internal_project",
    url="https://gitlab.company.com/data/internal-project.git"
)
```

## **Troubleshooting**

<AccordionGroup>
  <Accordion title="Authentication Failed">
    * Verify Personal Access Token is valid and not expired
    * Check token has required scopes: `api`, `read_repository`, `write_repository`
    * For self-hosted: ensure network access to GitLab instance
    * Re-store credentials with `store_gitlab_credentials`
  </Accordion>

  <Accordion title="list_remote_repos Shows Only Personal Projects">
    * Group/organization projects come from GitLab `membership=true` listing; the PAT needs `read_api`
    * Inspect the `warnings` array on the response for HTTP 403/401 hints
    * Recreate or widen the saved GitLab connection PAT, then retry **Select repos** or `git_action(action="list_remote_repos")`
  </Accordion>

  <Accordion title="Push Rejected - Pipeline Failed">
    * Check `.gitlab-ci.yml` for syntax errors
    * Review pipeline logs in GitLab UI
    * Ensure CI/CD runners are available
    * Fix failing tests before pushing
  </Accordion>

  <Accordion title="Push Rejected - Protected Branch">
    * Use merge request workflow instead of direct push
    * Pull latest changes first: `git_action(action="pull")`
    * Check for merge conflicts in `get_status`
    * Verify you have maintainer/developer role
  </Accordion>

  <Accordion title="Push Rejected - Verified Author or Push Rules">
    * In **Config -> Connections**, edit the saved GitLab connection and set `git_author_mode` to `authenticated_git_user` or `custom`
    * If you choose `custom`, also set both `git_author_name` and `git_author_email`
    * Genesis uses the resolved author for local commits and for the managed GitLab Commits API fallback path when a remote push is rejected
    * Retry the GitLab review or push step after updating the connection
  </Accordion>

  <Accordion title="API Commit Fails - STALE_REMOTE_HEAD">
    * Another commit reached the target branch after your API commit was prepared
    * The response includes `expected_sha` and `actual_sha` so you can see the mismatch
    * Refresh the dev session or re-read the managed repo state, then rebuild the change against the latest remote branch head and retry
  </Accordion>

  <Accordion title="Merge Request Cannot Be Merged">
    * Resolve merge conflicts locally first
    * Ensure CI/CD pipeline passes
    * Check if approval requirements are met
    * Verify target branch is not locked
  </Accordion>

  <Accordion title="File Not Found">
    * Verify file\_path uses forward slashes (/)
    * Check path is relative without leading slash
    * Use `file(action="list")` to see available files
    * Ensure you're on the correct branch
  </Accordion>

  <Accordion title="API Rate Limit Exceeded">
    * Wait for rate limit window to reset (usually 1 minute)
    * Batch operations to reduce API calls
    * Consider upgrading GitLab tier for higher limits
    * Check rate limit status in error response
  </Accordion>

  <Accordion title="Clone Failed - Repository Not Found">
    * Verify repository URL is correct
    * Check if repository is private and you have access
    * Ensure credentials have correct scopes
    * For self-hosted: verify network connectivity
  </Accordion>
</AccordionGroup>

## **Comparison: GitLab vs GitHub**

| Feature | GitLab | GitHub |
| - | - | - |
| **Code Review** | Merge Requests (MRs) | Pull Requests (PRs) |
| **CI/CD** | Built-in (`.gitlab-ci.yml`) | GitHub Actions (separate) |
| **Issue Tracking** | Integrated Issues & Boards | GitHub Issues |
| **Self-Hosted Option** | ✅ Yes (GitLab CE/EE) | ❌ Enterprise only |
| **Approval Workflows** | ✅ Advanced approval rules | Limited (required reviewers) |
| **Container Registry** | ✅ Built-in | ✅ GitHub Packages |
| **Wiki** | ✅ Built-in | ✅ Built-in |
| **API Rate Limits** | 300-1000/min (tier-based) | 5000/hour |

<Note>
  GitHub and GitLab repositories use the same `git_action` and `file` tools. The platform auto-detects whether you're working with GitHub or GitLab based on repository URLs and stored credentials.
</Note>

## **Security Best Practices**

<CardGroup cols={2}>
  <Card title="Token Scopes" icon="key">
    Use minimal required scopes. Avoid `sudo` and `admin` scopes unless absolutely necessary.
  </Card>

  <Card title="Token Rotation" icon="rotate">
    Regularly rotate Personal Access Tokens. Set expiration dates and renew proactively.
  </Card>

  <Card title="Protected Branches" icon="shield">
    Configure branch protection rules in GitLab UI. Require MRs and approvals for main branches.
  </Card>

  <Card title="Secret Management" icon="lock">
    Use GitLab CI/CD variables (masked/protected) for secrets. Never commit credentials to repos.
  </Card>
</CardGroup>

## **Enterprise Features**

For GitLab Premium/Ultimate tiers:

* **Code Owners**: Automatic reviewer assignment based on file paths
* **Approval Rules**: Require specific approvers or groups
* **Merge Request Dependencies**: Block merging until dependent MRs complete
* **Security Scanning**: SAST, DAST, dependency scanning in CI/CD
* **Compliance Frameworks**: Enforce policies and audit requirements
* **Advanced Analytics**: Code review analytics, productivity metrics

<Tip>
  Many enterprise teams choose GitLab for its all-in-one platform approach, especially when self-hosting is required for compliance or data sovereignty requirements.
</Tip>
