GitLab: Estimating the size of open merge requests
# Open merge request sizes
This table was generated as of **16/04/2026** and is a guess estimate of MR sizes, just to give a rough sorting by difficulty. The columns indicate the number of **changed lines** (insertions + deletions) in the entire MR, whitespace changes and empty lines are ignored. For better visibility, changes to "Makefiles" and tests are counted in separate columns, other changes are displayed as "**Functional**" (see the [section below](https://gitlab.com/freepascal.org/fpc/source/-/work_items/41722#details) for calculation details):
| Functional | Makefiles | Tests | Merge request |
| --- | --- | --- | --- |
|0|0|460|!568+|
|0|0|0|!962+|
|0|0|420|!1113+|
|2|0|0|!903+|
|2|0|57|!1429+|
|3|0|40|!739+|
|3|0|0|!1051+|
|3|0|0|!1266+|
|5|0|0|!1108+|
|6|0|0|!64+|
|6|0|0|!687+|
|6|0|0|!1250+|
|7|0|0|!261+|
|7|0|0|!541+|
|7|0|0|!1289+|
|7|0|57|!1427+|
|8|0|0|!249+|
|8|0|15|!1435+|
|10|0|0|!76+|
|10|0|0|!561+|
|10|0|0|!733+|
|11|0|26|!1421+|
|11|0|64|!1426+|
|14|0|0|!100+|
|14|0|0|!1413+|
|14|0|0|!1428+|
|18|0|0|!617+|
|19|0|0|!448+|
|19|0|0|!1007+|
|21|0|0|!1393+|
|21|0|71|!1425+|
|23|0|0|!977+|
|23|0|0|!1418+|
|24|0|35|!1424+|
|25|0|49|!1434+|
|29|0|0|!1045+|
|30|0|0|!1414+|
|33|0|0|!65+|
|33|0|71|!1407+|
|34|0|0|!619+|
|36|0|0|!1193+|
|41|0|0|!1353+|
|44|0|0|!242+|
|48|0|0|!692+|
|48|0|0|!1154+|
|57|0|0|!644+|
|65|0|0|!158+|
|70|0|0|!227+|
|72|0|0|!250+|
|74|0|0|!240+|
|75|0|21|!149+|
|75|0|12|!648+|
|79|0|1165|!1419+|
|87|0|0|!625+|
|89|0|0|!892+|
|97|0|0|!232+|
|98|0|0|!251+|
|99|0|0|!458+|
|100|0|0|!1156+|
|107|0|0|!964+|
|113|0|0|!887+|
|117|0|0|!1423+|
|118|0|0|!66+|
|118|0|0|!181+|
|119|0|0|!883+|
|120|0|0|!186+|
|122|0|0|!1155+|
|141|0|0|!732+|
|142|0|0|!683+|
|144|0|0|!1403+|
|151|0|412|!829+|
|152|0|271|!860+|
|154|0|0|!338+|
|160|0|0|!621+|
|166|0|0|!1026+|
|168|0|0|!536+|
|168|0|0|!1071+|
|177|0|0|!1127+|
|185|0|269|!875+|
|187|0|0|!285+|
|192|0|0|!85+|
|193|0|0|!1105+|
|201|0|0|!633+|
|222|0|0|!302+|
|224|0|0|!1034+|
|226|0|0|!725+|
|228|0|0|!895+|
|231|0|85|!856+|
|235|0|0|!233+|
|243|0|338|!830+|
|251|0|0|!634+|
|261|0|0|!1268+|
|262|0|0|!978+|
|266|0|0|!134+|
|280|0|0|!743+|
|286|0|226|!1048+|
|290|0|397|!1037+|
|295|0|0|!1436+|
|353|0|0|!209+|
|358|0|0|!408+|
|362|0|0|!281+|
|400|0|220|!1149+|
|418|0|0|!898+|
|431|0|0|!527+|
|438|0|0|!537+|
|440|0|0|!1053+|
|459|0|0|!196+|
|461|0|14|!878+|
|490|0|0|!67+|
|522|0|0|!287+|
|534|0|0|!1362+|
|539|0|0|!596+|
|543|0|0|!110+|
|614|0|0|!74+|
|617|0|2400|!498+|
|623|0|627|!837+|
|639|0|0|!1252+|
|687|0|0|!367+|
|736|0|23|!828+|
|887|0|0|!391+|
|894|0|0|!126+|
|904|0|6|!1437+|
|926|0|0|!259+|
|947|0|0|!1385+|
|987|0|0|!207+|
|1083|0|52|!230+|
|1193|0|0|!253+|
|1370|0|469|!340+|
|1378|0|309|!850+|
|1544|0|46|!1195+|
|1643|0|0|!191+|
|2185|0|3424|!822+|
|2213|0|936|!645+|
|3026|0|1116|!1+|
|3885|0|66|!1038+|
|5306|7|0|!1159+|
|7138|0|0|!1409+|
|8191|4|0|!179+|
|12382|0|11880|!1187+|
|12751|2559|0|!775+|
|25544|41021|1936|!1263+|
|47795|0|39566|!78+|
|341268|1058891|36013|!187+|
# Details
There's a [GitLab GraphQL API](https://docs.gitlab.com/api/graphql/reference/#mergerequest), but it seems there's no way to get the change count (only commits)? In any case, it definitely won't allow you to filter changes, such as makefiles. Therefore, a local calculation method was used:
1. **GitLab** stores hidden references inside **Git** for MR that can be [easily retrieved](https://docs.gitlab.com/user/project/merge_requests/merge_request_troubleshooting/#check-out-locally-by-modifying-gitconfig-for-a-given-repository).
2. After fetching, they can be parsed with a small program, which will also filter out changes to makefiles and tests. Filtering criteria can be expanded (for example, to include documentation or specific file extensions). See the code below for details (generates a **Markdown** table):
<details>
<summary>Click to view draft program</summary>
~~~pascal
uses Classes, SysUtils, Process;
const
CRepo = 'S:\fpc.git'; // path to FPC source repository
CFilter = 'git log main..origin/merge-requests/%d --stat' + ' -w --ignore-blank-lines';
var
MR: integer;
lStat: TStringList; // "git log --stat" output
lFileName, lGraph, s: string;
nTotal, nMake, nTests, n: integer; // line changes
begin
writeln('| Functional | Makefiles | Tests | Merge request |');
writeln('| --- | --- | --- | --- |');
lStat := TStringList.Create;
for MR := 1 to 2000 do // take 2000 as a maximum
if RunCommandInDir(CRepo, Format(CFilter, [MR]), s) then begin // if the MR reference was found
nTotal := 0;
nMake := 0;
nTests := 0;
lStat.Text := s;
for s in lStat do
if pos('|', s) > 0 then begin
// pattern: " packages/pastojs/src/fppas2js.pp | 106 ++++++++++++++++++++++++++++-----"
SScanf(s, ' %s | %d %s', [@lFileName, @n, @lGraph]);
nTotal += n;
if SameText(ExtractFileName(lFileName), 'makefile') then // "Makefile" / "Makefile.fpc" / "Makefile.pkg"
nMake += n;
if pos('test', LowerCase(lFileName)) > 0 then // assumption that tests use "test" in the file name or path
nTests += n;
end;
writeln(Format('|%d|%d|%d|!%d+|', [nTotal-nMake-nTests, nMake, nTests, MR]));
end;
end.
~~~
</details>
3. The references also contain merged and closed MRs. The [GitLab REST API](https://docs.gitlab.com/api/merge_requests/) was used to obtain MR status, the data was filtered and sorted (not shown in the program code).
The results are presented in the table above, sorted by the number of lines of functional change.
issue