GET: repo-to-worktree verb (checkout, clone, switch, restore)

gritzko

GET exports git trees from repo into the worktree: clone, switch branch, detach, or restore in git's terms. The regular form does fast-forward/backward, maybe re-applying uncommitted changes. The forceful form resets the worktree to a chosen version, deleting all the untrackeds. The exact action is defined by the shape of the URI:

  1. Path: (unless Host is set) scopes to file/subtree/submod,
  2. Fragment: a sha pin, in case we want to specify the exact commit.
  3. Query: the branch/tag/hash to switch to,
  4. Host: either a remote or a scheme-less form of //name for a worktree.
  5. Scheme: the protocol (ssh: be: file:) to use for a remote.

CLI use

be get...
                     (empty) bare: move the wt to cur's branch tip
?feat                switch wt+cur to branch feat
?./fix               enter a child branch (?../sib a sibling)
?                    switch to the trunk
?abc1234             detached checkout at a sha
#~1                  rewind cur one commit, reset the wt
file.c               restore one file from cur's baseline
file.c?feat          get file.c from feat's tip
//ABC-123            checkout the rev worktree ABC-123 is on
ssh://host?feat      fetch, then checkout
ssh://host/repo.git  clone: fetch + checkout (recurses subs)
file:../proj?feat    wire an empty cwd as a sibling worktree

RefLog/WTLog interaction

  1. Reference Log: resolves the ?ref#sha to a tip sha,
  2. Worktree Log: writes a get row (the new base branch + tip hash),

Forceful execution

The regular form can only do fast-forward or fast-backward, refuses otherwise. The local changes get carried over by weave merge. The forceful form be get! resets the worktree to a clean state, all local changes discarded. That can be any commit, not necessarily fast-forward or fast-backward.

Summary of invocation patterns

gritzko, no LLM allowed

get is the most basic Beagle operation: get a specific revision of a repo and probably its nested submodules. Clone, checkout, update, switch, etc. The recentmost get defines which ref the tree tracks and what is its base commit (base commit can also be changed by post).

  1. get comes in many forms:
    1. bare get - implies the tracked ref as the argument (the recentmost get record of the wtlog contains the tracked URI; can be any case of 2..6)
    2. get ?branch, get ?tag, specify the target ref in the local store (can use branch paths, incl relative, e.g. get ?../sibling_branch)
    3. get //worktree/path - worktree get (reads the base hash of that tree, tracks that tree afterwards, same-store op),
    4. get #hash - direct commit checkout, detaches the worktree;
    5. get #~1 - roll back one commit,
    6. get file:..., get https:..., get ssh:..., `get
    be:...` all include the network leg, conversation with git's or own daemon to obtain refs and objects; the only pattern that changes something in the store.
  2. get can be 0. bootstrap clone, no local copy, creates wtlog and the checkout 1. normal, when dirty file changes get weaved into the new versions 2. get! forceful that discards local changes and untracked files, can go to any commit (not just ff/fb) 3. get file.c, get dir/ - current tip, narrowed to a specific path (recovers) 4. get! file.c narrowed forceful, resets a file/subdir 5. get //WORK/submod/path/file.c cherry-picking files from other refs (an optional feature)
  3. commit history wise, the target can be 1. ahead 2. behind 3. same - nothing to do 4. divergent
  4. the tree dirtiness: 0. clean tree - get new blobs, 1. in case local files have uncommitted changes, those are carried over by weave merge; if that fails, errs out.
  5. get submodule recursion rules:
    1. does not recur if invoked with --nosub
    2. by default: gets submodule's pinned hash
      • for every submodule that is attached to the parent's pin
      • while ignoring modules that are attached differently
    3. get! forcefully: into every submodule, gets its pinned hash