Every `git commit` forks `git maintenance run --auto --quiet --detach`,
and git 2.54 changed what that runs from the `gc` task to the
"geometric" strategy. The geometric repack's auto condition passes its
threshold of 100 to too_many_loose_objects(), which estimates the loose
object count from the objects/17 fanout directory times 256, so the real
trigger is two objects in that one directory -- where the old gc task
needed 27. Fixture repos reach two easily: every CreateNCommits(n>=6)
repo already stores the blob for file06.txt there, so a single commit
object hashing into 17 (about 4% of fixtures with 10 commits, 15% with
40) tips it over, and from then on every commit in that repo forks a
detached `git repack -d`, which prunes loose objects while the next
fixture command -- or lazygit under test -- is still working in the same
repo.
That is where the CI panics during fixture setup come from:
panic: error running command: [git commit -m commit-10]
error: invalid object 100644 50d5612... for 'file09.txt'
error: Error building trees
The reported hashes are exactly the fixture blobs, so `git add` staged
them correctly; they were unlinked underneath the commit. Only the
"git latest" jobs saw this, since the pinned 2.32/2.38/2.44 jobs predate
the strategy change.
git's own test suite guards against the same thing by exporting
GIT_TEST_MAINT_AUTO_DETACH=false ("Ensure that tests cannot race with
background maintenance by default"). Turning maintenance off outright is
stronger: no test repo needs it, and it also spares us a forked git
process per commit. maintenance.auto has been honored since git 2.29, so
it covers every version in the CI matrix.
Measured on a 40-commit fixture: a background repack fired in 4 of 25
runs before, 0 of 25 after.
Add a 2-second background poll that calls Status.RefsSnapshot and
compares against the snapshot stored at the end of the last refs-
touching refresh. On a diff, trigger a full refresh — same scope as the
focus-in handler, because once we know something changed externally
we can't be sure what (an agent might have created a worktree or
stashed something alongside the commit we detected).
Refresh runs in SYNC mode because goEvery already serializes iterations
via <-done: a slow refresh delays the next tick naturally instead of
letting work stack. The post-refresh hook from the previous commit
updates the snapshot, so in-app commands don't cause the next poll to
spuriously re-fire.
Disabled in the integration test config, like autoRefresh and autoFetch,
because demo replays make repo changes throughout the run; at 2-second
cadence the resulting full refreshes compete with the demo's own
choreography and push some demos past their 40-second timeout.
Also list the two new config keys in checkForChangedConfigsThatDontAutoReload
so a config edit warns the user that lazygit needs a restart.
This changes GetRepoPaths() to pull information from `git rev-parse`
instead of effectively reimplementing git's logic for pathfinding. This
change fixes issues with bare repos, esp. versioned homedir use cases,
by aligning lazygit's path handling to what git itself does.
This change also enables lazygit to run from arbitrary subdirectories of
a repository, including correct handling of symlinks, including "deep"
symlinks into a repo, worktree, a repo's submodules, etc.
Integration tests are now resilient against unintended side effects from
the host's environment variables. Of necessity, $PATH and $TERM are the
only env vars allowed through now.
We're not fully standardising here: different contexts can store their range state however
they like. What we are standardising on is that now the view is always responsible for
highlighting the selected lines, meaning the context/controller needs to tell the view
where the range start is.
Two convenient benefits from this change:
1) we no longer need bespoke code in integration tests for asserting on selected lines because
we can just ask the view
2) line selection in staging/patch-building/merge-conflicts views now look the same as in
list views i.e. the highlight applies to the whole line (including trailing space)
I also noticed a bug with merge conflicts not rendering the selection on focus though I suspect
it wasn't a bug with any real consequences when the view wasn't displaying the selection.
I'm going to scrap the selectedRangeBgColor config and just let it use the single line
background color. Hopefully nobody cares, but there's really no need for an extra config.
I've been thinking about this for a while: I think it looks really cool if nuking your working tree
actually results in a nuke animation.
So I've added an opt-out config for it