NORMAL ~/wkd/p/gitsuite/help :set skin=modern utf-8

gitsuite.txt

One :Git command tree for everything git — gitsuite.nvim

doc/gitsuite.txt — rendered from the plugin's own vimdoc

*gitsuite.txt*  One :Git command tree for everything git             *gitsuite.nvim*

Author:   Stefan Bartl
Version:  0.1.0

CONTENTS *gitsuite-contents*

  1. Introduction .............. |gitsuite-intro|
  2. Requirements ............... |gitsuite-requirements|
  3. Installation ............... |gitsuite-installation|
  4. Commands .................... |gitsuite-commands|
  5. Configuration ............... |gitsuite-config|
  6. Adapters ..................... |gitsuite-adapters|
  7. Events ....................... |gitsuite-events|
  8. Statusline ................... |gitsuite-statusline|
  9. Health check ................. |gitsuite-health|

1. INTRODUCTION *gitsuite-intro*

gitsuite.nvim collects every git-related user command this config used to
spread across seven external plugins into one :Git <scope> <action> tree
(see |gitsuite-commands|). It follows the filetree.nvim pattern: its own
implementation where that pays off (merge-conflict resolution, blame,
browse), and a thin adapter where an external plugin has already done years
of edge-case work (gitsigns' hunk engine, neogit's staging UI, diffview, the
real lazygit TUI run in a floating terminal).

This is an alpha-stage, actively-growing plugin -- every subcommand listed
in docs/BINDINGS.md is a real implementation, but the surface is not
frozen yet: breaking changes are still possible.

2. REQUIREMENTS *gitsuite-requirements*

- Neovim >= 0.10
- git on $PATH
- StefanBartl/lib.nvim (hard dependency)
- StefanBartl/diff.nvim (hard dependency, used by :Git diff */:Git hunk *)
- StefanBartl/ui.nvim (hard dependency, used by :Git dashboard)

See docs/requirements.md for the optional tools (gitsigns, diffview,
neogit, lazygit, nvr, open.nvim, pickers.nvim) and exactly what each one
backs versus what falls back without it.

3. INSTALLATION *gitsuite-installation*

  {
    "StefanBartl/gitsuite.nvim",
    dependencies = { "StefanBartl/lib.nvim", "StefanBartl/diff.nvim", "StefanBartl/ui.nvim" },
    cmd = "Git",
    config = function(_, opts)
      require("gitsuite").setup(opts)
    end,
  }
See docs/installation.md for packer.nvim, vim-plug and mini.deps variants.

4. COMMANDS *gitsuite-commands*

                                                                        *:Git*
:Git {scope} {action} [args]

Compound command tree with <Tab> completion at every level. See
docs/BINDINGS.md for the full, generated list of {scope} {action} pairs --
that file is generated from the same route tree that drives dispatch, so it
never drifts from what :Git <Tab> actually offers.

:Git ui lazygit [dir] opens lazygit for the repository containing dir (any
directory inside its work tree) instead of the one of the current working
directory; from Lua: require("gitsuite.features.ui").lazygit(dir). A dir
that does not exist or is not inside a git repository is reported, no float
is opened.

Blame without a buffer (for other plugins): `require("gitsuite.features.blame")
.for_location(dir, path, lnum) returns { line, sha, author, author_time,
summary } for one line of path (relative to dir`, or absolute); an
uncommitted line has an all-zero sha. It blocks without a callback; with a
cb(entry, err) as fourth argument it runs asynchronously and returns a
{ stop } handle. Failures (not a repo, untracked file, line past the end) are
nil, err.

                                                          *gitsuite-conflict*
:Git conflict {ours|theirs|both|base|none} resolves the conflict under the
cursor. Markers are matched by their exact length (<<<<<<< opens a conflict,
and every other marker of it has as many characters): git writes a conflict
nested in the base section -- the conflicting virtual ancestor of a criss-cross
merge -- with longer markers, and the conflict-marker-size git attribute
raises the length for a file.

A line that is exactly ======= can be text (the underline of a Markdown
setext heading). In a merge-style conflict that makes the separator
impossible to tell from the text: the region is still highlighted (markers and
every candidate line only), found by :Git conflict next|prev and counted by
has_conflicts(). With more than one candidate, `:Git conflict
ours|theirs|both|base|none asks which =======` is the real one via
vim.ui.select (a line-before/line-after preview per candidate) instead of
guessing where our side ends -- the parser itself still never guesses, only
the user does, with the buffer content in front of them. With exactly one
candidate the *base* marker itself is what is ambiguous instead (two or more
||||||| before it), which no separator choice can resolve -- that case still
refuses with a message; *.md conflict-marker-size=10 in .gitattributes
avoids either case for the next merge. diff3/zdiff3 are otherwise affected
only if the base section itself holds a =======-looking line (the
||||||| marker otherwise tells the sides apart, and git keeps conflicts
around an unchanged underline apart).

                                                        *gitsuite-dashboard*
