URI: scheme://authority/path?ref#fragment

-- gritzko

Beagle employs Uniform Resource Identifiers (URIs) to uniformly identify all the revision controlled resources (surprise!). URIs address any repos, files, branches, revisions, blobs and any views/projections the system can produce. URI format is [scheme:][//authority][path][?ref][#fragment]. The use of URIs mainly agrees with the common practices. Revision specific info goes into query (?branch) or fragment (#hashpin). The query/branch part implies some actual history DAG while the fragment/pin implies lone commit object.

//URI-123

Local worktree URIs: a scheme-less //name is a worktree, period — a remote URI always carries its transport scheme. Worktrees live in the the meta-project's work/ dir: work/URI-123/ goes as //URI-123, its files as //URI-123/main.js. The work/ dir is ignored by the meta-project's own revision control; the worktrees under it share one Store.

file:/home/gritzko/src/

Filesystem based URI. Standard. No authority. May point to a literal file or directory. May point at a repo/worktree. Then, the path must lead to a .be/ store or a .be store pointer. Paths ending in .be imply the exact store path. May use query/fragment for branch/hash. file: clone creates a flat worktree / reuses the original store.

https://github.com

A regular git smart protocol HTTP URI, same as GitHub provides. By convention, may add branch/hash information into query/fragment; that info is consumed/stripped locally.

ssh://git@github.com

A regular ssh-based git smart protocol endpoint. git tends to use ssh-style non-standard URI syntax, e.g. git@github.com:gritzko/libdog.git. Beagle accepts that, but normalizes to ssh://git@github.com/gritzko/libdog.git internally, see RFC3986. May use query/fragment for branch/hash.

be://replicated.live?/project/branch

Beagle protocol URI. The protocol supports sharded .be Stores carrying multiple projects, some scalability and performance features. Works over HTTP. Natively uses query and fragment for branch/hash information, passes that to the server.

Relative URIs: ./sub, ../, ?hashlet, etc

URIs as typed by the user can be context-dependent — relative or implied paths, tags, branches. For internal use and storage fully-resolved URIs are safer, so URIs get resolved at the entry point, to prevent any later ambiguity.

Path shapes: legacy, repo-relative, recursive, cwd-relative

URI paths specify paths in the tree objects that lead to the tree/blob/submodule of interest. In some cases (legacy/ssh:/file:), a path may also specify the file system path to the repo. (Beagle per se prefers one repo per host.) So, the cases are:

Query shapes: resolved, absolute, project- & branch-relative

Beagle branches are tree-structured, the trunk is named as the project e.g. ?/beagle. Cases are:

URI->hash resolution

In all contexts that require resolution to a hash, we use

    resolve_hash(context_uri, uri) -> {
	    store: "/home/gritzko/.be/",  // object store
		mpath: "/home/gritzko/src/journal/", // main tree
		shard: "libdog",   // the repo in question
		wtree: "ABC-123",  // worktree
		spath: "abc/",     // (innermost) submodule path
		rpath: "SHA.h",    // path within submodule
		chash: "f425d6a84528cdf46125a3c12bfd2979786eadad",
		otype: "blob",
	    ohash: "5efa169aeadd9b0c952cfffdd0b8d1f8c81bd119",
    }

In all the CLI runs, the context URI is derived from $PWD, in all TUI runs by the TUI shell. Resolution proceeds as follows:

  1. First, we resolve the root of the project. We keep climbing till we find the topmost .be file or dir

still lower than $HOME. That is the project root It either has its own store in .be/ or its .be file references the repo in the first line, as e.g. 26625HI34e repo file:/home/gritzko/.be/journal At this point, we have store and mpath.

  1. //WT/wtrel stands for $SRC_ROOT/work/WT/wtrel,

///mtrel stands for $SRC_ROOT/mtrel, worktree and maintree paths respectively.

  1. uri is resolved relative to the context_uri the following way:

1. if uri lacks a worktree, it is taken from the context_uri 2. if uri has a relative path, it is resolved relative to the context_uri

  1. At this point, the filesystem path is fixed, we may derive shard, wtree, spath, rpath.
  2. At which point we resolve chash:
    1. If the object #fullsha1hash is set, we check in store/shard index if it is a commit, done.
    2. If #hashlet is set, we resolve it against store/ shard index, check if it is a commit, done.
    3. If the ?branch is set, we resolve it against store/shard reflog, done.
    4. If ?hashlet is set, we resolve it against store/ shard index, check if it is a commit, done.

5. Having wtree and spath we check the tree's current commit (the last get or post record), done.

  1. If rpath is specified, we follow the path from the store/shard/chash root to obtain otype, ohash.