Expose single file merge request diff endpoint to Public API
<!--IssueSummary start--> <details> <summary> Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards. </summary> - [Close this issue](https://contributors.gitlab.com/manage-issue?action=close&projectId=278964&issueIid=414389) </details> <!--IssueSummary end--> ## Problem to Solve In cases where diffs exceed the threshold for 10% of the configured limits, those diffs are collapsed in merge requests. In the merge request UI you can click a button load the diff and retrieve the changes anyway. However, if you're retrieving diffs via the API we return an empty diff section if it's collapsed. There is currently no endpoint to retrieve the single file diff. ## Proposal We have an internal API to retrieve the single file diff, we should expose that in the public API so that if you receive an empty diff in the main listing, you can access that single file separately. <details> <summary>Original Bug Report</summary> ### Summary One of our [customers](https://gitlab.zendesk.com/agent/tickets/414041) reported that they are seeing an empty diff when using the [list merge request diffs API](https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-request-diffs). They mentioned that this seems to happen whenever an MR contains a new file that exceeds a certain size. They've narrowed down the lower boundary of the size required to reproduce it somewhat: - Correct diffs returned for new file with 20096 bytes. - Empty diffs returned for new file with 20224 bytes (and larger). After some troubleshooting, I was only able to reproduce this behavior after [using an external storage for merge request diffs](https://docs.gitlab.com/ee/administration/merge_request_diffs.html#using-external-storage). I was able to reproduce on GitLab 15.7.9 (customer's version) and GitLab 16.0.1. It also appears to happen on GitLab.com. Are we using external storage for merge request diffs in Gitlab.com? UI shows the actual diff: - https://gitlab.com/jdasmarinas/test-mr-diff/-/merge_requests/4/diffs But the API shows that the `diff` for `lorem-ipsum.txt` is empty: - https://gitlab.com/api/v4/projects/46272613/merge_requests/4/diffs ``` | 1 | | |--------------|-------------------| | diff | "" | | new_path | "lorem-ipsum.txt" | | old_path | "lorem-ipsum.txt" | | a_mode | "0" | | b_mode | "100644" | | new_file | true | | renamed_file | false | | deleted_file | false | ``` ### Steps to reproduce 1. Install GitLab and set `gitlab_rails['external_diffs_enabled']` to `true`. 2. Create a new MR. 3. Add a file in the source branch that exceeded ~21 KB. 4. Use the [list merge request diffs API](https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-request-diffs) against the MR. ### Example Project - https://gitlab.com/jdasmarinas/test-mr-diff/-/merge_requests/4/diffs - https://gitlab.com/api/v4/projects/46272613/merge_requests/4/diffs ### What is the current *bug* behavior? List merge request diffs shows an empty diff for a file if it exceeded a certain size and external diff storage is on. ### What is the expected *correct* behavior? List merge request diffs should show the actual diff. ### Relevant logs and/or screenshots <!-- Paste any relevant logs - please use code blocks (```) to format console output, logs, and code as it's tough to read otherwise. --> ### Output of checks <!-- If you are reporting a bug on GitLab.com, uncomment below --> <!-- This bug happens on GitLab.com --> <!-- /label ~"reproduced on GitLab.com" --> #### Results of GitLab environment info <!-- Input any relevant GitLab environment information if needed. --> <details> <summary>Expand for output related to GitLab environment info</summary> <pre> (For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:env:info`) (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`) </pre> </details> #### Results of GitLab application Check <!-- Input any relevant GitLab application check information if needed. --> <details> <summary>Expand for output related to the GitLab application check</summary> <pre> (For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:check SANITIZE=true`) (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true`) (we will only investigate if the tests are passing) </pre> </details> ### Possible fixes <!-- If you can, link to the line of code that might be responsible for the problem. --> </details>
issue