{"id":50639332,"url":"https://github.com/lararosekelley/git-stk","last_synced_at":"2026-06-15T00:02:07.601Z","repository":{"id":362814019,"uuid":"1260777754","full_name":"lararosekelley/git-stk","owner":"lararosekelley","description":"Git-native stacked branch workflow helper, with GitHub and GitLab integration","archived":false,"fork":false,"pushed_at":"2026-06-10T20:11:03.000Z","size":702,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T11:23:29.666Z","etag":null,"topics":["cargo","git","git-cli","repository-management","rust","stacked-branches"],"latest_commit_sha":null,"homepage":"https://larakelley.com/posts/git-stk","language":"Rust","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/lararosekelley.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T21:32:08.000Z","updated_at":"2026-06-10T20:11:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lararosekelley/git-stk","commit_stats":null,"previous_names":["lararosekelley/git-stack"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/lararosekelley/git-stk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lararosekelley%2Fgit-stk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lararosekelley%2Fgit-stk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lararosekelley%2Fgit-stk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lararosekelley%2Fgit-stk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lararosekelley","download_url":"https://codeload.github.com/lararosekelley/git-stk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lararosekelley%2Fgit-stk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34243053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cargo","git","git-cli","repository-management","rust","stacked-branches"],"created_at":"2026-06-07T07:00:57.551Z","updated_at":"2026-06-15T00:02:07.581Z","avatar_url":"https://github.com/lararosekelley.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://raw.githubusercontent.com/lararosekelley/git-stk/main/assets/logo.svg\"\n     width=\"48\" height=\"48\" alt=\"git-stk logo\" /\u003e\n\n# git-stk\n\n[![crates.io](https://img.shields.io/crates/v/git-stk?color=cc6699)](https://crates.io/crates/git-stk)\n\n\u003e Git-native stacked branch workflow helper with GitHub and GitLab review integration.\n\n---\n\n`git-stk` keeps stacks as ordinary Git branches. Stack parent metadata is stored locally in `.git/config` as\n`branch.\u003cname\u003e.stkParent`, and GitHub PR bases or GitLab MR target branches can be used to reconstruct that metadata.\n\n![Formatted and automatically managed PR descriptions](./assets/git-stk-pr-description.png)\n\n## Reporting issues\n\nPlanned work and known issues are tracked in\n[GitHub issues](https://github.com/lararosekelley/git-stk/issues).\n\nFeel free to report bugs, feedback, feature requests, or ask questions\nthere; just be polite 😉\n\n## Install\n\nInstall using the official install script (except for PowerShell), which downloads the pre-built binary:\n\n```sh\ncurl https://larakelley.com/sh/git-stk | bash\n```\n\nOr, with [Homebrew](https://brew.sh) on macOS:\n\n```sh\nbrew install lararosekelley/tap/git-stk\n```\n\nWith a Rust toolchain, `cargo install git-stk --locked` builds from source, or `cargo binstall git-stk`\nfetches the pre-built binary without compiling.\n\nOn native Windows, use the PowerShell installer instead:\n\n```powershell\npowershell -ExecutionPolicy Bypass -c \"irm https://github.com/lararosekelley/git-stk/releases/latest/download/git-stk-installer.ps1 | iex\"\n```\n\nThe shell command runs [`install.sh`](./install.sh) - a thin wrapper around the\n[`cargo-dist`](https://github.com/axodotdev/cargo-dist)-generated `git-stk-installer.sh`; PowerShell\nfetches the matching `git-stk-installer.ps1`. Every release attaches the pre-built binaries, both\ninstallers, and per-file `.sha256` checksums to\n[GitHub Releases](https://github.com/lararosekelley/git-stk/releases), so you can download and verify a\nbinary directly instead of piping to a shell:\n\n```sh\n# Linux x86_64, for example\nsha256sum -c git-stk-x86_64-unknown-linux-musl.tar.xz.sha256\n```\n\nThe Linux builds are static (musl), so they run anywhere - glibc, Alpine, or an older distro.\n\n**Prerequisites:** review commands drive the GitHub (`gh`) or GitLab (`glab`) CLI, so install the one you\nuse and sign in (`gh auth login` / `glab auth login`). git-stk needs git 2.38 or newer (for\n`rebase --update-refs`). The local stack commands work without either CLI.\n\nThen install the man page and wire up shell completions (idempotent; prompts before touching your shell rc):\n\n```sh\ngit stk setup [-y] [--refresh]\n```\n\nUpgrade an installer-managed copy with:\n\n```sh\ngit stk upgrade\n```\n\nTo remove git-stk, `git stk uninstall` reverses `setup` and the installer: it strips the completion line it\nadded to your shell rc, deletes the man page, and removes the config/receipt directory (`--dry-run` to\npreview, `-y` to skip the prompt). It prints how to remove the binary itself rather than deleting it - a\nrunning program can't reliably delete its own executable, and a `cargo install` / Homebrew copy should go\nthrough `cargo uninstall git-stk` or `brew uninstall git-stk`. Per-repo `stk.*` config and branch metadata\nare left untouched.\n\n## Quickstart\n\n```sh\ngit stk new feature/api       # stack a branch on the current one\n# ...commit work...\ngit stk new feature/web       # stack another on top of it\n# ...commit work...\ngit stk submit --stack        # open a PR/MR for each branch, in order\ngit stk merge --all           # land them bottom-up, in one command\n```\n\nNew to stacking? `git stk guide` runs the whole loop offline in a disposable sandbox - nothing real is\ntouched and no account is needed. The tours: `intro` (create a stack, submit, restack, land it),\n`conflicts` (resolve and continue an interrupted restack), `repair` (rebuild lost stack metadata),\n`absorb` (fold review fixes into the commits that introduced them), `adopt` (adopt a hand-made branch, or\nmove one to a new parent), and `undo` (reverse the last stack-rewriting command). `git config stk.provider\ndemo` turns any scratch repo into the same offline playground.\n\n## Shell Completions\n\n`git stk setup` configures these automatically. Completions are dynamic: the shell asks the binary for\ncandidates at completion time, so subcommands, flags, and even branch names complete (`git stk up \u003cTAB\u003e`\noffers only the current branch's stack children). The installed binary prints its own registration script,\nso completions stay in sync across upgrades:\n\n```sh\n# bash: add to ~/.bashrc (the guard keeps shell startup quiet if git-stk is removed)\ncommand -v git-stk \u003e/dev/null \u0026\u0026 source \u003c(git stk completions bash)\n\n# zsh: write to a directory on your fpath\ngit stk completions zsh \u003e \"${fpath[1]}/_git-stk\"\n```\n\n```powershell\n# PowerShell: add to $PROFILE (git stk setup does this for you on Windows)\nif (Get-Command git-stk -ErrorAction SilentlyContinue) { git stk completions powershell | Out-String | Invoke-Expression }\n```\n\n`git stk setup` detects bash, zsh, and fish from `$SHELL` (covering Git Bash and WSL), and falls back to\nPowerShell on native Windows by wiring `$PROFILE`. Elvish is also supported via `git stk completions\nelvish`. The bash and zsh output includes a wrapper so git's own completion can complete `git stk \u003cTAB\u003e`\nin addition to `git-stk \u003cTAB\u003e`. `-y`/`--yes` skips the shell-rc confirmation for non-interactive setup;\n`--refresh` only re-renders the man page and never touches your shell rc - it is what `upgrade` runs with\nthe freshly installed binary.\n\n## Install For Development\n\n```sh\njust install\njust check\ncargo install --path .\n```\n\nAfter installation, Git can use the binary as a sub-command:\n\n```sh\ngit stk list\n```\n\n## Commands\n\nGit's own narration (rebase progress, switch advice, push chatter) is captured and shown only when a\ngit command fails; pass `-v`/`--verbose` to any command to stream it through instead. Output is colored\nwhen the terminal supports it; pipes and [`NO_COLOR`](https://no-color.org/) turn it off. Every command\nthat takes `--dry-run` also accepts `-n` as a short alias.\n\nLocal stack metadata:\n\n```sh\ngit stk new \u003cbranch\u003e [--insert | --prepend] [--dry-run]\ngit stk parent [branch]\ngit stk children [branch]\ngit stk list [--all | --format \u003cmarkdown|plain\u003e]\ngit stk adopt [branch] [--parent \u003cparent\u003e] [--dry-run]   # defaults: current branch, trunk\ngit stk detach [branch]\ngit stk rename [branch] \u003cnew-name\u003e [--dry-run]\n```\n\n`new` normally stacks a fresh branch on top of where you stand. `--insert` splices it in _above_ the\ncurrent branch instead, moving the current branch's children onto it; `--prepend` splices it in _below_,\nmoving the current branch onto it. The new branch is empty and shares its base's tip, so descendants stay\ncorrectly based - commit to it, then `restack` to replay them. `--prepend` needs a clean worktree.\n\n`rename` is `git branch -m` plus stack upkeep: children pointing at the old name are retargeted. When an\nopen review still heads the old branch (platforms do not follow local renames), it records the rename so\nyour next `submit` opens a fresh review for the new name, then offers to close the stale one and delete its\nbranch - leaving no orphaned PR, and the stack overview in every review drops the superseded entry.\n\n`list` prints the stack leaf-first, like a pile sitting on its base, with the trunk labeled. Each branch\nalso shows, dimmed, its open review number (once submitted) and its diff size against its parent:\n\n```text\n    ◉ feature/b (#13, +42/-7)\n  ○ feature/a (#12, +9/-0)\n○ main (trunk)\n```\n\nThe size is computed locally (no provider call), so it shows even before you submit; an empty branch and\nthe trunk show none.\n\n`list --all` shows every stack at once instead of just the one you are on - the trunk once at the bottom,\neach stack's tree above it, and any rootless fragments as their own trees - for an overview when several\nstacks are in flight.\n\n`status` and `list` append `hint:` lines pointing at the next command when there is one: `restack` when a\nbranch is behind its parent, `submit` when a review base went stale, `sync` when a review in the stack\nmerged.\n\n`list --format markdown` prints a shareable summary instead - a status line and the PRs in merge order\nwith links and states, ready to paste into a tracking issue or PR comment:\n\n```markdown\n2 PRs, base `main`, 1 open / 1 merged\n\n1. [Bottom change (#9)](https://github.com/owner/repo/pull/9) - merged\n2. [Top change (#10)](https://github.com/owner/repo/pull/10) - open\n```\n\nFor anywhere that does not render pasted markdown links (Slack, say), `--format plain` emits plain text\nwith bare URLs (which chat apps auto-link) instead:\n\n```text\n2 PRs, base main, 1 open / 1 merged\n\n1. Bottom change (#9) - merged\n   https://github.com/owner/repo/pull/9\n2. Top change (#10) - open\n   https://github.com/owner/repo/pull/10\n```\n\nBranches without reviews degrade to plain names, so both work before submitting too.\n\nNavigation and re-stacking:\n\n```sh\ngit stk up [branch]   # towards the top of the stack (children; picker at forks)\ngit stk down          # towards the trunk (parent)\ngit stk top           # jump to the leaf of the stack\ngit stk bottom        # jump to the branch just above the trunk\ngit stk restack [--update-refs | --no-update-refs] [--push | --no-push] [--dry-run]\ngit stk run [--fail-fast] -- \u003ccommand\u003e   # run a command on each branch, bottom-up\ngit stk absorb [--dry-run] [--include-unstaged]\ngit stk continue\ngit stk abort\ngit stk undo\n```\n\n`run` checks out each branch bottom-up and runs the command (e.g. `git stk run -- cargo test`), printing a\nper-branch pass/fail summary and exiting non-zero if any branch failed - a quick way to confirm each PR is\nindependently green before submitting. `--fail-fast` stops at the first failure. It refuses a dirty\nworktree and returns you to the branch you started on.\n\n`absorb` takes review fixes scattered across the stack and folds each into the commit that introduced the\nlines it touches: stage the fixes (`git add`), then `git stk absorb` blames each hunk, amends it into its\nowning commit via a fixup + autosquash rebase, and carries every branch ref along. `--dry-run` prints the\nhunk -\u003e commit routing first; `--include-unstaged` (or `stk.absorbIncludeUnstaged`) also takes unstaged\ntracked edits. Hunks it cannot attribute - new lines, trunk-owned lines, lines spanning commits - are left\nin place and reported. Folding the fixes in is atomic - a conflict there rolls back untouched. Branches\nthat fork off below you are then restacked onto the rewritten commits; if one of those hits a conflict it\nstops in the usual resumable state (`git stk continue`/`abort`, or `git stk undo` to reverse the whole\nabsorb).\n\n`undo` reverses the last stack-rewriting command - `restack`, `sync`, `merge`, `cleanup`, `rename`,\n`absorb`, or `new --insert`/`--prepend` - restoring local branch tips and stack metadata (it even\nrecreates a branch `cleanup` deleted). It is local only: pushes and platform merges are not reverted.\nOne level deep, it refuses on a dirty worktree (it resets the current branch) or mid-conflict (finish\nwith `continue`/`abort` first).\n\nProvider-backed workflows:\n\n```sh\ngit stk provider\ngit stk config\ngit stk status [branch]\ngit stk review [branch]\ngit stk view [branch]\ngit stk sync [--dry-run] [--push | --no-push]\ngit stk merge [-y] [--auto | --all [--wait | --no-wait]] [--dry-run]\ngit stk repair [--dry-run | --from-remote]\ngit stk submit [branch] [--no-stack] [-d \u003cdesc\u003e] [--draft | --no-draft] [--ready] [--dry-run] [--push | --no-push]\ngit stk submit [--stack | --no-stack | --downstack] [-d \u003cdesc\u003e] [--draft | --no-draft] [--ready] [--rebuild-overview] [--dry-run] [--push | --no-push]\ngit stk cleanup [branch] [--dry-run] [--keep-branch]\n```\n\n`review` prints a branch's review (id, base, state, url); `view` opens it in your browser. Both work on\nmerged and closed reviews, and report clearly when none exists yet.\n\n`sync` is the merge-loop one-shot: it fetches the trunk (without leaving your branch), refreshes stack\nmetadata from open reviews, cleans up merged branches (retargeting children and deleting), moves you off\nany branch it deletes, restacks and pushes the remainder, and ends by printing the next PR to merge -\nor `stack complete` when the loop is done. After squash-merging a PR, `git stk sync` is the only command\nyou need.\n\n`cleanup` does the branch-deletion half on demand: it removes the local branches whose reviews have\nmerged (retargeting any children first). It deletes without a prompt - unlike `merge` - because it only\ntouches _merged_ branches, whose work is already in the trunk and whose ref the reflog still holds (and\n`git stk undo` recreates them); `--dry-run` previews and `--keep-branch` retains them.\n\n`merge` merges the review at the bottom of the stack via the provider CLI (strategy from\n`stk.mergeStrategy`; squash by default), confirming first unless `-y` is passed, then runs the full `sync`\nflow. Landing a stack becomes one `git stk merge` per PR - or just `git stk merge --all`, which repeats\nmerge-and-sync bottom-up until the stack is complete, with a single confirmation up front. With required\nchecks still running, `--auto` schedules the merge instead (GitHub `--auto`, GitLab auto-merge); a merge\nthat only got scheduled - on GitLab that is the default - skips the sync (and stops `--all`) with a note\nto rerun `git stk sync` once checks pass. `merge --all --wait` (or `git config stk.mergeWait true`) polls\neach review's checks until they settle before merging it - turning the landing into genuinely one command;\na failing check stops the loop, and `--no-wait` overrides the config. A freshly pushed branch whose checks\nare still queued (not yet registered) is waited out, not mistaken for \"no checks.\" The wait gives up after\n`stk.checkTimeout` (default 30m; `0` waits indefinitely) so a pipeline that never settles can't block the\nlanding forever, and ctrl-c is always safe (rerun to resume from the new bottom).\n\n`submit --stack` (and `merge --all`) operate on the stack containing the current branch - its line from\nthe bottom up through the current branch and out to its descendants - so it never matters where in that\nstack you are standing, and independent stacks that only share the trunk are left for their own submit.\nWith `git config stk.submitStack true`, bare `submit` does this by default; `--no-stack` or naming a branch\nsubmits a single branch. (`restack` still rebases the whole subtree on the trunk, since re-basing an\nalready-current sibling is a harmless no-op.)\n\n`submit --downstack` submits the stack from its bottom through the current branch only, so\nwork-in-progress branches above you stay local. `--draft` (or `git config stk.submitDraft true`) opens\nnew reviews as drafts; `--no-draft` overrides the config, and `submit --ready` flips the submitted\nbranches' existing drafts to ready for review.\n\n`submit --push` (or `git config stk.pushOnSubmit true`) pushes the submitted branches with\n`-u --force-with-lease` before creating or updating reviews, so new branches exist remotely and rebased\nones are updated safely.\n\n`submit --stack` also maintains a stack overview at the end of every PR/MR description: the full stack as\nlinked bullets (leaf-first, with a pointer on the PR being viewed) sitting on the trunk, plus a footer\ncrediting the tool. The overview is a ledger, not a snapshot: entries are styled by status (🟢 open,\n🟣 merged, 🔴 closed, the latter two struck through), and merged or closed PRs stay listed even after\ntheir local branches are gone. `sync` (and therefore `merge`) and `cleanup` refresh the overview\nmid-loop, so the remaining PRs never show stale state. The section lives between HTML comment markers and self-repairs on\nthe next update if the markup is hand-edited away.\n\nBecause the ledger is append-only, a row that drifted in - a PR superseded outside the rename flow, a\nhand-edited body, an abandoned branch - lingers. `submit --stack --rebuild-overview` regenerates each\noverview from scratch: the live stack plus genuinely merged history, dropping closed or orphaned rows.\nPair it with `--dry-run` to see which rows it would drop first. It is opt-in - the default submit keeps\npreserving history.\n\n`submit` also links issues from branch names: a branch like `123-fix-thing` or `fix/issue-123` gets a\n`Closes #123` line in its PR/MR description, so the platform closes the issue when the review merges. This\nauto-link is one issue per branch; to close several from one PR (or use `Fixes`, cross-repo references,\netc.), put the keywords in `--desc` (below) - the platform honors every closing keyword in the body.\n\nTracking work in **Linear** or **Jira** instead? You do not need anything from stk: both vendors ship a\nGitHub/GitLab app that auto-links any branch or review whose name carries a ticket key\n(`eng-123-fix-thing`, `PROJ-456-thing`) and recognizes magic words (`Closes ENG-123`) in review bodies.\nName your branches with the ticket key and the platform integration does the linking and closing; stk's\nown `Closes #N` step stays inert on those shapes, so the two never collide.\n\n`submit --desc \u003ctext\u003e` (or `-d`) writes a description block at the top of the review body, above the\nmanaged sections, for the current or named branch only. It sticks across resubmits until changed;\n`--desc \"\"` removes it.\n\nUpgrading:\n\n```sh\ngit stk upgrade              # upgrade to the latest release\ngit stk upgrade --force      # reinstall the latest release even if up to date\ngit stk upgrade --head [-y]  # build and install the latest unreleased commit\n```\n\n`upgrade` is driven by the install receipt the shell installer writes to `~/.config/git-stk/`\n(`%LOCALAPPDATA%\\git-stk` on Windows): it records the installed version and where the binary lives, so\n`upgrade` knows what to replace. Copies installed with `cargo install` have no receipt and should upgrade\nthrough cargo instead.\n\n`--head` requires a Rust tool-chain, prompts before installing a pre-release build, and intentionally\nleaves the receipt's version stale - the HEAD build did not come from a release, so the receipt keeps\npointing at the last one. `git stk upgrade --force` is the way back onto releases afterwards.\n\nOnce a day, the everyday workflow commands (`list`, `status`, `sync`, `submit`, `merge`, `restack`,\n`cleanup`) check for a newer release after their work is done - capped at five seconds, silent on any\nfailure or when stderr is not a terminal - and print a one-line nudge when behind. The check stamps\n`update-check` next to the receipt; `git config stk.noUpdateCheck true` turns it off.\n\n`git stk credits` lists the stacked-workflow tools that inspired git-stk, with a link to each.\n\n## Configuration\n\nAll settings live under `[stk]` in git config, so the tool's footprint stays separated from git's own.\nEverything is optional; defaults shown below:\n\n```ini\n[stk]\n    ; Review provider: github, gitlab, or demo (offline playground).\n    ; Default: auto-detect from the remote URL.\n    provider = github\n    ; Self-hosted GitLab host to detect as GitLab alongside gitlab.com (a bare\n    ; host or a full URL). `glab` picks up the host from the remote itself.\n    ; Default: gitlab.com only.\n    gitlabHost = gitlab.example.com\n    ; Remote used for provider detection and pushes. Default: origin.\n    remote = origin\n    ; Pass --update-refs to git rebase during restack. Default: false.\n    updateRefs = true\n    ; Force-push (with lease) rebased branches after restack (also the restack\n    ; step inside sync and merge). Default: false.\n    pushOnRestack = true\n    ; Push branches (-u --force-with-lease) before submitting reviews. Default: false.\n    pushOnSubmit = true\n    ; Bare `submit` submits the whole stack instead of one branch. Default: false.\n    submitStack = true\n    ; Strategy for `merge`: squash, rebase, or merge. Default: squash.\n    mergeStrategy = squash\n    ; `merge --all` waits for each review's checks before merging it. Default: false.\n    mergeWait = true\n    ; Seconds `merge --wait` polls a review's checks before giving up. 0 waits\n    ; indefinitely. Default: 1800 (30m).\n    checkTimeout = 1800\n    ; Open new reviews as drafts. Default: false.\n    submitDraft = true\n    ; `absorb` also folds unstaged tracked edits, not just staged ones. Default: false.\n    absorbIncludeUnstaged = true\n    ; Skip the once-a-day check for a newer release. Default: false.\n    noUpdateCheck = true\n```\n\nThe tool also manages per-branch metadata: `branch.\u003cname\u003e.stkParent` (the stack parent) and\n`branch.\u003cname\u003e.stkBase` (the recorded fork point). These are written by `new`, `adopt`, `rename`, `sync`, `restack`,\n`cleanup`, and `repair`; you normally never touch them by hand.\n\nBranches are the real state; the metadata is just annotation. If it is ever lost or stale, `git stk repair`\nrebuilds it from review bases (when `gh`/`glab` is available) and branch ancestry, and verifies recorded\nfork points. Anything it cannot resolve safely is reported for a manual `git stk adopt`.\n\nWorking across machines? The parent map rides along on a shared ref (`refs/stk/metadata`), published\nautomatically whenever git-stk pushes branches (`submit`/`restack`/`sync` with push). On another clone,\n`git stk repair --from-remote` fetches that ref, pulls down any of its branches you do not have yet, and\nrebuilds the local metadata - no platform or open PRs required. (Local-only commits you have not pushed\nstill can't transfer, of course.)\n\nWhile a stack-rewriting command runs (`submit`, `merge`, `sync`, `restack`, `absorb`, and friends) it holds\na lock at `.git/stk-lock` so a second git-stk run cannot rewrite the stack at the same time; read-only\ncommands are never blocked. If a run is killed mid-operation the lock can linger, but the next\nstack-rewriting command reclaims it automatically once it sees the holding process is gone (on Windows,\nremove `.git/stk-lock` by hand).\n\nInspect everything stk reads or wrote with:\n\n```sh\ngit stk config\n```\n\n## Providers\n\nProvider detection uses `stk.provider` first, then `stk.remote`, then `origin`. GitHub support shells out\nto `gh`. GitLab support shells out to `glab`. Authenticate those CLIs before using provider commands.\n\n## Re-stacking\n\n`restack` follows the `stk.updateRefs` config (default false). Use `--update-refs` or `--no-update-refs` to\noverride that for one run. If a rebase conflicts, `git-stk` records state in `.git/stack-state`; resolve\nconflicts and run `git stk continue`, or run `git stk abort`.\n\n`git-stk` records each branch's fork point in `.gitconfig` as `branch.\u003cname\u003e.stkBase` and rebases with\n`--onto`, so only a branch's own commits are replayed. This makes restacking safe after a parent is\nsquash-merged, rebase-merged, or amended. A missing or stale fork point falls back to a plain rebase.\n\nAfter a restack, every rebased branch's remote counterpart is stale. Pass `--push` (or set\n`git config stk.pushOnRestack true`) to force-push (with lease) all rebased branches automatically,\nincluding after a conflicted restack finishes via `git stk continue`. Without it, `restack` prints the\nexact push command instead. `--no-push` overrides the config for one run; `stk.remote` picks the remote\n(default `origin`).\n\n## Generated Assets\n\nShell completions and a `man` page can be generated with:\n\n```sh\njust generate-assets\n```\n\nGenerated files are written under `target/generated`.\n\n## Project Tasks\n\n```sh\njust build\njust test\njust lint\njust check\n```\n\n## License\n\nCopyright (c) 2026 [Lara Kelley](https://larakelley.com). MIT License. See [LICENSE](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flararosekelley%2Fgit-stk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flararosekelley%2Fgit-stk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flararosekelley%2Fgit-stk/lists"}