detached fca9155

fix(app): reconcile pull refs before force-push GC tests

commit
fca915500912709c587cf0e32e3242fda73ffbcd
author
brice · · 2026-10-19 20:43 UTC
parent
4d9eaac
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
checks
8/8
refs
tag: v0.28.0
2 files · +8 -0
M internal/app/cli_mr_e2e_test.go +4 -0
@@ -224,6 +224,10 @@ func TestMergeRequestsCLIEndToEnd(t *testing.T) {
224224 c.mustGit(wt, "reset", "-q", "--hard", main0)
225225 c.writeFile(wt, "other.txt", []byte("o\n"))
226226 c.mustGit(wt, "push", "-q", "--force", url, "feat/search")
227+ // Push refreshes the pull refs asynchronously. Reconcile them synchronously
228+ // before GC, or the old pull head/merge can still retain the read commit.
229+ require.NoError(t, c.forge.CI.RescanPulls(c.ctx, c.name("proj")))
230+ require.NotContains(t, strings.Fields(c.bareGit("proj", "rev-list", "--all")), head1)
227231 c.bareGit("proj", "reflog", "expire", "--expire=now", "--all")
228232 c.bareGit("proj", "gc", "-q", "--prune=now")
229233 res = c.cli(t, "", "mr", "show", "proj", "1", "--since-last-read", "--json").ok(t)
@@ -224,6 +224,10 @@ func TestMergeRequestsCLIEndToEnd(t *testing.T) {
224 c.mustGit(wt, "reset", "-q", "--hard", main0)224 c.mustGit(wt, "reset", "-q", "--hard", main0)
225 c.writeFile(wt, "other.txt", []byte("o\n"))225 c.writeFile(wt, "other.txt", []byte("o\n"))
226 c.mustGit(wt, "push", "-q", "--force", url, "feat/search")226 c.mustGit(wt, "push", "-q", "--force", url, "feat/search")
227+ // Push refreshes the pull refs asynchronously. Reconcile them synchronously
228+ // before GC, or the old pull head/merge can still retain the read commit.
229+ require.NoError(t, c.forge.CI.RescanPulls(c.ctx, c.name("proj")))
230+ require.NotContains(t, strings.Fields(c.bareGit("proj", "rev-list", "--all")), head1)
227 c.bareGit("proj", "reflog", "expire", "--expire=now", "--all")231 c.bareGit("proj", "reflog", "expire", "--expire=now", "--all")
228 c.bareGit("proj", "gc", "-q", "--prune=now")232 c.bareGit("proj", "gc", "-q", "--prune=now")
229 res = c.cli(t, "", "mr", "show", "proj", "1", "--since-last-read", "--json").ok(t)233 res = c.cli(t, "", "mr", "show", "proj", "1", "--since-last-read", "--json").ok(t)
M internal/app/web_mr_test.go +4 -0
@@ -653,6 +653,10 @@ func TestWebMergeRequestSinceAfterForcePush(t *testing.T) {
653653 r.mustGit(r.wt, "reset", "-q", "--hard", "main")
654654 r.writeFile(r.wt, "other.txt", []byte("o\n"))
655655 r.mustGit(r.wt, "push", "-q", "--force", r.url, "feat/search")
656+ // Push refreshes the pull refs asynchronously. Reconcile them synchronously
657+ // before GC, or the old pull head/merge can still retain the read commit.
658+ require.NoError(t, r.forge.CI.RescanPulls(r.ctx, r.name("proj")))
659+ require.NotContains(t, strings.Fields(r.bareGit("proj", "rev-list", "--all")), head1)
656660 r.bareGit("proj", "reflog", "expire", "--expire=now", "--all")
657661 r.bareGit("proj", "gc", "-q", "--prune=now")
658662
@@ -653,6 +653,10 @@ func TestWebMergeRequestSinceAfterForcePush(t *testing.T) {
653 r.mustGit(r.wt, "reset", "-q", "--hard", "main")653 r.mustGit(r.wt, "reset", "-q", "--hard", "main")
654 r.writeFile(r.wt, "other.txt", []byte("o\n"))654 r.writeFile(r.wt, "other.txt", []byte("o\n"))
655 r.mustGit(r.wt, "push", "-q", "--force", r.url, "feat/search")655 r.mustGit(r.wt, "push", "-q", "--force", r.url, "feat/search")
656+ // Push refreshes the pull refs asynchronously. Reconcile them synchronously
657+ // before GC, or the old pull head/merge can still retain the read commit.
658+ require.NoError(t, r.forge.CI.RescanPulls(r.ctx, r.name("proj")))
659+ require.NotContains(t, strings.Fields(r.bareGit("proj", "rev-list", "--all")), head1)
656 r.bareGit("proj", "reflog", "expire", "--expire=now", "--all")660 r.bareGit("proj", "reflog", "expire", "--expire=now", "--all")
657 r.bareGit("proj", "gc", "-q", "--prune=now")661 r.bareGit("proj", "gc", "-q", "--prune=now")
658 662

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 41

↑↓ moveenter openesc close