gitgrip 1.0.0

Multi-repo workflow tool - manage multiple git repositories as one
Documentation
# gitgrip Manifest Schema Specification
# Version: 2
#
# This document describes the structure of a gitgrip gripspace.yml file.
# The workspace file defines a multi-repository workspace configuration.

# Schema version (required)
version: 2

# Named remotes with base fetch URLs (optional, v2)
# Repos can reference a remote by name instead of specifying a full URL.
# The repo name + ".git" is auto-appended to the fetch base URL.
remotes:
  upstream:
    fetch: "git@github.com:org/"    # → git@github.com:org/<repo-name>.git

# Gripspace includes (optional)
# Include repos, scripts, env, hooks, and linkfiles from other gripspace repositories.
# Gripspaces are cloned into .gitgrip/spaces/<name>/ and their manifests are merged.
# Local manifest values always win on conflict.
# Supports recursive includes (max depth: 5) with cycle detection.
gripspaces:
  - url: "https://github.com/org/base-gripspace.git"
    rev: "main"                   # Optional: pin to branch/tag/commit (default: remote HEAD)

# Manifest repository self-tracking (optional)
# If specified, gitgrip will include the manifest repo in sync/branch/push operations
manifest:
  # Git URL for the manifest repository (required)
  url: "git@github.com:org/workspace-manifest.git"

  # Upstream revision (defaults to "main")
  revision: "main"

  # Files to copy from manifest repo to workspace root (optional)
  copyfile:
    - src: "envsetup.sh"          # Source path relative to manifest repo
      dest: "envsetup.sh"         # Destination path relative to workspace root

  # Symlinks from workspace to manifest repo (optional)
  linkfile:
    - src: "config/shared.yaml"
      dest: ".config/shared.yaml"

  # Composed files (optional)
  # Generate files by concatenating parts from gripspaces and/or local manifest repo.
  # Processed on every `gr sync` and `gr link --apply`.
  composefile:
    - dest: "CLAUDE.md"           # Destination path relative to workspace root
      separator: "\n\n"           # Optional separator between parts (default: "\n\n")
      parts:
        - gripspace: "base-gripspace"  # Read from .gitgrip/spaces/base-gripspace/
          src: "CODI.md"               # Source path relative to gripspace root
        - src: "PRIVATE_DOCS.md"       # Read from manifest content dir (spaces/main/ or manifests/)

  # Platform override for self-hosted instances (optional)
  platform:
    type: "github"                # github, gitlab, azure-devops, bitbucket
    base_url: "https://github.mycompany.com"

# Repository definitions (required, at least one)
repos:
  # Key is the repository name used in gitgrip commands
  frontend:
    # Git URL - SSH or HTTPS (required unless `remote` is set)
    url: "git@github.com:me/frontend.git"

    # Local path relative to workspace root (required)
    path: "./frontend"

    # Upstream revision to clone/sync (defaults to "main", inherits from settings)
    revision: "main"

    # PR base branch (just a branch name, inherits from settings, then revision)
    target: "develop"

    # Remote for fetch/rebase (defaults to "origin", inherits from settings)
    sync_remote: "upstream"

    # Remote for push (defaults to "origin", inherits from settings)
    push_remote: "origin"

    # Groups for selective operations (optional)
    # Use with: gr sync --group=core
    groups:
      - core
      - web

    # Mark as reference/read-only repo (optional, defaults to false)
    # Reference repos are synced but excluded from branch/commit/PR operations
    reference: false

    # Platform override (optional, auto-detected from URL)
    platform:
      type: "github"
      base_url: null              # Only needed for self-hosted instances

    # Files to copy after clone/sync (optional)
    copyfile:
      - src: "README.md"
        dest: "docs/FRONTEND_README.md"

    # Symlinks to create (optional)
    linkfile:
      - src: ".env.example"
        dest: ".env"

    # Agent context for AI tools (optional)
    # Machine-readable metadata for AI coding agents
    agent:
      description: "React web frontend"
      language: "typescript"
      build: "pnpm build"
      test: "pnpm test"
      lint: "pnpm lint"
      format: "pnpm format"

  # Repo using top-level remote (URL derived: git@github.com:org/backend.git)
  backend:
    remote: "upstream"
    path: "./backend"
    revision: "master"
    target: "staging"
    groups:
      - core
      - api
    agent:
      description: "Rust API server"
      language: "rust"
      build: "cargo build"
      test: "cargo test"
      lint: "cargo clippy"
      format: "cargo fmt"

  # Reference repositories (read-only)
  reference-lib:
    url: "https://github.com/external/lib.git"
    path: "./ref/lib"
    reference: true               # Excluded from branch/commit operations

