Liking cljdoc? Tell your friends :D

com.blockether.vis.ext.channel-tui.magit

Magit-style PORCELAIN layer for the TUI — the pure, testable half of the C-x g status buffer. Everything runs over the native git CLI via internal.git/run-git; nothing here touches a terminal.

Three surfaces:

  • status-model — one snapshot of the repo: head/upstream facts plus the magit sections (untracked / unstaged / staged / unmerged / stashes / unpushed / unpulled / recent commits).
  • actions — stage-file!, unstage-file!, discard-file!, commit!, push!, pull!, fetch!, branch and stash verbs. Each returns {:ok? bool :msg str} so the dialog can echo success/failure verbatim.
  • status-rows — PURE projection of a model (+ the expanded-diff set) into renderable row maps; the dialog only paints and moves a cursor over what this returns.

Keeping the model/actions/rows split pure means the whole magit feature is exercisable in tests against a throw-away repo, with zero lanterna.

Magit-style PORCELAIN layer for the TUI — the pure, testable half of the
C-x g status buffer. Everything runs over the native `git` CLI via
`internal.git/run-git`; nothing here touches a terminal.

Three surfaces:

- `status-model`   — one snapshot of the repo: head/upstream facts plus the
                     magit sections (untracked / unstaged / staged /
                     unmerged / stashes / unpushed / unpulled / recent
                     commits).
- actions          — `stage-file!`, `unstage-file!`, `discard-file!`,
                     `commit!`, `push!`, `pull!`, `fetch!`, branch and
                     stash verbs. Each returns `{:ok? bool :msg str}` so
                     the dialog can echo success/failure verbatim.
- `status-rows`    — PURE projection of a model (+ the expanded-diff set)
                     into renderable row maps; the dialog only paints and
                     moves a cursor over what this returns.

Keeping the model/actions/rows split pure means the whole magit feature is
exercisable in tests against a throw-away repo, with zero lanterna.
raw docstring

checkout-branch!clj

(checkout-branch! root branch)
source

commit!clj

(commit! root message {:keys [amend?]})

Refuses an empty message and — like magit's Nothing staged guard — a non-amend commit over a clean index (a bare git commit failure would echo a whole status dump). The index guard only applies when HEAD resolves: diff --cached --quiet reports clean on an unborn branch even with staged files.

Refuses an empty message and — like magit's `Nothing staged` guard — a
non-amend commit over a clean index (a bare `git commit` failure would echo
a whole status dump). The index guard only applies when HEAD resolves:
`diff --cached --quiet` reports clean on an unborn branch even with staged
files.
sourceraw docstring

commit-diff-linesclj

(commit-diff-lines root {:keys [sha]})

Diff body for one commit row, as plain lines (for the TAB fold): the patch git show produces for sha, kept from the first diff --git header down so every file the commit touched is named.

Diff body for one commit row, as plain lines (for the TAB fold): the patch
`git show` produces for `sha`, kept from the first `diff --git` header down so
every file the commit touched is named.
sourceraw docstring

create-branch!clj

(create-branch! root name)

Create AND check out name (magit's b c).

Create AND check out `name` (magit's `b c`).
sourceraw docstring

delete-branch!clj

(delete-branch! root name {:keys [force?]})
source

discard-file!clj

(discard-file! root {:keys [path area]})

Magit's k: throw the change away.

  • untracked file → delete it (git clean -f)
  • UNSTAGED change → restore the INDEX version in the worktree only (git checkout -- path) — the staged half of the same file survives, exactly like magit
  • staged change in HEAD → restore the HEAD version in index AND worktree
  • added, not in HEAD → unstage only (the file survives as untracked — never silently delete content git has never stored).
Magit's `k`: throw the change away.
- untracked file        → delete it (`git clean -f`)
- UNSTAGED change       → restore the INDEX version in the worktree only
                          (`git checkout -- path`) — the staged half of the
                          same file survives, exactly like magit
- staged change in HEAD → restore the HEAD version in index AND worktree
- added, not in HEAD    → unstage only (the file survives as untracked —
  never silently delete content git has never stored).
sourceraw docstring

fetch!clj

(fetch! root)
source

file-diff-linesclj

(file-diff-lines root {:keys [path area]})

Diff body for one file row, as plain lines (for the TAB fold). area picks the side: :staged → diff --cached, :unstaged/:unmerged → diff, :untracked → the file's own content rendered as additions.

Diff body for one file row, as plain lines (for the TAB fold).
`area` picks the side: :staged → `diff --cached`, :unstaged/:unmerged →
`diff`, :untracked → the file's own content rendered as additions.
sourceraw docstring

first-selectableclj

(first-selectable rows idx)

Index of the first selectable row at-or-after idx (wrapping search both directions handled by the caller); nil when nothing is selectable.

Index of the first selectable row at-or-after `idx` (wrapping search both
directions handled by the caller); nil when nothing is selectable.
sourceraw docstring

head-rowsclj

(head-rows {:keys [branch detached? head head-subject upstream? upstream ahead
                   behind]})

The Head: / Merge: preamble of the status buffer.

The `Head:` / `Merge:` preamble of the status buffer.
sourceraw docstring

head-subjectclj

(head-subject root)

Subject line of HEAD's commit, or nil on an unborn branch.

Subject line of HEAD's commit, or nil on an unborn branch.
sourceraw docstring

last-commit-messageclj

(last-commit-message root)

Full message of HEAD's commit (for amend pre-fill), or nil.

Full message of HEAD's commit (for amend pre-fill), or nil.
sourceraw docstring

load-reposclj

(load-repos repo-entries)

Attach a fresh :model snapshot to every repo entry — one status-model read per root. The refresh path of a multi-root buffer.

Attach a fresh `:model` snapshot to every repo entry — one `status-model`
read per root. The refresh path of a multi-root buffer.
sourceraw docstring

local-branchesclj

(local-branches root)

Local branches as [{:name :current?}], current first.

Local branches as `[{:name :current?}]`, current first.
sourceraw docstring

multi-status-rowsclj

(multi-status-rows repos expanded diff-fn)

Rows for one OR many repos. repos is [{:root :label :draft? :model}] (:model a status-model, nil outside a git repo). ONE repo renders exactly like status-rows — the single-root buffer looks unchanged — while several repos each get a :repo header row. EVERY row is tagged with its :root so the dialog's verbs route to the right repo.

expanded is a set of [root area path] triples; diff-fn receives the root-tagged file row.

Rows for one OR many repos. `repos` is `[{:root :label :draft? :model}]`
(`:model` a `status-model`, nil outside a git repo). ONE repo renders
exactly like `status-rows` — the single-root buffer looks unchanged —
while several repos each get a `:repo` header row. EVERY row is tagged
with its `:root` so the dialog's verbs route to the right repo.

`expanded` is a set of `[root area path]` triples; `diff-fn` receives the
root-tagged file row.
sourceraw docstring

next-selectableclj

(next-selectable rows idx dir)

Index of the nearest selectable row moving from idx by dir (+1/-1); returns idx unchanged when there is none further that way.

Index of the nearest selectable row moving from `idx` by `dir` (+1/-1);
returns `idx` unchanged when there is none further that way.
sourceraw docstring

pull!clj

(pull! root)
source

push!clj

(push! root {:keys [set-upstream? force?]})

opts: :set-upstream? adds -u origin <branch>, :force? uses --force-with-lease (never bare --force).

`opts`: :set-upstream? adds `-u origin <branch>`, :force? uses
`--force-with-lease` (never bare --force).
sourceraw docstring

range-commitsclj

(range-commits root range-spec)

Commits in range-spec (e.g. "@{upstream}..HEAD") as [{:sha :subject}], newest first. Empty when the range is empty or unresolvable.

Commits in `range-spec` (e.g. "@{upstream}..HEAD") as `[{:sha :subject}]`,
newest first. Empty when the range is empty or unresolvable.
sourceraw docstring

recent-commitsclj

(recent-commits root n)

Latest n commits as [{:sha :subject}], newest first.

Latest `n` commits as `[{:sha :subject}]`, newest first.
sourceraw docstring

repo-rowclj

(repo-row {:keys [label root draft?]})

The repo header row a multi-root buffer shows above each repo's sections.

The repo header row a multi-root buffer shows above each repo's sections.
sourceraw docstring

section-ofclj

(section-of rows section-idx)

The [area path]-bearing rows covered by a :section header row — used for section-wide stage/unstage (s/u on the header). Stops at the next :section OR :repo header and only matches rows of the SAME repo (:root), so a multi-root buffer never bleeds one repo's files into another's section.

The `[area path]`-bearing rows covered by a `:section` header row —
used for section-wide stage/unstage (`s`/`u` on the header). Stops at the
next `:section` OR `:repo` header and only matches rows of the SAME repo
(`:root`), so a multi-root buffer never bleeds one repo's files into
another's section.
sourceraw docstring

selectable?clj

(selectable? {:keys [kind]})

Rows the dialog cursor can land on.

Rows the dialog cursor can land on.
sourceraw docstring

stage-all!clj

(stage-all! root)
source

stage-file!clj

(stage-file! root path)
source

stash-apply!clj

(stash-apply! root ref)
source

stash-drop!clj

(stash-drop! root ref)
source

stash-pop!clj

(stash-pop! root ref)
source

stash-push!clj

(stash-push! root message)

Stash the working tree INCLUDING untracked files (the least surprising default for a status-buffer 'stash everything' verb). Git exits 0 with 'No local changes to save' when there is nothing to stash — surface that as a failure so the dialog doesn't claim success.

Stash the working tree INCLUDING untracked files (the least surprising
default for a status-buffer 'stash everything' verb). Git exits 0 with
'No local changes to save' when there is nothing to stash — surface that
as a failure so the dialog doesn't claim success.
sourceraw docstring

stashesclj

(stashes root)

Stash list as [{:ref "stash@{0}" :message}], newest first.

Stash list as `[{:ref "stash@{0}" :message}]`, newest first.
sourceraw docstring

status-modelclj

(status-model root)

One full magit snapshot of the repo at root, or nil outside a repo.

{:branch :detached? :head :upstream? :upstream :ahead :behind :head-subject :untracked [path …] :unstaged [{:path :code} …] ;; worktree side (porcelain Y) :staged [{:path :code} …] ;; index side (porcelain X) :unmerged [{:path :code} …] :stashes [{:ref :message} …] :unpushed [{:sha :subject} …] ;; @{upstream}..HEAD — magit's Unmerged into :unpulled [{:sha :subject} …] ;; HEAD..@{upstream} — magit's Unpulled from :commits [{:sha :subject} …]}

One full magit snapshot of the repo at `root`, or nil outside a repo.

{:branch :detached? :head :upstream? :upstream :ahead :behind
 :head-subject
 :untracked [path …]
 :unstaged  [{:path :code} …]     ;; worktree side (porcelain Y)
 :staged    [{:path :code} …]     ;; index side   (porcelain X)
 :unmerged  [{:path :code} …]
 :stashes   [{:ref :message} …]
 :unpushed  [{:sha :subject} …]   ;; @{upstream}..HEAD — magit's `Unmerged into`
 :unpulled  [{:sha :subject} …]   ;; HEAD..@{upstream} — magit's `Unpulled from`
 :commits   [{:sha :subject} …]}
sourceraw docstring

status-rowsclj

(status-rows model expanded)
(status-rows {:keys [untracked unstaged staged unmerged stashes commits upstream
                     unpushed unpulled]
              :as model}
             expanded
             diff-fn)

PURE projection: model (+ expanded set of [area path], + optional diff-fn row→lines) → renderable rows. Every row is {:kind :info|:section|:file|:diff|:stash|:commit|:blank :text …}. Section order mirrors magit: unpushed commits render as Unmerged into <upstream> and Recent commits appears ONLY when nothing is unpushed (magit's unpushed-to-upstream-or-recent); Unpulled from <upstream> closes the buffer when the branch is behind.

PURE projection: model (+ `expanded` set of `[area path]`, + optional
`diff-fn` row→lines) → renderable rows. Every row is
`{:kind :info|:section|:file|:diff|:stash|:commit|:blank :text …}`.
Section order mirrors magit: unpushed commits render as
`Unmerged into <upstream>` and `Recent commits` appears ONLY when nothing
is unpushed (magit's `unpushed-to-upstream-or-recent`); `Unpulled from
<upstream>` closes the buffer when the branch is behind.
sourceraw docstring

unstage-all!clj

(unstage-all! root)
source

unstage-file!clj

(unstage-file! root path)

Magit's u: git reset -q -- path. Unlike restore --staged this also works on an unborn HEAD (before the first commit), exactly like magit.

Magit's `u`: `git reset -q -- path`. Unlike `restore --staged` this also
works on an unborn HEAD (before the first commit), exactly like magit.
sourceraw docstring

upstream-nameclj

(upstream-name root)

Short name of the current branch's upstream (origin/main), or nil.

Short name of the current branch's upstream (`origin/main`), or nil.
sourceraw docstring

workspace-rootsclj

(workspace-roots ws fallback-root)

Ordered repo entries the magit buffer shows for one SESSION: the primary workspace root first, then every extra filesystem root (/fs, the dir picker). Accepts the gateway session-workspace-info map in EITHER key shape (in-process kebab or canonical snake wire); ws nil → one entry for fallback-root.

DRAFT semantics: each entry's :root is the path the session actually EDITS — for a draft that's the CLONE (primary :root, extras' :clone), never the trunk — with :trunk carrying the real dir it was forked from and :draft? set. Deduped by :root, order preserved.

Entry: {:root abs-path :trunk abs-path :label basename :draft? bool}.

Ordered repo entries the magit buffer shows for one SESSION: the primary
workspace root first, then every extra filesystem root (`/fs`, the dir
picker). Accepts the gateway `session-workspace-info` map in EITHER key
shape (in-process kebab or canonical snake wire); `ws` nil → one entry for
`fallback-root`.

DRAFT semantics: each entry's `:root` is the path the session actually
EDITS — for a draft that's the CLONE (primary `:root`, extras' `:clone`),
never the trunk — with `:trunk` carrying the real dir it was forked from
and `:draft?` set. Deduped by `:root`, order preserved.

Entry: `{:root abs-path :trunk abs-path :label basename :draft? bool}`.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close