:Git dashboard [dir] [--out=...] [--to=...] and `:Git dashboard update
[dir]` are the one multi-repo exception -- every other scope above
operates on the current buffer's repository, dashboard reads the git
status of every repository in dir/dashboard.base_dir ($REPOS_DIR by
default), or a configured dashboard.groups page. Row/marked-set/whole-
page push, pull and fetch (p/P/f/gp/gP/gf/gu), page
navigation (<C-l>/<C-h>), and per-page path add/remove (a/x) --
moved here from reposcope.nvim's former :Reposcope dashboard/update.
See docs/BINDINGS.md for the full key table, docs/configuration.md for
dashboard.*, and docs/scope.md for why this one scope is different.

5. CONFIGURATION *gitsuite-config*

  require("gitsuite").setup({
    features = { conflict = true, hunk = true, blame = true, diff = true,
      browse = true, branch = true, ui = true, status = true },
    commands = { git = "Git" },
    keymaps = { blame_full = "<leader>gb", ui_lazygit = "<leader>lg" },
    browse = { hosts = {} },
    dashboard = { base_dir = "", extra_paths = {}, groups = {} },
    progress_style = "auto",
  })
Set a keymaps.* entry to false to disable that default mapping without
disabling the underlying feature. dashboard has no features.dashboard
flag -- the scope is always registered, see |gitsuite-dashboard|. See
docs/configuration.md for every key explained individually.

6. ADAPTERS *gitsuite-adapters*

Each feature family resolves its own backend independently through
gitsuite.adapter (gitsigns, diffview, neogit, lazygit, native).
native needs nothing but git itself and is always available inside a git
repo; every other adapter is only available once its own plugin/binary is
present -- an unavailable adapter is never an error by itself, only the
family it would have served falling back further, or refusing with a clear
message when nothing is left to fall back to.

7. EVENTS *gitsuite-events*

gitsuite.nvim fires plain User autocmd events after certain actions so a
sister plugin can react without gitsuite knowing it exists (D-2: events, not
a direct require() from gitsuite into a consumer -- gitsuite.events is
the one place they are fired from). Subscribe the usual way:
  vim.api.nvim_create_autocmd("User", {
    pattern = "GitsuiteBranchSwitched",
    callback = function(event) vim.print(event.data) end,
  })
                                                       *GitsuiteBranchSwitched*
GitsuiteBranchSwitched  { dir, branch } -- after `gitsuite.features.branch
.switch() checks out a different branch. dir` is the repo root the checkout
ran in, branch the ref now checked out.

                                                    *GitsuiteConflictsResolved*
GitsuiteConflictsResolved  { bufnr } -- after `gitsuite.features.conflict
.choose()` resolves the *last* remaining conflict region in a buffer, not on
every choose() call -- only once the buffer has none left.

                                                        *GitsuiteStatusChanged*
GitsuiteStatusChanged  { dir } -- after a hunk stage (single hunk or whole
buffer) actually writes to the git index, fired from gitsigns' own
completion callback rather than merely after the (async) action was
requested. Not fired for a hunk reset: gitsigns' reset only rewrites the
buffer's in-memory lines, never the index or the file on disk.

8. STATUSLINE *gitsuite-statusline*

require("gitsuite.statusline").status(bufnr?) returns an ambient
merge-conflict indicator for the current (or given) buffer, e.g. "MERGE 2"
-- "" when the buffer has no conflicts, features.conflict is off, or
bufnr is invalid. Cached per buffer by nvim_buf_get_changedtick, safe to
call unconditionally on every statusline redraw -- no process runs in the
render path. lualine_component is status under another name, for
sections = { lualine_x = { require("gitsuite.statusline").lualine_component } }.
ui.nvim ships a ready-made adapter, ui.statusline.modules.gitsuite_conflict
(add gitsuite_conflict to your order). See docs/statusline.md for the
full wiring (heirline, the native statusline) and why the cache is keyed by
changedtick rather than |GitsuiteConflictsResolved|.

9. HEALTH CHECK *gitsuite-health*

:checkhealth gitsuite reports:
  - lib.nvim / diff.nvim presence (hard dependencies -- error if missing)
  - git on $PATH
  - each adapter's availability (info, not warn/error -- see |gitsuite-adapters|)
  - rejected setup() options, if any
  - the composer's own route-tree check for :Git

keys

j / k
next / previous line
gg / G
first / last line
⏎
open the line under the cursor
/
search the plugins
:
command line — Tab completes
:help x
vimdoc of a plugin (:e x = plugin page)
:ls · :log · :stack
plugin list · activity stream · dependency graph
:colo x
colorscheme
:set skin=
modern | tui
?
this help
esc
close