# Global settings (optional)
settings:
  # Prefix for PR titles (defaults to "[cross-repo]")
  pr_prefix: "[cross-repo]"

  # Merge strategy for linked PRs
  # all-or-nothing: All PRs must merge together or none
  # independent: Each PR can be merged separately
  merge_strategy: "all-or-nothing"

  # Default revision for all repos (defaults to "main")
  revision: "main"

  # PR base branch for all repos (defaults to revision)
  target: "develop"

  # Default remote for fetch/rebase (defaults to "origin")
  sync_remote: "origin"

  # Default remote for push (defaults to "origin")
  push_remote: "origin"

# Resolution chains:
#   revision:    repo > settings > "main"
#   target:      repo > settings > revision
#   sync_remote: repo > settings > "origin"
#   push_remote: repo > settings > "origin"
#   url:         explicit url, or remotes[repo.remote].fetch + name + ".git"

# Workspace configuration (optional)
# Includes scripts, hooks, env, CI, and agent metadata
workspace:
  # Environment variables available to workspace scripts
  env:
    NODE_ENV: "development"
    WORKSPACE_NAME: "myproject"

  # Named scripts runnable via `gr run <name>`
  scripts:
    build:
      description: "Build all packages"
      command: "npm run build"
      cwd: "."                    # Working directory (optional)

    test:
      description: "Run all tests"
      # Multi-step scripts
      steps:
        - name: "Lint"
          command: "npm run lint"
          cwd: "./frontend"
        - name: "Unit tests"
          command: "npm test"
        - name: "Integration tests"
          command: "npm run test:integration"

  # Lifecycle hooks (optional)
  hooks:
    # Run after `gr sync`
    post-sync:
      - command: "npm install"
        cwd: "./frontend"
      - command: "cargo build"
        cwd: "./backend"

    # Run after `gr checkout`
    post-checkout:
      - command: "./scripts/setup-env.sh"

  # CI/CD pipelines runnable via `gr ci run <name>`
  ci:
    pipelines:
      test:
        description: "Run full test suite"
        steps:
          - name: "Install dependencies"
            command: "npm ci"
          - name: "Run tests"
            command: "npm test"
            continue_on_error: false
          - name: "Upload coverage"
            command: "npm run coverage:upload"
            env:
              COVERAGE_TOKEN: "${COVERAGE_TOKEN}"

  # Agent context for AI tools (optional)
  # Workspace-level metadata for AI coding agents
  agent:
    description: "Multi-repo web application workspace"
    conventions:
      - "Use conventional commits (feat:, fix:, chore:)"
      - "All PRs require review before merge"
      - "Use gr commands, never raw git"
    workflows:
      deploy: "gr pr merge && ./scripts/deploy.sh"
      release: "gr run release"

# Supported platform types:
# - github: GitHub.com or GitHub Enterprise
# - gitlab: GitLab.com or self-hosted GitLab
# - azure-devops: Azure DevOps (dev.azure.com) or Azure DevOps Server
# - bitbucket: Bitbucket Cloud or Bitbucket Server

# Path rules:
# - Paths must be relative to workspace root
# - Paths cannot start with ".." or "/"
# - Paths cannot contain "/../"
# - These rules prevent directory traversal attacks

# v1 Backward Compatibility:
# - v1 manifests are auto-migrated when parsed
# - `default_branch` is accepted as an alias for `revision`
# - `target` containing "/" (e.g. "upstream/develop") is split into target + sync_remote
# - Version is upgraded to 2 internally