fix: merge autodetect can't close other PRs but only the last one when multiple PRs are pushed at once#37512
Merged
Conversation
services/pull/check.go:getMergeCommit shells out to "git rev-list --ancestry-path --merges --reverse <prHead>..<base>" and forwards the entire stdout to gitRepo.GetCommit. When several PRs targeting the same base branch are merged locally and pushed in one push, rev-list returns one line per merge commit on the ancestry path, so every PR except the most recent one ends up with a multi-line value. Before #35775 this happened to work: "git cat-file --batch-check" treated each line as another object name. Since #35775 the repository uses "git cat-file --batch-command", which interprets the second line as an unknown command, prints a fatal error, and exits. Because the *Repository caches the cat-file process, the subsequent commit lookup on the freshly resolved hash fails with EOF and the PR is silently skipped. Limit the rev-list output to a single hash with --max-count=1. The ancestry-path/--reverse ordering already puts the merge commit that introduced this PR first, so the result is unchanged for the only hash we actually need. Also reorder TrimSpace before the length check so the fast-forward fallback triggers on whitespace-only output (it never did before, but it is the obviously correct ordering). Includes TestManualMergeAutodetectMultiplePRs as a regression test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
testEditFileToNewBranch edits an existing file (README.md) on each new branch, which causes the second and third merges in the regression test to hit a README.md merge conflict. Switch to testCreateFile so each branch adds its own distinct file and the sequential merges produce clean fast-forward / merge commits, which is the actual scenario being reproduced. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
git rev-list --max-count=1 --reverse does not return the oldest commit: git applies --max-count during the natural newest-to-oldest traversal, so the surviving entry is the newest. Combined with --reverse it still yields the newest merge — meaning the previous fix would attribute every PR to whichever merge happened last in the push, even though detection itself worked. Drop --max-count=1 and slice the first line off the rev-list output in Go instead. The --reverse ordering of the full output is correct: the first line is the oldest merge on the ancestry path, which is the merge commit that actually introduced this PR onto the base branch. Tighten TestManualMergeAutodetectMultiplePRs to assert each PR's MergedCommitID matches that branch's actual merge commit (captured from the local clone after each "git merge"). The previous test only checked HasMerged / Status / MergerID, so the wrong-hash regression slipped through. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
|
Made some new improvements. And let's extend the existing test, but not introduce a new one (not really needed) |
0803220 to
050830e
Compare
wxiaoguang
approved these changes
May 2, 2026
bircni
approved these changes
May 2, 2026
6 tasks
silverwind
added a commit
to McMichalK/gitea
that referenced
this pull request
May 5, 2026
* origin/main: (49 commits) ci: lint PR titles with commitlint (go-gitea#37498) Make ServeSetHeaders default to download attachment if filename exists (go-gitea#37552) fix(actions): validate workflow param to prevent 500 error (go-gitea#37546) Fix various problems (go-gitea#37547) docs: fix 4 typos in CHANGELOG.md (go-gitea#37549) [skip ci] Updated translations via Crowdin chore(deps): update action dependencies (go-gitea#37540) fix: Fix `nolyfill` for renovate (go-gitea#37537) Refactor pull request view (7) (go-gitea#37524) Update go js py dependencies (go-gitea#37525) Don't unblock run-level-concurrency-blocked runs in the resolver (go-gitea#37461) Refactor pull request view (6) (go-gitea#37522) Refactor pull request view (5) (go-gitea#37517) fix: persist mirror repository metadata (go-gitea#37519) fix(packages): use file names for generic web downloads (go-gitea#37514) fix: merge autodetect can't close other PRs but only the last one when multiple PRs are pushed at once (go-gitea#37512) Fix update branch protection order (go-gitea#37508) Refactor "flex-list" to "flex-divided-list" (go-gitea#37505) fix: redirect early CLI console logger to stderr (go-gitea#37507) Fix mCaptcha broken after Vite migration (go-gitea#37492) ... # Conflicts: # templates/repo/diff/box.tmpl
zjjhot
added a commit
to zjjhot/gitea
that referenced
this pull request
May 6, 2026
* main: (36 commits) refactor(deps): migrate from `nektos/act` fork to `gitea/runner` (go-gitea#37557) ci: lint PR titles with commitlint (go-gitea#37498) Make ServeSetHeaders default to download attachment if filename exists (go-gitea#37552) fix(actions): validate workflow param to prevent 500 error (go-gitea#37546) Fix various problems (go-gitea#37547) docs: fix 4 typos in CHANGELOG.md (go-gitea#37549) [skip ci] Updated translations via Crowdin chore(deps): update action dependencies (go-gitea#37540) fix: Fix `nolyfill` for renovate (go-gitea#37537) Refactor pull request view (7) (go-gitea#37524) Update go js py dependencies (go-gitea#37525) Don't unblock run-level-concurrency-blocked runs in the resolver (go-gitea#37461) Refactor pull request view (6) (go-gitea#37522) Refactor pull request view (5) (go-gitea#37517) fix: persist mirror repository metadata (go-gitea#37519) fix(packages): use file names for generic web downloads (go-gitea#37514) fix: merge autodetect can't close other PRs but only the last one when multiple PRs are pushed at once (go-gitea#37512) Fix update branch protection order (go-gitea#37508) Refactor "flex-list" to "flex-divided-list" (go-gitea#37505) fix: redirect early CLI console logger to stderr (go-gitea#37507) ...
eleboucher
pushed a commit
to eleboucher/apoci
that referenced
this pull request
May 20, 2026
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [code.gitea.io/gitea](https://github.com/go-gitea/gitea) | `v1.26.1` → `v1.26.2` |  |  | --- ### Release Notes <details> <summary>go-gitea/gitea (code.gitea.io/gitea)</summary> ### [`v1.26.2`](https://github.com/go-gitea/gitea/releases/tag/v1.26.2) [Compare Source](go-gitea/gitea@v1.26.1...v1.26.2) - SECURITY - fix(permissions): Fix reading permission ([#​37769](go-gitea/gitea#37769)) - fix(actions): make artifact signature payloads unambiguous ([#​37707](go-gitea/gitea#37707)) - fix: Unify public-only token filtering in API queries and repo access checks ([#​37118](go-gitea/gitea#37118)) - fix: Add missed token scope checking ([#​37735](go-gitea/gitea#37735)) - fix(oauth): bind token exchanges to the original client request ([#​37704](go-gitea/gitea#37704)) - fix(oauth): strengthen PKCE validation and refresh token replay protection ([#​37706](go-gitea/gitea#37706)) - fix(web): enforce token scopes on raw, media, and attachment downloads ([#​37698](go-gitea/gitea#37698)) - fix(security): enforce wiki git writes and LFS token access at request time ([#​37695](go-gitea/gitea#37695)) - feat(api): encrypt AWS creds ([#​37679](go-gitea/gitea#37679)) - fix(deps): update dependency mermaid to v11.15.0 \[security], add e2e test - fix(packages): Add label for private and internal package and fix composor package source permission check ([#​37610](go-gitea/gitea#37610)) - fix(git): Fix smart http request scope bug ([#​37583](go-gitea/gitea#37583)) - Fix basic auth bug ([#​37503](go-gitea/gitea#37503)) - Fix allow maintainer edit permission check ([#​37479](go-gitea/gitea#37479)) ([#​37484](go-gitea/gitea#37484)) - Fix URL sanitization to handle schemeless credentials ([#​37440](go-gitea/gitea#37440)) ([#​37471](go-gitea/gitea#37471)) - Fix attachment Content-Security-Policy ([#​37455](go-gitea/gitea#37455)) ([#​37464](go-gitea/gitea#37464)) - chore(deps): bump go-git/go-git/v5 to 5.19.0 ([#​37608](go-gitea/gitea#37608)) - BUGFIXES - fix(pull): handle empty pull request files view to allow reviews ([#​37783](go-gitea/gitea#37783)) - fix(markup): make RenderString never fail ([#​37779](go-gitea/gitea#37779)) - fix: add natural sort to sortTreeViewNodes ([#​37772](go-gitea/gitea#37772)) - fix: package creation unique conflict ([#​37774](go-gitea/gitea#37774)) - fix!: add DEFAULT\_TITLE\_SOURCE setting for pull request title default behavior ([#​37465](go-gitea/gitea#37465)) - fix: Allow direct commits for unprotected files with push restrictions ([#​37657](go-gitea/gitea#37657)) - fix(actions): wrong assumption that run id always >= job id ([#​37737](go-gitea/gitea#37737)) - fix(auth): set User-Agent on avatar fetch and sync avatar on link-account register ([#​37564](go-gitea/gitea#37564)) ([#​37588](go-gitea/gitea#37588)) - fix(actions): deadlock between PrepareRunAndInsert and UpdateTaskByState ([#​37692](go-gitea/gitea#37692)) - fix(repo): /generate must sync the branch table for the new repo ([#​37693](go-gitea/gitea#37693)) - build: Fix snap build (1.26) - fix(actions): run TransferLogs on UpdateLog{Rows:\[], NoMore:true} ([#​37631](go-gitea/gitea#37631)) - fix show correct mergebase - fix: make clone URL respect public URL detection setting ([#​37615](go-gitea/gitea#37615)) - fix: "run as root" check ([#​37622](go-gitea/gitea#37622)) - chore(deps): update dependency go to v1.26.3 ([#​37601](go-gitea/gitea#37601)) - Compare dropdown fails when selecting branch with no common merge-base ([#​37470](go-gitea/gitea#37470)) - fix: treat email addresses case-insensitively ([#​37600](go-gitea/gitea#37600)) - fix(actions): fix blank lines after ::endgroup:: ([#​37597](go-gitea/gitea#37597)) - fix(actions): report individual step status in workflow job API response ([#​37592](go-gitea/gitea#37592)) - fix: Invalid UTF-8 commit messages in JSON API responses ([#​37542](go-gitea/gitea#37542)) - fix: use consistent GetUser family functions ([#​37553](go-gitea/gitea#37553)) - fix(api): return 409 message instead of empty JSON for wrong commit id ([#​37572](go-gitea/gitea#37572)) - fix(actions): prevent panic when workflow contains null jobs ([#​37570](go-gitea/gitea#37570)) - Make ServeSetHeaders default to download attachment if filename exists ([#​37552](go-gitea/gitea#37552)) ([#​37555](go-gitea/gitea#37555)) - Fix(actions): validate workflow param to prevent 500 error ([#​37546](go-gitea/gitea#37546)) ([#​37554](go-gitea/gitea#37554)) - Don't unblock run-level-concurrency-blocked runs in the resolver ([#​37461](go-gitea/gitea#37461)) ([#​37538](go-gitea/gitea#37538)) - Fix(packages): use file names for generic web downloads ([#​37514](go-gitea/gitea#37514)) ([#​37520](go-gitea/gitea#37520)) - Fix merge autodetect can't close other PRs but only the last one when multiple PRs are pushed at once ([#​37512](go-gitea/gitea#37512)) ([#​37516](go-gitea/gitea#37516)) - Fix update branch protection order ([#​37508](go-gitea/gitea#37508)) ([#​37513](go-gitea/gitea#37513)) - Fix mCaptcha broken after Vite migration ([#​37492](go-gitea/gitea#37492)) ([#​37509](go-gitea/gitea#37509)) - Fix review submission from single-commit PR view ([#​37475](go-gitea/gitea#37475)) ([#​37485](go-gitea/gitea#37485)) - Fix scheduled action panic with null event payload ([#​37459](go-gitea/gitea#37459)) ([#​37466](go-gitea/gitea#37466)) - Make GetPossibleUserByID can handle deleted user ([#​37430](go-gitea/gitea#37430)) ([#​37431](go-gitea/gitea#37431)) - Remove excessive quote from terraform instructions ([#​37424](go-gitea/gitea#37424)) ([#​37426](go-gitea/gitea#37426)) - Fix color regressions, add `priority` color ([#​37417](go-gitea/gitea#37417)) ([#​37421](go-gitea/gitea#37421)) - MISC - Add CurrentURL template variable back ([#​37444](go-gitea/gitea#37444)) ([#​37449](go-gitea/gitea#37449)) Instances on **[Gitea Cloud](https://cloud.gitea.com)** will be automatically upgraded to this version during the specified maintenance window. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/apoci/pulls/47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
AI-assisted contribution per the AI Contribution Policy: written with assistance from Claude Code. Each commit is annotated with
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>. Manually reviewed, manually executed against the integration test suite on the affected branches.Summary
Fix a behavior introduced in v1.26.0 where
manuallyMergedautodetect only closes the last of several PRs that were merged locally and pushed in a single push.services/pull/check.go:getMergeCommitran:and forwarded the entire stdout to
gitRepo.GetCommit. For PRs that aren't the most recent merge in a multi-merge push, rev-list legitimately returns several hashes, one per line. The multi-line value was then sent into the repository's cachedcat-file --batch-commandprocess, which interpreted the second line as an unknown command, printedfatal: unknown command: '...', and exited. The first lookup happened to consume the valid response and return the correct hash; the next lookup (repo.getCommit(id)) reused the now-dead cached process and failed withEOF, somanuallyMergedreturned false and the PR stayed open.Pre-v1.26.0, Gitea used
cat-file --batch/--batch-check, which treats every input line as an object name and tolerates multi-line input. The switch to--batch-commandin #35775 (commite226720cff) exposed this behavior.Fix
Take only the first line of
rev-listoutput before passing it toGetCommit. The--reverseordering of the full output already places the merge commit that introduced this PR onto the base branch first, so the result for every previously-working case is unchanged.Also re-orders
strings.TrimSpaceto run before the length check so the fast-forward fallback also handles whitespace-only output.Testing
TestManualMergeAutodetectMultiplePRs(new) — creates three branches, opens a PR per branch, has a second user clone the repo, run three sequentialgit merge --no-ff, and push once. Asserts every PR ends upManuallyMerged, attributed to the pusher, and thatpr.MergedCommitIDmatches that branch's actual merge commit (without the last assertion the wrong-hash class of regression slips through).TestManualMergeAutodetect(single PR, fast-forward) still passes.Fixes #37510.
Refs #37341 (where the multi-PR variant was first reported).