Skip to content

Rebasing a stack unnecessarily enumerates each untracked file #627

Open

Description

@allanlewis

gh stack rebase feels noticeably slower than manually rebasing each branch onto its predecessor in a large monorepo I work on. Working-tree cleanliness checks appear to account for part of the extra time, even when there are no changes to report.

Observed behavior

The cleanliness check runs git status --porcelain --untracked-files=all:

func (d *defaultOps) HasUncommittedChanges() (bool, error) {
out, err := d.run("status", "--porcelain", "--untracked-files=all")
if err != nil {
return false, err
}
return out != "", nil
}

In my checkout, this command consistently takes about 2.8 seconds. Rebase checks cleanliness during preflight and again when preparing branches, so the cost accumulates across a stack.

Measurements

I ran each of these commands three times in the same checkout, with short pauses between runs:

time git status --porcelain --untracked-files=all
time git status --porcelain --untracked-files=normal
Untracked mode Run 1 Run 2 Run 3 Mean
all 2.848 s 2.610 s 3.014 s 2.824 s
normal 0.236 s 0.243 s 0.240 s 0.240 s

The roughly 11.8× difference suggests that exhaustive untracked-file scanning contributes substantially to the cost of each check. These are timings of the status command, not an end-to-end rebase benchmark; I have not measured how much of the total rebase time is spent in these checks.

Expected behavior

Rebasing a stack in a large repository should avoid substantial repeated filesystem-scanning overhead while retaining the existing checks that protect local work.

Related: #579 reduced redundant Git and worktree lookups, but individual cleanliness checks can still be expensive.

Related draft PR

I have a candidate fix in allanlewis#1. It is hosted in my fork because I do not have permission to open an upstream PR in github/gh-stack. It targets my fork’s main, which matches upstream main.

AI assistance: Codex helped investigate the implementation, prepare and test the candidate fix, and draft this report. The timings above were measured by me.

Activity

  1. changed the title [-]Reduce rebase overhead by avoiding exhaustive untracked-file enumeration[/-] [+]Slow rebase in large monorepos: repeated cleanliness checks take several seconds[/+] on Nov 12, 2026
  2. changed the title [-]Slow rebase in large monorepos: repeated cleanliness checks take several seconds[/-] [+]`gh stack rebase` is slow in large monorepos[/+] on Nov 12, 2026
  3. changed the title [-]`gh stack rebase` is slow in large monorepos[/-] [+]Rebasing a stack unnecessarily enumerates each untracked file[/+] on Nov 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions