{"id":13412735,"url":"https://github.com/chrisgrieser/nvim-tinygit","last_synced_at":"2025-04-04T18:04:53.141Z","repository":{"id":195975619,"uuid":"694071686","full_name":"chrisgrieser/nvim-tinygit","owner":"chrisgrieser","description":"A lightweight bundle of commands focussed on swift and streamlined git operations.","archived":false,"fork":false,"pushed_at":"2025-03-31T14:23:25.000Z","size":680,"stargazers_count":180,"open_issues_count":1,"forks_count":6,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-04T16:36:13.583Z","etag":null,"topics":["commit-message","conventional-commits","git-client","nvim-plugin"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisgrieser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://www.paypal.me/ChrisGrieser","ko_fi":"pseudometa"}},"created_at":"2023-09-20T09:19:39.000Z","updated_at":"2025-03-31T14:23:28.000Z","dependencies_parsed_at":"2024-03-02T14:05:35.354Z","dependency_job_id":"cb0b5556-b7da-479a-a0d1-435d7968b855","html_url":"https://github.com/chrisgrieser/nvim-tinygit","commit_stats":{"total_commits":675,"total_committers":5,"mean_commits":135.0,"dds":"0.013333333333333308","last_synced_commit":"0cfbe666572e13524e0fc5341a6d587488003ab0"},"previous_names":["chrisgrieser/nvim-tinygit"],"tags_count":1,"template":false,"template_full_name":"chrisgrieser/nvim-pseudometa-plugin-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-tinygit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-tinygit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-tinygit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-tinygit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisgrieser","download_url":"https://codeload.github.com/chrisgrieser/nvim-tinygit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226213,"owners_count":20904465,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commit-message","conventional-commits","git-client","nvim-plugin"],"created_at":"2024-07-30T20:01:28.517Z","updated_at":"2025-04-04T18:04:53.111Z","avatar_url":"https://github.com/chrisgrieser.png","language":"Lua","readme":"\u003c!-- LTeX: enabled=false --\u003e\n# nvim-tinygit\n\u003c!-- LTeX: enabled=true --\u003e\n\u003ca href=\"https://dotfyle.com/plugins/chrisgrieser/nvim-tinygit\"\u003e\n\u003cimg alt=\"badge\" src=\"https://dotfyle.com/plugins/chrisgrieser/nvim-tinygit/shield?style=flat\"/\u003e\u003c/a\u003e\n\nBundle of commands focused on swift and streamlined git operations.\n\n## Breaking changes in v1.0\n- `dressing.nvim` and `nvim-notify` are **no longer dependencies**.\n- `telescope.nvim` is now a **required dependency**.\n- The `commit.insertIssuesOnHashSign` feature has been removed. Better issue\n  insertion via plugins like [cmp-git](https://github.com/petertriho/cmp-git) or\n  [blink-cmp-git](https://github.com/Kaiser-Yang/blink-cmp-git) now work there.\n- `smartCommit` was overhauled. Among other improvements, it now supports a\n  commit body.\n\n\u003e [!NOTE]\n\u003e If you want to keep using the previous version, without these breaking\n\u003e changes, you can pin the tag `v0.9`:\n\u003e\n\u003e ```lua\n\u003e -- lazy.nvim\n\u003e {\n\u003e \t\"chrisgrieser/nvim-tinygit\",\n\u003e \ttag = \"v0.9\"\n\u003e \tdependencies = \"stevearc/dressing.nvim\",\n\u003e },\n\u003e ```\n\n## Feature overview\n\n\u003ctable\u003e\n\t\u003ctr\u003e\n\t\t\u003cth\u003eInteractive staging\u003c/th\u003e\n\t\t\u003cth\u003eSmart commit\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e\u003cimg alt=\"interactive staging\" src=\"https://github.com/user-attachments/assets/93812b73-7a0d-4496-b101-8551c41ee393\"\u003e\u003c/td\u003e\n\t\t\u003ctd\u003e\u003cimg alt=\"smart commit\" src=\"https://github.com/user-attachments/assets/8dfdaa83-2f5b-49ee-a4a7-a72ae07f5941\"\u003e\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003cth\u003eFile history\u003c/th\u003e\n\t\t\u003cth\u003e\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e\u003cimg alt=\"file history\" src=\"https://github.com/chrisgrieser/nvim-tinygit/assets/73286100/b4cb918e-ff95-40ac-a09f-feb767ba2b94\"\u003e\u003c/td\u003e\n\t\t\u003ctd\u003e\u003c/td\u003e\n\t\u003c/tr\u003e\n \u003c/table\u003e\n\n- **Interactive staging** of hunks (parts of a file). Displays hunk diffs with\n  syntax highlighting, and allows resetting or navigating to the hunk.\n- **Smart-commit**: Open a popup to enter a commit message with syntax highlighting,\n  commit preview, and commit title length indicators. If there are no staged\n  changes, stages all changes before doing so (`git add -A`). Optionally trigger\n  a `git push` afterward.\n- Convenient commands for **amend, stash, fixup, or undoing** commits.\n- Search **issues \u0026 PRs**. Open the selected issue or PR in the browser.\n- Open the **GitHub URL** of the current file, repo, or selected lines. Also\n  supports opening GitHub's blame view.\n- **Explore file history**: Search the git history of a file for a string (\"git\n  pickaxe\"), or examine the history of a function or line range. Displays the\n  results in a diff view with syntax highlighting, correctly following file\n  renamings.\n- **Status line components:** `git blame` of a file and branch state.\n- **Streamlined workflow:** operations are smartly combined to minimize\n  friction. For instance, the smart-commit command combines staging, committing,\n  and pushing, and searching the file history combines unshallowing, searching,\n  and diff navigation.\n\n## Table of contents\n\n\u003c!-- toc --\u003e\n\n- [Installation](#installation)\n- [Configuration](#configuration)\n- [Commands](#commands)\n\t* [Interactive staging](#interactive-staging)\n\t* [Smart commit](#smart-commit)\n\t* [Amend and fixup commits](#amend-and-fixup-commits)\n\t* [Undo last commit/amend](#undo-last-commitamend)\n\t* [GitHub interaction](#github-interaction)\n\t* [Push \u0026 PRs](#push--prs)\n\t* [File history](#file-history)\n\t* [Stash](#stash)\n- [Status line components](#status-line-components)\n\t* [git blame](#git-blame)\n\t* [Branch state](#branch-state)\n- [Credits](#credits)\n\n\u003c!-- tocstop --\u003e\n\n## Installation\n**Requirements**\n- nvim 0.10+\n- [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)\n- `curl` for GitHub-related features\n- *optional*: Treesitter parser for syntax highlighting: `TSInstall gitcommit`\n\n```lua\n-- lazy.nvim (automatically takes care of dependencies)\n{ \"chrisgrieser/nvim-tinygit\" },\n\n-- packer\nuse {\n\t\"chrisgrieser/nvim-tinygit\",\n\trequires = \"nvim-telescope/telescope.nvim\",\n}\n```\n\n## Configuration\nThe `setup` call is optional.\n\n```lua\n-- default config\nrequire(\"tinygit\").setup {\n\tstage = { -- requires `telescope.nvim`\n\t\tcontextSize = 1, -- larger values \"merge\" hunks. 0 is not supported.\n\t\tstagedIndicator = \"󰐖\",\n\t\tkeymaps = { -- insert \u0026 normal mode\n\t\t\tstagingToggle = \"\u003cSpace\u003e\", -- stage/unstage hunk\n\t\t\tgotoHunk = \"\u003cCR\u003e\",\n\t\t\tresetHunk = \"\u003cC-r\u003e\",\n\t\t},\n\t\tmoveToNextHunkOnStagingToggle = false,\n\n\t\t-- accepts the common telescope picker config\n\t\ttelescopeOpts = { \n\t\t\tlayout_strategy = \"horizontal\",\n\t\t\tlayout_config = {\n\t\t\t\thorizontal = {\n\t\t\t\t\tpreview_width = 0.65,\n\t\t\t\t\theight = { 0.7, min = 20 },\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tcommit = {\n\t\tkeepAbortedMsgSecs = 300,\n\t\tborder = getBorder(), -- `vim.o.winborder` on nvim 0.11, otherwise \"rounded\"\n\t\tspellcheck = false, -- vim's builtin spellcheck\n\t\twrap = \"hard\", ---@type \"hard\"|\"soft\"|\"none\"\n\t\tkeymaps = {\n\t\t\tnormal = { abort = \"q\", confirm = \"\u003cCR\u003e\" },\n\t\t\tinsert = { confirm = \"\u003cC-CR\u003e\" },\n\t\t},\n\t\tsubject = {\n\t\t\t-- automatically apply formatting to the subject line\n\t\t\tautoFormat = function(subject) ---@type nil|fun(subject: string): string\n\t\t\t\tsubject = subject:gsub(\"%.$\", \"\") -- remove trailing dot https://commitlint.js.org/reference/rules.html#body-full-stop\n\t\t\t\treturn subject\n\t\t\tend,\n\n\t\t\t-- disallow commits that do not use an allowed type\n\t\t\tenforceType = false,\n\t\t\t-- stylua: ignore\n\t\t\ttypes = {\n\t\t\t\t\"fix\", \"feat\", \"chore\", \"docs\", \"refactor\", \"build\", \"test\",\n\t\t\t\t\"perf\", \"style\", \"revert\", \"ci\", \"break\",\n\t\t\t},\n\t\t},\n\t\tbody = {\n\t\t\tenforce = false,\n\t\t},\n\t},\n\tpush = {\n\t\tpreventPushingFixupCommits = true,\n\t\tconfirmationSound = true, -- currently macOS only, PRs welcome\n\n\t\t-- If pushed commits contain references to issues, open them in the browser\n\t\t-- (not used when using force-push).\n\t\topenReferencedIssues = false,\n\t},\n\tgithub = {\n\t\ticons = {\n\t\t\topenIssue = \"🟢\",\n\t\t\tclosedIssue = \"🟣\",\n\t\t\tnotPlannedIssue = \"⚪\",\n\t\t\topenPR = \"🟩\",\n\t\t\tmergedPR = \"🟪\",\n\t\t\tdraftPR = \"⬜\",\n\t\t\tclosedPR = \"🟥\",\n\t\t},\n\t},\n\thistory = {\n\t\tdiffPopup = {\n\t\t\twidth = 0.8, -- between 0-1\n\t\t\theight = 0.8,\n\t\t\tborder = getBorder(), -- `vim.o.winborder` on nvim 0.11, otherwise \"rounded\"\n\t\t},\n\t\tautoUnshallowIfNeeded = false,\n\t},\n\tappearance = {\n\t\tmainIcon = \"󰊢\",\n\t\tbackdrop = {\n\t\t\tenabled = true,\n\t\t\tblend = 40, -- 0-100\n\t\t},\n\t},\n\tstatusline = {\n\t\tblame = {\n\t\t\tignoreAuthors = {}, -- hide component if from these authors (useful for bots)\n\t\t\thideAuthorNames = {}, -- show component, but hide names (useful for your own name)\n\t\t\tmaxMsgLen = 40,\n\t\t\ticon = \"ﰖ\",\n\t\t},\n\t\tbranchState = {\n\t\t\ticons = {\n\t\t\t\tahead = \"󰶣\",\n\t\t\t\tbehind = \"󰶡\",\n\t\t\t\tdiverge = \"󰃻\",\n\t\t\t},\n\t\t},\n\t},\n}\n```\n\n## Commands\nAll commands are available via lua function or sub-command of `:Tinygit`, for\nexample `require(\"tinygit\").interactiveStaging()` and `:Tinygit\ninteractiveStaging`. However, do note that the lua function is preferable,\nsince the `:Tinygit` does not accept command-specific options and does not\ntrigger visual-mode specific changes to the commands.\n\n### Interactive staging\n- This command stages hunks, that is, *parts* of a file instead of the\n  full file. It is roughly comparable to `git add -p`.\n- Use `\u003cSpace\u003e` to (un)stage the hunk, `\u003cCR\u003e` to go to the hunk, or `\u003cC-r` to\n  reset the hunk (mappings customizable). Your regular `telescope` mappings also\n  apply.\n- The size of the hunks is determined by the setting `staging.contextSize`.\n  Larger context size is going to \"merge\" changes that are close to one another\n  into one hunk. (As such, the hunks displayed are not 1:1 the same as the hunks\n  from `gitsigns.nvim`.) A context size between 1 and 4 is recommended.\n- Limitations: `contextSize=0` (= no merging at all) is not supported.\n\n```lua\nrequire(\"tinygit\").interactiveStaging()\n```\n\n### Smart commit\n- Open a commit popup, alongside a preview of what is going to be committed. If\n  there are no staged changes, stage all changes (`git add --all`) before the\n  commit. Optionally run `git push` if the repo is clean after committing.\n- The window title of the input field displays what actions are going to be\n  performed. You can see at glance whether all changes are going to be\n  committed, or whether there a `git push` is triggered afterward, so there are\n  no surprises.\n- Input field contents of aborted commits are briefly kept, if you just want to\n  fix a detail.\n- The first line is used as commit subject, the rest is as commit body.\n\n```lua\n-- values shown are the defaults\nrequire(\"tinygit\").smartCommit { pushIfClean = false, pullBeforePush = true }\n```\n\n**Example workflow**  \nAssuming these keybindings:\n\n```lua\nvim.keymap.set(\"n\", \"\u003cleader\u003ega\", function() require(\"tinygit\").interactiveStaging() end, { desc = \"git add\" })\nvim.keymap.set(\"n\", \"\u003cleader\u003egc\", function() require(\"tinygit\").smartCommit() end, { desc = \"git commit\" })\nvim.keymap.set(\"n\", \"\u003cleader\u003egp\", function() require(\"tinygit\").push() end, { desc = \"git push\" })\n```\n\n1. Stage some changes via `\u003cleader\u003ega`.\n2. Use `\u003cleader\u003egc` to enter a commit message.\n3. Repeat 1 and 2.\n4. When done, `\u003cleader\u003egp` to push the commits.\n\nUsing `pushIfClean = true` allows you to combine staging, committing, and\npushing into a single step, when it is the last commit you intend to make.\n\n### Amend and fixup commits\n**Amending**\n- `amendOnlyMsg` just opens the commit popup to change the last commit message,\n  and does not stage any changes.\n- `amendNoEdit` keeps the last commit message; if there are no staged changes,\n  stages all changes (`git add --all`), like `smartCommit`.\n- Optionally runs `git push --force-with-lease` afterward, if the branch has\n  diverged (that is, the amended commit was already pushed).\n\n```lua\n-- values shown are the defaults\nrequire(\"tinygit\").amendOnlyMsg { forcePushIfDiverged = false }\nrequire(\"tinygit\").amendNoEdit { forcePushIfDiverged = false, stageAllIfNothingStaged = true }\n```\n\n**Fixup commits**\n- `fixupCommit` lets you select a commit from the last X commits and runs `git\n  commit --fixup` on the selected commit.\n- If there are no staged changes, stages all changes (`git add --all`), like\n  `smartCommit`.\n- `autoRebase = true` automatically runs rebase with `--autosquash` and\n`--autostash` afterward, confirming all fixups and squashes **without opening a\nrebase to do editor**. Note that this can potentially result in conflicts.\n\n```lua\n-- values shown are the defaults\nrequire(\"tinygit\").fixupCommit {\n\tselectFromLastXCommits = 15,\n\tautoRebase = false,\n}\n```\n\n### Undo last commit/amend\n\n```lua\nrequire(\"tinygit\").undoLastCommitOrAmend()\n```\n\n- Changes in the working directory are kept, but unstaged. (In the background,\n  this uses `git reset --mixed`.)\n- If there was a `push` operation done as a followup (such as `.smartCommit {\n  pushIfClean = false }`), the last commit is not undone.\n\n### GitHub interaction\n**Search issues \u0026 PRs**  \n- Requires `curl`.\n\n```lua\n-- state: all|closed|open (default: all)\n-- type: all|issue|pr (default: all)\nrequire(\"tinygit\").issuesAndPrs { type = \"all\", state = \"all\" }\n\n-- alternative: if the word under the cursor is of the form `#123`,\n-- open that issue/PR\nrequire(\"tinygit\").openIssueUnderCursor()\n```\n\n**GitHub URL**  \nCreates a permalink to the current file/lines at GitHub. The link is opened in\nthe browser and copied to the system clipboard. In normal mode, uses the current\nfile, in visual mode, uses the selected lines. (Note that visual mode detection\nrequires you to use the lua function below instead of the `:Tinygit` ex-command.)\n- `\"file\"`: code view\n- `\"blame\"`: blame view\n- `\"repo\"`: repo root\n\n```lua\n-- file|repo|blame (default: file)\nrequire(\"tinygit\").githubUrl(\"file\")\n```\n\n### Push \u0026 PRs\n- `push` can be combined with other actions, depending on the options.\n- `createGitHubPr` opens a PR from the current branch browser. (This requires the\n  repo to be a fork with sufficient information on the remote.)\n\n```lua\n-- values shown are the defaults\nrequire(\"tinygit\").push {\n\tpullBefore = false,\n\tforceWithLease = false,\n\tcreateGitHubPr = false,\n}\nrequire(\"tinygit\").createGitHubPr()\n```\n\n### File history\nSearch the git history of the current file. Select from the matching commits to\nopen a popup with a diffview of the changes.\n\nIf the config `history.autoUnshallowIfNeeded` is set to `true`, will also\nautomatically un-shallow the repo if needed.\n\n```lua\nrequire(\"tinygit\").fileHistory()\n```\n\nThe type of history search depends on the mode `.fileHistory` is called from:\n- **Normal mode**: search file history for a string (`git log -G`)\n\t* Correctly follows file renamings, and displays past filenames in the\n\t  commit selection.\n\t* The search input is case-insensitive and supports regex.\n\t* Leave the input field empty to display *all* commits that changed the\n\t  current file.\n- **Visual mode**: function history (`git log -L`).\n\t* The selected text is assumed to be the name of the function whose history\n\t  you want to explore.\n\t* Note that [`git` uses heuristics to determine the enclosing function of\n\t  a change](https://news.ycombinator.com/item?id=38153309), so this is not\n\t  100% perfect and has varying reliability across languages.\n\t* Caveat: for function history, git does not support to follow renamings of\n\t  the file or function name.\n- **Visual line mode**: line range history (`git log -L`).\n\t* Uses the selected lines as the line range.\n\t* Caveat: for line history, git does not support to follow file renamings.\n\nNote that visual mode detection requires you to use the lua function above\ninstead of the `:Tinygit` ex-command.\n\n### Stash\nSimple wrappers around `git stash push` and `git stash pop`.\n\n```lua\nrequire(\"tinygit\").stashPush()\nrequire(\"tinygit\").stashPop()\n```\n\n## Status line components\n\n\u003c!-- LTeX: enabled=false --\u003e\n### git blame\n\u003c!-- LTeX: enabled=true --\u003e\nShows the message and date (`git blame`) of the last commit that changed the\ncurrent *file* (not line).\n\n```lua\nrequire(\"tinygit.statusline\").blame()\n```\n\n\u003e [!TIP]\n\u003e Some status line plugins also allow you to put components into the tab line or\n\u003e win bar. If your status line is too crowded, you can add the blame-component\n\u003e to one of those bars instead.\n\nThe component can be configured with the `statusline.blame` options in the [plugin\nconfiguration](#configuration).\n\n### Branch state\nShows whether the local branch is ahead or behind of its remote counterpart.\n(Note that this component does not run `git fetch` for performance reasons, so\nthe component may not be up-to-date with remote changes.)\n\n```lua\nrequire(\"tinygit.statusline\").branchState()\n```\n\n## Credits\nIn my day job, I am a sociologist studying the social mechanisms underlying the\ndigital economy. For my PhD project, I investigate the governance of the app\neconomy and how software ecosystems manage the tension between innovation and\ncompatibility. If you are interested in this subject, feel free to get in touch.\n\nI also occasionally blog about vim: [Nano Tips for Vim](https://nanotipsforvim.prose.sh)\n\n- [Website](https://chris-grieser.de/)\n- [Mastodon](https://pkm.social/@pseudometa)\n- [ResearchGate](https://www.researchgate.net/profile/Christopher-Grieser)\n- [LinkedIn](https://www.linkedin.com/in/christopher-grieser-ba693b17a/)\n\n\u003ca href='https://ko-fi.com/Y8Y86SQ91' target='_blank'\u003e \u003cimg height='36'\nstyle='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3'\nborder='0' alt='Buy Me a Coffee at ko-fi.com' /\u003e\u003c/a\u003e\n","funding_links":["https://www.paypal.me/ChrisGrieser","https://ko-fi.com/pseudometa","https://ko-fi.com/Y8Y86SQ91'"],"categories":["Git","Lua"],"sub_categories":["Quickfix"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisgrieser%2Fnvim-tinygit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisgrieser%2Fnvim-tinygit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisgrieser%2Fnvim-tinygit/lists"}