Home

Awesome

<!-- LTeX: enabled=false -->

nvim-tinygit

<!-- LTeX: enabled=true --> <a href="https://dotfyle.com/plugins/chrisgrieser/nvim-tinygit"> <img src="https://dotfyle.com/plugins/chrisgrieser/nvim-tinygit/shield?style=flat" /> </a>

A lightweight bundle of commands focussed on swift and streamlined git operations.

<img alt="Showcase interactive staging" width=70% src="https://github.com/chrisgrieser/nvim-tinygit/assets/73286100/3c055861-6b93-4065-8601-f79568d8ac28"> <img alt="Showcase smart commit" width=70% src="https://github.com/chrisgrieser/nvim-tinygit/assets/73286100/7000ca1e-199b-4632-802b-fe630589f8f5"> <img alt="Showcase git history" width=70% src="https://github.com/chrisgrieser/nvim-tinygit/assets/73286100/b4cb918e-ff95-40ac-a09f-feb767ba2b94">

Feature Overview

<!-- toc --> <!-- tocstop -->

Installation

Hard Requirements

Optional/Recommended Requirements

-- lazy.nvim
{
	"chrisgrieser/nvim-tinygit",
	dependencies = {
		"stevearc/dressing.nvim",
		"nvim-telescope/telescope.nvim", -- optional, but recommended
		"rcarriga/nvim-notify", -- optional, but recommended
	},
},

-- packer
use {
	"chrisgrieser/nvim-tinygit",
	requires = {
		"stevearc/dressing.nvim", 
		"nvim-telescope/telescope.nvim", -- optional, but recommended
		"rcarriga/nvim-notify", -- optional, but recommended
	},
}

Commands

Interactive Staging

require("tinygit").interactiveStaging()

Smart-Commit

-- values shown are the defaults
require("tinygit").smartCommit { pushIfClean = false, pullBeforePush = true }

Example Workflow Assuming these keybindings:

vim.keymap.set("n", "ga", "<cmd>Gitsigns add_hunk<CR>") -- gitsigns.nvim
vim.keymap.set("n", "gc", function() require("tinygit").smartCommit() end)
vim.keymap.set("n", "gp", function() require("tinygit").push() end)
  1. Stage some hunks (changes) via ga.
  2. Use gc to enter a commit message.
  3. Repeat 1 and 2.
  4. When done, gp to push the commits.

Using pushIfClean = true allows you to combine staging, committing, and pushing into a single step, when it is the last commit you intend to make.

Amend, Fixup, and Squash Commits

Amending

-- options default to `false`
require("tinygit").amendOnlyMsg { forcePushIfDiverged = false }
require("tinygit").amendNoEdit { forcePushIfDiverged = false }

Fixup and Squash

-- options show default values
require("tinygit").fixupCommit {
	selectFromLastXCommits = 15,
	squashInstead = false,
	autoRebase = false,
}

Undo Last Commit/Amend

require("tinygit").undoLastCommitOrAmend()

GitHub Interaction

-- state: all|closed|open (default: all)
-- type: all|issue|pr (default: all)
require("tinygit").issuesAndPrs { type = "all", state = "all" }

-- alternative: if the word under the cursor is of the form `#123`,
-- just open that issue/PR
require("tinygit").openIssueUnderCursor()
-- file|repo (default: file)
require("tinygit").githubUrl("file")

Push & PR

-- options default to `false`
require("tinygit").push {
	pullBefore = false,
	forceWithLease = false,
	createGitHubPr = false,
}
require("tinygit").createGitHubPr()

Explore the History of a File, Function, or Line ("git pickaxe")

Search the git history. Select from the matching commits to open a popup with a diffview of the changes.

Keymaps in the diff popup

require("tinygit").searchFileHistory()
require("tinygit").functionHistory()
require("tinygit").lineHistory()

Stash

Simple wrappers around git stash push and git stash pop.

require("tinygit").stashPush()
require("tinygit").stashPop()

Statusline Components

Git Blame

Shows the message and date (git blame) of the last commit that changed the current file (not line).

require("tinygit.statusline").blame()

[!TIP] Some status line plugins also allow you to put components into the tabline or winbar. If your status line is too crowded, you can add the blame-component to the one of those bars instead.

The component can be configured with the statusline.blame options in the plugin configuration.

Branch State

Shows whether the local branch is ahead or behind of its remote counterpart. (Note that this component does not run git fetch for performance reasons, so the information may not be up-to-date with remote changes.)

require("tinygit.statusline").branchState()

Configuration

The setup call is optional. These are the default settings:

-- default config
require("tinygit").setup({
	staging = { -- requires telescope
		contextSize = 1, -- larger values "merge" hunks
		stagedIndicator = "✜ ",
		keymaps = { -- insert & normal mode
			stagingToggle = "<Space>", -- stage/unstage hunk
			gotoHunk = "<CR>",
			resetHunk = "<C-r>",
		},
	},
	commitMsg = {
		commitPreview = true, -- requires nvim-notify
		spellcheck = false,
		keepAbortedMsgSecs = 300,
		inputFieldWidth = 72, -- `false` to use dressing.nvim config
		conventionalCommits = {
			enforce = false,
			-- stylua: ignore
			keywords = {
				"fix", "feat", "chore", "docs", "refactor", "build", "test",
				"perf", "style", "revert", "ci", "break", "improv",
			},
		},
		openReferencedIssue = false, -- if message has issue/PR, open in browser afterwards
		insertIssuesOnHash = {
			-- Experimental. Typing `#` will insert the most recent open issue.
			-- Requires nvim-notify.
			enabled = false,
			next = "<Tab>", -- insert & normal mode
			prev = "<S-Tab>",
			issuesToFetch = 20,
		},
	},
	push = {
		preventPushingFixupOrSquashCommits = true,
		confirmationSound = true, -- currently macOS only, PRs welcome
	},
	historySearch = {
		diffPopup = {
			width = 0.8, -- float, 0 to 1
			height = 0.8,
			border = "single",
		},
		autoUnshallowIfNeeded = false,
	},
	issueIcons = {
		openIssue = "🟢",
		closedIssue = "🟣",
		notPlannedIssue = "⚪",
		openPR = "🟩",
		mergedPR = "🟪",
		closedPR = "🟥",
	},
	statusline = {
		blame = {
			ignoreAuthors = {}, -- hide component if these authors (useful for bots)
			hideAuthorNames = {}, -- show component, but hide names (useful for your own name)
			maxMsgLen = 40,
			icon = "ﰖ ",
		},
		branchState = {
			icons = {
				ahead = "󰶣",
				behind = "󰶡",
				diverge = "󰃻",
			},
		},
	},
	backdrop = {
		enabled = true,
		blend = 50, -- 0-100
	},
})

The appearance of the commit preview and notifications is determined by nvim-notify. To change for example the width of the preview, use:

require("notify").setup {
	max_width = 60,
}
<!-- vale Google.FirstPerson = NO -->

About me

In my day job, I am a sociologist studying the social mechanisms underlying the digital economy. For my PhD project, I investigate the governance of the app economy and how software ecosystems manage the tension between innovation and compatibility. If you are interested in this subject, feel free to get in touch.

I also occasionally blog about vim: Nano Tips for Vim

<a href='https://ko-fi.com/Y8Y86SQ91' target='_blank'> <img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>