Josh (Just One Single History)

repository·master·Indexed 21 days ago

https://github.com/josh-project/josh

A platform for scaling Git-based development that enables working with massive repositories through fast, reversible projections (filters) of specific parts of a repository's history. It includes the josh CLI for local partial projections and josh-proxy, a Git HTTP/SSH proxy providing on-the-fly history transformations and a GraphQL API for CI/Build integration.

Tokens
80K
Snippets
141
Records
544
Agent score
81%

What's inside Josh

  1. Overview of Josh – Just One Single History

    master

    Josh is a platform designed to scale distributed development and collaboration with Git. It addresses the challenges of growing organizations by enabling developers to work in codebases of any size without slowing down change velocity.

    Key capabilities include:

    • Repo Filtering: Instead of splitting monorepos into multiple static repositories for scalability or access control, Josh uses fast, reversible Git history transformations. This allows you to present any part of a Git repository (e.g., a subfolder) as an independent repository, preserving history and the ability to contribute while limiting visibility, scope, and CI rebuilds.
    • Build / CI Integration: Josh provides a GraphQL API to check the state of a repository or its partial projections without performing a full checkout. This allows CI systems to quickly determine if a specific subproject has already been successfully built.
  2. What is Josh (Just One Single History)

    master

    Josh is a platform consisting of tools and services designed to extend Git-based distributed development and collaboration. It aims to allow any number of contributors to work on codebases of any scale without reducing change velocity.

    Key capabilities include:

    • Repository Filtering: Allows treating sub-folders of a monorepo as independent repositories with their own history, visibility, and CI scope. This enables dynamic, reversible Git history transformations.
    • CI/Build Integration: Provides a GraphQL API to check the status of any repository part or mapping without needing to check out the full repository.
  3. What is Forge Integration and when to use it

    master

    Forge integration is an optional feature that connects josh to a code hosting platform (currently only GitHub is supported). It is not required for standard git operations like cloning, pushing, or pulling.

    Its primary purpose is to enable automatic pull request management during stacked changes workflows. When using josh changes publish, josh can automatically create or update pull requests for each commit in a stack on GitHub.

  4. What is Josh and how does it work?

    master

    Josh is a tool designed to bridge the gap between monorepos and multirepos by providing a blazingly-fast, incremental, and reversible implementation of git history filtering.

    Unlike traditional tools like git-filter-branch (which is slow and intended for one-off fixes) or git-filter-repo/BFG repo cleaner (which are fast but destructive and intended for maintenance), Josh is designed for everyday workflows.

    Key technical characteristics:

    • Incremental Filtering: Josh uses a persistent cache between runs. The work required to re-run a filter on a new commit is proportional to the changes since the last run, rather than the total length of the history.
    • Reversibility: To ensure operations are reversible, Josh does not allow arbitrary scripting. Instead, it uses a Domain-Specific Language (DSL) to express complex filters as combinations of simpler, predictable ones.
    • Non-destructive: Because filters are reversible and fast, they can be used seamlessly by developers and CI systems to relate histories between different repositories without discarding the original history.
  5. What is a View in josh?

    master

    A view is a named, versioned binding that denotes a filter plus evaluation pragmas (like history flags or migration points) applied to a repository.

    Unlike a standard filter (which is an anonymous, pure expression), a view is tied to a specific Git reference (ref) containing a view.josh file. This allows views to have their own history, access controls, and lifecycle independent of the source code, while still being able to evolve alongside it.

    Key distinctions:

    • Filter: An anonymous pure expression (a tree/history transformation).
    • View: A named, versioned binding (a filter + pragmas).
    • Workspace: The default view template, providing a writable dev-checkout flavor.
  6. What is a workspace in Josh?

    master
    A workspace is a remapped view of a central repository. It allows you to select a specific subset of files and folders from a monorepo and present them in a new, isolated repository layout. This is useful for developers who only need to see and work on code relevant to their specific project, even if that project depends on shared libraries located elsewhere in the monorepo.
  7. Understand the concept of Views in josh

    master

    A View is a named, versioned filter object stored as a git ref. A view is identified by any ref whose commit tree contains a view.josh file.

    Views are designed to decouple the filter definition from the repository history, solving several limitations of the legacy workspace mechanism:

    • Versioned Policy: Provides a mutable, versioned home for meta options (like history flags, gpgsig handling, or compatibility flags) without requiring changes to the source history.
    • Migration Points: Allows recording structural changes (e.g., moving a root directory) at specific points in time using :rev.
    • Stable Identity: Unlike legacy workspaces, which vary depending on the branch being fetched, a View provides a consistent identity for use in CI configurations and remote URLs.
    • Decoupled Storage: The view stores the view.josh text itself, rather than a serialized filter representation.
  8. Understand josh Levels and Worktree isolation

    master

    Concept: Levels and Namespaces

    In josh, Levels are distinct histories related by filters. There is no single 'canonical' history; instead, remotes and worktrees sit at different levels.

    To prevent accidental usage of unrelated branches, josh uses Namespaces at the protocol layer. Every level is a git namespace in the store (e.g., refs/namespaces/<level>/...). A worktree only sees the refs belonging to its specific level.

    Concept: How history flows between levels

    • Same level (e.g., a worktree and a remote at the same level): Use standard git fetch and git push. No filtering occurs.
    • One edge apart (e.g., a worktree at a filtered level and a remote at the wider level):
      • josh fetch applies the filter to move history from the wider level to the filtered level.
      • josh push 'unapplies' the filter to move history from the filtered level back to the wider level.

    Comparison: josh worktrees vs. git sparse-checkout

    Featuregit sparse-checkoutjosh worktree
    ScopeNarrows working treeNarrows working tree AND history
    PathsFull paths preservedSupports path remapping
    HistoryFull history/log/blameFiltered history (scoped log/blame)
    Round-tripNo notion of pushing projectionsSupports pushing filtered changes back to upstream
  9. Compare Josh with git subtree

    master

    Josh is a high-performance alternative to git subtree:

    • git subtree: Often too slow for daily use on medium-sized repositories unless commits are squashed (which results in loss of history).
    • Josh: Provides a highly optimized implementation of the git subtree split concept, specifically designed to be run frequently within the same repository without the performance penalties or history loss associated with git subtree.
  10. Understand the Worktree-centric CLI model

    master

    The josh CLI uses a 'bare-repo-plus-worktrees' pattern rather than a direct git drop-in replacement model. This design separates the shared object store from the specific filtered views (projections) you work on.

    Core Components

    • Shared Store: Created via josh init, this is a bare repository that holds the shared object store, cache, and network fetch logic. It does not contain a working checkout.
    • Upstreams: Attached to the store using josh remote add.
    • Worktrees: Created via josh worktree add, these are filtered checkouts. Each worktree is tied to a specific filter (projection), allowing you to work on different parts of a repository side-by-side.

    Key Benefits

    • Shared Costs: Unfiltered history is fetched once for all worktrees. Filtering work is cached in a shared sled cache, so multiple worktrees (or multiple agents) do not multiply network or CPU costs.
    • Isolation: A worktree is a physical scope boundary. An agent or user cannot touch files outside the worktree's projection.
    • Plain Git Compatibility: Inside a worktree, everything is standard git. git fetch and git push operate on the local, filtered history provided by the josh store via git namespaces.
  11. Use locator filters to find `view.josh` in existing branches

    master

    By default, josh looks for view.josh at the root of a ref. However, you can use a locator filter to specify a subdirectory where the view resides within an existing branch (e.g., main).

    A view reference is a pair of (ref, locator). The locator is a path-selecting filter (a subdirectory chain) applied to the ref's tree before looking up view.josh.

    Example: If the ref is refs/heads/main and the locator is :/views/foo, josh will look for the view definition at views/foo/view.josh on the main branch.

  12. Syntax for Josh history filters

    master

    Josh transforms git history by applying filters to commits. Filters always begin with a colon (:) and can be chained together (e.g., :filter1:filter2).

    Usage Rules:

    • URLs: Filters used in URLs must not contain whitespace or newlines.
    • Files: When reading from a file, whitespace can be inserted between filters (but not after the leading colon), and newlines can be used instead of commas in composition filters.
    • Arguments: Arguments can be optionally quoted with double quotes if they contain special characters like : or spaces.

    Example Syntax:

    :filter1:filter2
    :filter=argument1,"argument2"