From 419eb0a4a26dfb7ad7f48c44a3708689dc18ee79 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 10 Oct 2025 14:15:38 +0200 Subject: [PATCH] feat: improve getting shortstat (#9587) Refactor the existing functions to get shortstat of commit and between two commits to use performant alternatives, mainly `git-diff-tree` and `git-diff-index`. Resolves forgejo/forgejo#9551 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9587 Reviewed-by: Earl Warren Co-authored-by: Gusted Co-committed-by: Gusted --- modules/git/repo_compare.go | 48 +++++++++----- modules/git/repo_compare_test.go | 59 ++++++++++++++++++ modules/git/tests/repos/symmetric_repo/HEAD | 1 + modules/git/tests/repos/symmetric_repo/config | 4 ++ .../01/fc2bb01605691ba1f40694c1da70501583a085 | Bin 0 -> 1042 bytes .../02/84078471ec566623807297baf4450382542dcb | Bin 0 -> 1038 bytes .../19/33da329284aca10dab8dc2fdd54213acd39be5 | Bin 0 -> 46 bytes .../3f/10b1d474ee0a63d008be715494586ccbbbc9da | Bin 0 -> 951 bytes .../3f/151445f4d22fec48009aa692142c96bce6dcf6 | Bin 0 -> 999 bytes .../4b/825dc642cb6eb9a060e54bf8d69288fbee4904 | Bin 0 -> 15 bytes .../54/93447336137e6fc28e3be3067f7049273c6909 | Bin 0 -> 999 bytes .../61/780798228d17af2d34fce4cfbdf35556832472 | Bin 0 -> 17 bytes .../6a/69f92020f5df77af6e8813ff1232493383b708 | Bin 0 -> 17 bytes .../6b/e660545b31f61a82a87d2b1915f0b88bb9f16f | Bin 0 -> 46 bytes .../71/3fc38bac217f3909a1ca43479dec4f3f6e039e | Bin 0 -> 95 bytes .../83/966f2fad7dfb1c567ca63bb68e9a7d38b4afc6 | Bin 0 -> 1041 bytes .../9d/36f18c8ca14ad28c4751afd14f3e3146a785dc | Bin 0 -> 999 bytes .../bf/91e6a4737da117217f8b32276998b10ee55f65 | Bin 0 -> 135 bytes .../d6/dfac318c3dcd5f05554472666d7bb6dfd9e8db | Bin 0 -> 951 bytes .../e4/2ba3e77f66f623836b47df796932f7e5604aec | Bin 0 -> 70 bytes .../f2/ad6c76f0115a6ba5b00456a849810e7ec0af20 | Bin 0 -> 17 bytes .../f4/e316302084c597f1678ff1db625b28f68194ae | Bin 0 -> 70 bytes .../tests/repos/symmetric_repo/packed-refs | 8 +++ .../repos/symmetric_repo/refs/heads/.gitkeep | 0 .../repos/symmetric_repo/refs/tags/.gitkeep | 0 services/convert/pull.go | 5 +- services/gitdiff/gitdiff.go | 21 ++----- services/repository/files/temp_repo.go | 2 +- 28 files changed, 116 insertions(+), 32 deletions(-) create mode 100644 modules/git/tests/repos/symmetric_repo/HEAD create mode 100644 modules/git/tests/repos/symmetric_repo/config create mode 100644 modules/git/tests/repos/symmetric_repo/objects/01/fc2bb01605691ba1f40694c1da70501583a085 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/02/84078471ec566623807297baf4450382542dcb create mode 100644 modules/git/tests/repos/symmetric_repo/objects/19/33da329284aca10dab8dc2fdd54213acd39be5 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/3f/10b1d474ee0a63d008be715494586ccbbbc9da create mode 100644 modules/git/tests/repos/symmetric_repo/objects/3f/151445f4d22fec48009aa692142c96bce6dcf6 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/54/93447336137e6fc28e3be3067f7049273c6909 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/61/780798228d17af2d34fce4cfbdf35556832472 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/6a/69f92020f5df77af6e8813ff1232493383b708 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/6b/e660545b31f61a82a87d2b1915f0b88bb9f16f create mode 100644 modules/git/tests/repos/symmetric_repo/objects/71/3fc38bac217f3909a1ca43479dec4f3f6e039e create mode 100644 modules/git/tests/repos/symmetric_repo/objects/83/966f2fad7dfb1c567ca63bb68e9a7d38b4afc6 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/9d/36f18c8ca14ad28c4751afd14f3e3146a785dc create mode 100644 modules/git/tests/repos/symmetric_repo/objects/bf/91e6a4737da117217f8b32276998b10ee55f65 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/d6/dfac318c3dcd5f05554472666d7bb6dfd9e8db create mode 100644 modules/git/tests/repos/symmetric_repo/objects/e4/2ba3e77f66f623836b47df796932f7e5604aec create mode 100644 modules/git/tests/repos/symmetric_repo/objects/f2/ad6c76f0115a6ba5b00456a849810e7ec0af20 create mode 100644 modules/git/tests/repos/symmetric_repo/objects/f4/e316302084c597f1678ff1db625b28f68194ae create mode 100644 modules/git/tests/repos/symmetric_repo/packed-refs create mode 100644 modules/git/tests/repos/symmetric_repo/refs/heads/.gitkeep create mode 100644 modules/git/tests/repos/symmetric_repo/refs/tags/.gitkeep diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index 94f1911c4a..fc7944a8c6 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -174,16 +174,36 @@ func (repo *Repository) GetDiffNumChangedFiles(base, head string, directComparis return w.numLines, nil } -// GetDiffShortStat counts number of changed files, number of additions and deletions -func (repo *Repository) GetDiffShortStat(base, head string) (numFiles, totalAdditions, totalDeletions int, err error) { - numFiles, totalAdditions, totalDeletions, err = GetDiffShortStat(repo.Ctx, repo.Path, nil, base+"..."+head) - if err != nil && strings.Contains(err.Error(), "no merge base") { - return GetDiffShortStat(repo.Ctx, repo.Path, nil, base, head) +var ( + ErrNoMergebaseFound = errors.New("no merge base found") + ErrMultipleMergebasesFound = errors.New("multiple merge bases found") +) + +// GetShortStat returns the number of changed files, additions and deletions. If +// `useMergebase` is specified then the merge base between `base` and `head` is +// used to compare against `head`. +func (repo *Repository) GetShortStat(base, head string, useMergebase bool) (numFiles, totalAdditions, totalDeletions int, err error) { + cmd := NewCommand(repo.Ctx, "diff-tree", "--shortstat") + if useMergebase { + cmd = cmd.AddArguments("--merge-base") } - return numFiles, totalAdditions, totalDeletions, err + cmd.AddDynamicArguments(base, head) + + stdout, stderr, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) + if err != nil { + switch stderr { + case "fatal: no merge base found\n": + return 0, 0, 0, ErrNoMergebaseFound + case "fatal: multiple merge bases found\n": + return 0, 0, 0, ErrMultipleMergebasesFound + } + return 0, 0, 0, err + } + + return parseDiffStat(stdout) } -// GetCommitStat returns the number of files, total additions and total deletions the commit has. +// GetCommitShortStat returns the number of files, total additions and total deletions the commit has. func (repo *Repository) GetCommitShortStat(commitID string) (numFiles, totalAdditions, totalDeletions int, err error) { cmd := NewCommand(repo.Ctx, "diff-tree", "--shortstat", "--no-commit-id", "--root").AddDynamicArguments(commitID) stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) @@ -194,13 +214,13 @@ func (repo *Repository) GetCommitShortStat(commitID string) (numFiles, totalAddi return parseDiffStat(stdout) } -// GetDiffShortStat counts number of changed files, number of additions and deletions -func GetDiffShortStat(ctx context.Context, repoPath string, trustedArgs TrustedCmdArgs, dynamicArgs ...string) (numFiles, totalAdditions, totalDeletions int, err error) { - // Now if we call: - // $ git diff --shortstat 1ebb35b98889ff77299f24d82da426b434b0cca0...788b8b1440462d477f45b0088875 - // we get: - // " 9902 files changed, 2034198 insertions(+), 298800 deletions(-)\n" - cmd := NewCommand(ctx, "diff", "--shortstat").AddArguments(trustedArgs...).AddDynamicArguments(dynamicArgs...) +// GetIndexShortStat returns the number of files, total additions and total +// deletions the commit has. +// +// NOTE: It uses `git-diff-index`, should only be used when working with +// temporary repository. When working on bare repositories use `GetCommitShortStat`. +func GetIndexShortStat(ctx context.Context, repoPath, commitID string) (numFiles, totalAdditions, totalDeletions int, err error) { + cmd := NewCommand(ctx, "diff-index", "--cached", "--shortstat").AddDynamicArguments(commitID) stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) if err != nil { return 0, 0, 0, err diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go index b1ebdf6177..cdce26d241 100644 --- a/modules/git/repo_compare_test.go +++ b/modules/git/repo_compare_test.go @@ -243,3 +243,62 @@ func TestGetCommitShortStat(t *testing.T) { assert.Equal(t, 0, totalDeletions) }) } + +func TestGetShortStat(t *testing.T) { + // https://github.com/git/git/blob/60f3f52f17cceefa5299709b189ce6fe2d181e7b/t/t4068-diff-symmetric-merge-base.sh#L10-L23 + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "symmetric_repo")) + require.NoError(t, err) + defer repo.Close() + + t.Run("Normal", func(t *testing.T) { + t.Run("Via merge base", func(t *testing.T) { + numFiles, totalAdditions, totalDeletions, err := repo.GetShortStat("br2", "main", true) + require.NoError(t, err) + assert.Equal(t, 1, numFiles) + assert.Equal(t, 1, totalAdditions) + assert.Zero(t, totalDeletions) + + numFiles, totalAdditions, totalDeletions, err = repo.GetShortStat("main", "br2", true) + require.NoError(t, err) + assert.Equal(t, 1, numFiles) + assert.Equal(t, 1, totalAdditions) + assert.Zero(t, totalDeletions) + }) + + t.Run("Direct compare", func(t *testing.T) { + numFiles, totalAdditions, totalDeletions, err := repo.GetShortStat("main", "br2", false) + require.NoError(t, err) + assert.Equal(t, 2, numFiles) + assert.Equal(t, 1, totalAdditions) + assert.Equal(t, 1, totalDeletions) + + numFiles, totalAdditions, totalDeletions, err = repo.GetShortStat("main", "br3", false) + require.NoError(t, err) + assert.Equal(t, 1, numFiles) + assert.Equal(t, 1, totalAdditions) + assert.Zero(t, totalDeletions) + + numFiles, totalAdditions, totalDeletions, err = repo.GetShortStat("br3", "main", false) + require.NoError(t, err) + assert.Equal(t, 1, numFiles) + assert.Zero(t, totalAdditions) + assert.Equal(t, 1, totalDeletions) + }) + }) + + t.Run("No merge base", func(t *testing.T) { + numFiles, totalAdditions, totalDeletions, err := repo.GetShortStat("main", "br3", true) + require.ErrorIs(t, err, ErrNoMergebaseFound) + assert.Zero(t, numFiles) + assert.Zero(t, totalAdditions) + assert.Zero(t, totalDeletions) + }) + + t.Run("Multiple merge base", func(t *testing.T) { + numFiles, totalAdditions, totalDeletions, err := repo.GetShortStat("main", "br1", true) + require.ErrorIs(t, err, ErrMultipleMergebasesFound) + assert.Zero(t, numFiles) + assert.Zero(t, totalAdditions) + assert.Zero(t, totalDeletions) + }) +} diff --git a/modules/git/tests/repos/symmetric_repo/HEAD b/modules/git/tests/repos/symmetric_repo/HEAD new file mode 100644 index 0000000000..992854f9fb --- /dev/null +++ b/modules/git/tests/repos/symmetric_repo/HEAD @@ -0,0 +1 @@ +ref: refs/heads/br3 diff --git a/modules/git/tests/repos/symmetric_repo/config b/modules/git/tests/repos/symmetric_repo/config new file mode 100644 index 0000000000..07d359d07c --- /dev/null +++ b/modules/git/tests/repos/symmetric_repo/config @@ -0,0 +1,4 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = true diff --git a/modules/git/tests/repos/symmetric_repo/objects/01/fc2bb01605691ba1f40694c1da70501583a085 b/modules/git/tests/repos/symmetric_repo/objects/01/fc2bb01605691ba1f40694c1da70501583a085 new file mode 100644 index 0000000000000000000000000000000000000000..914d958d7113f04630489455b71418074159c1ac GIT binary patch literal 1042 zcmWO0OKjT&0DxhzRl4ONP+~z@+e`RL_(Ox>c?UIs6$mX!+u}O(IASDM7EkeE7DU*;R(fcob|2HqQ&z|>s z@CHf{#P&N8hQEy_i8YoySz$O5Bi8W~;*cY_H6l*NA9Jfbxr(phYyv&u&Y~+Y(~E7O zsE)?b$7nps@nizWaqI*|lRB}^aCkg^RiaoT&aAE#e@Z4E5oA1`BuShg*ApyD>MMyg zCPAY3I-W!y5m<7KG>F5$7#Ml_WHGa|h%Bt~8;6l6iwjSAcwrS0SEjxH+`hH>dt~O` z{jIHgTR+^NjeIdX^XAOXd#PJB=JeUPIR3MHXDavFj`;P9v2bnY)eo-yd*?;ocik^e zUB3_`JCRRcxx2Zvw7k6Z@ZAUX&rVOzU%zp4cKhbpe{alO%x*S*ymNS1 zJvCji{VEoX4zz5B9^`E}R#bcq$gP%4kfy7l^k~@BE0xJ;d^yUc*aMa25l!Foa3*8s z@uMmnJ@R^F&|6V+Ij7~n9PzZtWvx1-o8j&-6_Sj0SS}3(|HSJtw4r;XVY({kCX`qV zQ@$dcaoS-_syZ|{wn7?}W+@K^9t_#z2E>)x2qv37E{b5RT4|^4H(AM`+y(x@mSOb1aGVtrPFG;wjbT?Hy}m|fLd7Q!lThBa9qX87G3GUS7*%@ zUIZoDwnEX7&1aZy(5w5>o;@{O$_k2}E;1sZ9OHGUm@|X^bW|Fo3%nQ@z~z1=?=}q> z$&4%}7^}G@UrWMyrR3-}uaJw@Dh@ns(cxHIo7gH(H6ULLfP)jP=6bNL_>g%#I>wqpe3j!Rp||AAb?1?$Lb&WBt>pOU224M7*(tVsL;S)&9r$f z9l{HS?r$QUeok=tve%ZqzP9e{R*YEs%Au=yAtb|e4RghG18Qovhob=_wcGT$MtL%< zlyK7@b6Z+l500{zaz%!#p`tc$>69o6PK;}%45b4M97T04zFLQ}CL2SBG~bf}18%qX z^daEsHTV02W(lxt%eJXh!ewpJT5Gq(K$k2H zEE&AR}ij`B01CLk^PxL134ucL0J=2r{nf&8X2Z;DnyRG;Bto0h0;RJ2AZ00*CfH!WA*aEJpt$)L zy?zP9POC=PfULqO;xeI57qp82;O2`S_jnK3?ZgL{v@d$PH*uib3Hlvp#D5K49sWbB zn0x5;&Ut4ZDz&3ZMTcVi6U$W+S$|m%*LTYITZr@H{;%KEJ!i+?y>j;7`)>l0b5eiH zxdXp;Tzl)C2g7}R{r!DUKYFrudwspue(|z$#L3IU7Tv^?|*vdO#XRJ?hDizm9A4&!WcTWOwdG8RwxOVDJj9D#cCR(#Ys_@pNVGt z6$@G<=sc(kumK)o%64^-2oX7X8t`OA2oWvt6;Rk!R2O-7GnNQ>fMmpdEM=uw3dn5m zbPOValR`>bk_o|O5VUBLDc;9Xh-gjDQCmVEn1~fuq)Y%$V^W`|UQrtbSq*7N3Vd0T zUyd~?e<2Yr2g_|VnYS$hbRokrP$LxMD?m=(01H7Y&zw-Pj6Vs9-Kqec4C_LEqjet8 zNYEmNge@7a!3cP=&g&q)A)r-kouzE~h?EPkTuyF@iVzZu%PN3M2OZmF?3OXtPJ&etFSH4a8^(f- zOjrRt>B);E4R;frCy_2OK@ipBAkXCU3~NohLlp?K3cxtfcKV{JV<2{;AR(F(BSKSI zo2U_2gJIfQ0wj!w_GmO)r9!o|7>$c<`KUC1990t(C@ES2PYmLOYjPtUDrT})GG(!A z)Y5z#MQ}lZ$S)|a=*nnCM({o`T$cJY7*{7GP$>}CL@ilkin3dY@Tsw7O^$#-k`;sl zUCpM1AhHoIZ3FEDMOq^q6ejSk6_p)4sj7oP8q10Wv`!NRt)MKSv)Jl5W@kQrb>*lw zH`@B@;qKj5#VmO#eQA-}**Q3n|1kS{V&6MC(|Pmz(Q7x`-+SbqnHxQt8d~^Ad3S1f z@b;g{j)5VqjumU~CxZk@jPY+448d2_fGu@#-XM+erU>#kVG$f#FFKZy^AH CQW0+e literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/3f/10b1d474ee0a63d008be715494586ccbbbc9da b/modules/git/tests/repos/symmetric_repo/objects/3f/10b1d474ee0a63d008be715494586ccbbbc9da new file mode 100644 index 0000000000000000000000000000000000000000..b54a2a79d7731b98adf62f29b797c65bf03e8bf0 GIT binary patch literal 951 zcmWO3O>5g`007`=t=-{}gP<}oZ3Je>RLoJ*#LM==YS6)2l@ASV)xbds_#k(_h%8|+ zw_s4H4T4R~84^=J3_eI;3ZhWRsvHbDSgRS;U^!V74R6RpJNVXvHD=bI@bG*KZF|4H zdX;C_3TuVCH}I`pZtbH2v%PtCduwNNz3|z_S>f4EVTUQ)+`Reo4!yfcZ!jC%AFiG4 zgj@NQ;mg&}4_8+RdY65Mzg#7TyLp0MIl6siA>!_QIl`A7KHA%RxcAeeYxq~!mNH9+ zWIj)0`*-h=_r9*4pAheTY@gqc@yjo++_-%I{9n*|khD)8d}CjIadrLDt*4K#FF$#F zvHZpB_5J}+s&HJ~0JpJI}`~Bnm>+8qQj~0J@clpW1^GlUK z`IH4>g&`FsQ40wzrbc3~h4+05m6HuZrpFjRD1*sY2VYWwq14ow1InaI<8X^ z;8QVdLoQbAq47Ly7oBNWQ`opK%{0BK3=#?}Rg+o5Xkw)dX|_G8TT7Hjuvs3XT9`oF zS&C1Y2wm>Ph&&Uf^+@e`37{r%%#NpBbZAs_l6KHk-S&7~1L=coorK3#*{h;<70?vk zKq_56MPZ_5nyzVxF_<H&HX`F&vywK9 Z`5!*{>z}_*R(?6GA42c^ap%+X{{bqfx()yU literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/3f/151445f4d22fec48009aa692142c96bce6dcf6 b/modules/git/tests/repos/symmetric_repo/objects/3f/151445f4d22fec48009aa692142c96bce6dcf6 new file mode 100644 index 0000000000000000000000000000000000000000..82c5d29824b3ead4615af5eb722bc3d4f5e1a5dc GIT binary patch literal 999 zcmWO1OKjT&0DxhLRkkILKy3tNO(c|zi8ywf*lkfud>}rM`q9ytm8sY_HaLJ(*+YWK zz9cut=HN&OZOMhAO-e4qO{AoAE(t=LADfhj10p#vv`VNqCt(tbC3^n#AHHv2rJg=> zU3f3Op2lvzmn50%X^Pyyu=GZTK{sg(qnl~6nZA}G(dPO(gXN8fdD5V@50h?c zFQ1`yD0*|Vncv*q+08KL>&8YV^FE4UROT9qp4VUKR(|I>2_sJ)uN4m0kkuV#?_u)s z+UgSqUfn^2{Dsgz*FV|+Be{I{-oe4$gCFm$B)?o)etY@w!{`m2Jb5}TPMPO?*^7s-e|+)Z+b>1%Qdn5HbS5MZlb^qKXMbyJdwc7_2lv}IPfkwXynJQl)|D6k zy|sL{vfugn?4vtZ-~IId%A?a8?XA;WFE0PEu)Y1@iwnJ9I}uK79t~o%88B30rAaU> zv7_o@qEt3#}s0jQKZ0R;W7q*2|i(>rBqD?0yNVH19-e%4ck!GwR@V~j>I)0%gqfS>hlV^ zh>v6p)EGRFD8r0pN|4njQGx8n7< zpzv1Na1|n;r}&YG`=u1-x!inEDob9&>}9jWuo+`DxN6~E!7qYZ6A!l|xfxL()fio> ztMh7+mSaRWpb;UA2&7oh5m}=r3&v7KoUt{CJ`&0-;ul7tEIJ__l#Ummc0|PtXV_OI z6IG@ShwO@CMWwovn0(Z8ph*Lsvt?iAUA%~gHObT~(P4ojIWyLe6R^f;Zabo2Zq-cK z9za%!n$e;vc(|lDWxS^!vp&u@Q@Csm>L>z;G!aJud(Kr#(QdUes`6P#tV!pJ>6r77 z0f@>TEaNN^m>$hNEe=WDfibblSsdySDyLFH!Kb1!zto>d8r49lR8Gk{CgOD>=8&6V zrc$4l+@dcSva80cJiRD;4U04+e_RrEHxZ%%sl_hUe9c=V9Q$03mJ)p@HLV2O5eb~O zhWZQ{4(NJLHpWprPIh6T=ICQo(=CoS=WfL~4hBOCtcXP+#1T%G?B$j)e(1oy(Tc^WAU1 TKU?_h`@e+efma?myMO)!)4pHY=HYTe}@L2vP@I zkuTQGwsw$Vj8?wbqlM%WBzuiB>tc_swX7B_b{NEmZ6q*qlkF9T4a@c8@!-Mt%`5El z7mkB(#o{sQ&U+Dtzm=vk*Vg0IdW<}XW!78q8&sTnl4dC`LsBG98fnUmHRBoX1WV(L z6Wu!C*4A07nf@t#J$^o~8R_-4_pfmryB5z-*UwdJZ2U=#&zv$i@$Bhpc6XIn$?#hT zk*BLG&v<+#Lx|~%&_B0sZvPQkdhl>(=fTbo50@ifEHAyawEJQ3w#FPipA;v54el-E zU*8qKemTiq+I{WgOaI<`DZ!T!apCfr7}_F#BobvH zG-~=C8X%G^n-o>mK}%&HGArwOWKTGD5yb7(C@j?wJ=~hv#xc@$iNioKi)I0x_W85~ zY9f8u9`>yyW{g|*u?6g7wv@xNd=0W3x)s%D36!mSDial%|`I*@cB$%1qpLgdW zYtbDs4z7g-y^gEyK!WW;&Js-n&{eCNvWA9#UNEOsn`C>u#>w++t6&M|6+(?iCQwK3 zNMVb$F&RqPv?8#@@VMz80i{6$3$wT^f@&>CFvE%k&j62zdX&VG+FqwWY6s-$9CiUh zA@;mhHQz{dl$;A1d-X~I1A7?i@P^+FxuD(Lui%{`P9<{~IMzKT86*jurXb#&qDqJEssR579RIXVo572IwM96(DL&&R!evalPHFbA>NR?i;iI*208<| zx5v3fyi#d|X9gT>5prI@24oJ>p#4RKlycI{hwvcFN$N2mLfr}=jV%Rnz(Q#x5bc2G zgc)&K9%%|LJ9AL1q)gKCqgBA{rDirqi#nVrcd32BDb1u{*@VN4OTkeC7^j9{U!x8K zx<$2|NzY&4sA{577nKxR=?<%7v%`~+1xYCs6+8u^F|7=8!4OnVmc6kcgnhkytwT-r z&;L;HLHY97D~B9)kUs}g9^_yeZ6=$wq&rjR96~|9lH6n~vO2Be^Ah@1JMiVyt&xXs XfBWn2FBU%i?oaV=;KGgHZeI8wLhQ8s literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/61/780798228d17af2d34fce4cfbdf35556832472 b/modules/git/tests/repos/symmetric_repo/objects/61/780798228d17af2d34fce4cfbdf35556832472 new file mode 100644 index 0000000000000000000000000000000000000000..586bf17a49e63a07b4b491ab4306a90e79e49378 GIT binary patch literal 17 Ycmb)5VqjumU~CxZk>s%^VgAA^+WX?JKRG}7bG3bYo9Sv1Musbeym0`E C;u1~( literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/71/3fc38bac217f3909a1ca43479dec4f3f6e039e b/modules/git/tests/repos/symmetric_repo/objects/71/3fc38bac217f3909a1ca43479dec4f3f6e039e new file mode 100644 index 0000000000000000000000000000000000000000..fde71ec26c4ce49ae4ded40e8c4eb3f3c5094eab GIT binary patch literal 95 zcmV-l0HFVP0V^p=O;xZkXD~D{Ff%bxNMcB=V4tDXE52UWAQ+XsbOTG+3eQHqx&!MKppt0}S(!f-6u#asU!T_@{9nk()3|v%2LMcTBV0?c BD0~0_ literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/83/966f2fad7dfb1c567ca63bb68e9a7d38b4afc6 b/modules/git/tests/repos/symmetric_repo/objects/83/966f2fad7dfb1c567ca63bb68e9a7d38b4afc6 new file mode 100644 index 0000000000000000000000000000000000000000..50d57fceec5f7c2c477d75ef893ad3de1c8c6d2c GIT binary patch literal 1041 zcmWO0O>Em_002;kRkqoVK&b^~Z6%ZpL~N%`{5hFg;sefs#6Kx@wt`B00t$y6s(45+ z*_Y%NCma$9q0POtXcOsWI8B?BO>ey)!qU&^w18dPJ2&V+`3{R4rO{|C0 zfR56UhzL>H^&JeQ90sWd43d?Z9-JUB=mCet*X5+Y_Y7P%P} z1U^EiKsp+uBRqW+7E@;&8G8C;S=wF>Ev3Zu$H6DdOHV~|DHX~kuOR>2zP0gZaPIzt z&CUCpKR%cbemy_;_T2V|@mm${_}OLt^6&oL8TpOv+&3>SGgr4?|M=>^cV8&zHE(X_ z+IcRx9sJ_8dmAe&tE(%IK6u#t^7#1d&FeSjw{D#N_txC`{6_1i^N;Sm_wFYT=YKu> zw7GJ&b$b1Wnbp-tUtQ_`*21z1$<0FJkkO$!xt(kqDF$qGym*pN=o!>99sh|#l`bS8 zc)esl5IV53@}4=BJozGO?;6Bx3-j-rwn4HJ-5~Nq%jZzkkVS+tYIp+KzC38VZa~c% zm9Z_2Mtgn1RpFfs%5)B#3c@o3GSk91IfpkOUWP(k8N`uYPoYZqSi@acP1vD0E^1TfLiH4T zW(DRDxK>G+qB|lMfIKO{kOuSeG{eZbxOCn<-S)T?eimr!d<%t*C z={7=mH_!lnmdnCJA5;?DeF~*ioZa!-nxuI_6JvcuBF}re*}e&Rl(CY4oYC%(G>g+k zFB3;Sy|K)+krQK}83!TY&uAr|;wTP6BB3Dxad;CGB!=@F0eGa$+9#69S4VXRve>-F zNlekw+T{cRgo)PPGvcN*4hRuW;8oUzl)T?8sfnJOYhtwuC{?C~LI;t|qMS9As>}$} zvb~_WI9Guk3a3UE+rWM)f8Q2Gj{Yz_88~z0<<(KnPxFz4P7ge>|W0?EAlRr=C}gmCu*| E2Z&m|K>z>% literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/9d/36f18c8ca14ad28c4751afd14f3e3146a785dc b/modules/git/tests/repos/symmetric_repo/objects/9d/36f18c8ca14ad28c4751afd14f3e3146a785dc new file mode 100644 index 0000000000000000000000000000000000000000..d1ecb2995fe8d617198112f1486e9a77f20a8f45 GIT binary patch literal 999 zcmWN|U1;M3003Z3nRnNuC|l5Z>p;>|Y<{-2=_Z@agUy3&eyVG{dCd0BJAF_X=_z_F zFUecm_>h3eUHh`i9n=?1S7~Sal8W5g^bQhy5Sj-MHjurgjR(?#d;a*od69kcbTqRq5L^{J6>C6_xW@4MMcp}SXW506D<{6sCnGv>| zj+nwr`)DoWFYg#>$-=XaBvn ze6h0E`SIfYdvCq@@xzth&TqB1&+nXF|9)X-=h0_Z%-=h3zBr9=j!(FB^Ux^dKtk(# zK8q_8wQQ9QqZ?{TtfF@N<@q=OI*7R>QCz*0Y)4^CZ;o=%zP;dI0k>Svt+nCVDy8OK`><3G&W8mB zuaDINPa%deR|hSpI+B8Y#ggI(Z7&gnaoJbt8ZZ>GyiSRsWT~vT;rKXLvT_*SoYfR} zKG3FQD>Q3D4cVH@Ba@YM3_4=ars`poE7~4N9$8@Ct0D%49x)JKY{Q1#C5`~9r#6jT zWrEVFVAom&HQaWGT(=-p8Bx{xv!50tBVp*~!)i$gDtsi_tl~u3WOc6%m+X>$;58U1+FQ#hoNCw$i|dDWTRhQmB2ORiK# zbM<(@QhB|a#4$}iG^My+2R3qtP^wU& z2SdT9ApG(XbRFkC2iHx)s|Ym}L2EKI5T}8%L-v5Fp6~jFu#W-k0>RNR~XfTV8~C(N=+_NuuL&FOEa`cwn$DiG)YV`vPd>DH#JO5OEEM_ zGfp)&G%-sww=hjf<|?TyNL5JA&&|y&;R2ZfVd^@AIO(ZH3ht%FC8;S2HU;^`CAo>k pC80lwfipnZG1w(UFOG{G=b8{mFZ380%11>JO0RRNFElC43FggGL literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/d6/dfac318c3dcd5f05554472666d7bb6dfd9e8db b/modules/git/tests/repos/symmetric_repo/objects/d6/dfac318c3dcd5f05554472666d7bb6dfd9e8db new file mode 100644 index 0000000000000000000000000000000000000000..75ea7eaed6db6141e294197080367824117c706e GIT binary patch literal 951 zcmV~$OK95$007W=t<|BBgP=AsZ3JRSRLoJ_e8vQ;K@5v1nFZRWfrDbu!RmA|S;Amy zL6A_H88$IxSj_zhe6TBgV`lGto7xF}d;L1k z6*dYRcW>d_Wxl|i71qkkhwHbu*|nYW*{2(Y^{vfKX8U~W_W8!yv#p)&^5!oah4FTN z#ecc_+5YMZ!IZgY_{&woFXstnQ!PIGwTGB6+oJi zv6>4PX}hL-P>%8uF)Jkwkl|Vy&2&pe(~6arni@1|QkekK%x}!$%q%l#xMB{|M*=7j z{f03u#eJGNrH!E^0i!4Z>YUv-J);yS3Zd615}8G_)39T!RUk@O+X3jln>Ht-fDphE zri6~J$(n|seIADDM$Q{JD%Kg3z1Zde-yOJUOKnw3Xb=QcY#?c(-`5o@!lo^`-xfeI zjd)ncqse-S&(4{ghxwHzH=o(nvDhx67zM|s1))O%cHE8+$xa5P8?sAQS&M8K94>$w z=A}|>(gm8V4I#5>?2lC~6IobyTpzNL)0|Hrsu(ssZJgq}BLycRI+&s^EW%#Iu#Nzx z?7-sdZe7ywlq`o`WiUZBu?t9}T$^#?cD4;W3=^iUtSJt<9oph%!zt$bPLiG!F+&zW z?ntVdxC%@&Q8sL4+63OOM7=s;`*zzpB{a2$YWgUL%7a#nb2v4fW35OvI*5nzdd=4b zP|5m!y~~vny;H1KL~Rs|a`OO{j5;7W3fm)KJso&3q1t+hJsL@BKgW?`B4ZN>$!HiW zfSqsxG$3duHPULE>J6MB57m+oQan_FSjv%&AWh93XED%W`~fX^HAk|_N6 W@t=SHb-eQHK6#LO=O5&g@BRm#P_Z2V literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/e4/2ba3e77f66f623836b47df796932f7e5604aec b/modules/git/tests/repos/symmetric_repo/objects/e4/2ba3e77f66f623836b47df796932f7e5604aec new file mode 100644 index 0000000000000000000000000000000000000000..dc832f465cc5e26ac56902e15335090e40c7c3c3 GIT binary patch literal 70 zcmV-M0J;Bo0V^p=O;s?pU@$Z=Ff%bxNMcB=V4tDXE52UWAQ+XsbOTG+3eQHqx&!MK0Pmp~mDCg+g#Z8m literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/symmetric_repo/objects/f2/ad6c76f0115a6ba5b00456a849810e7ec0af20 b/modules/git/tests/repos/symmetric_repo/objects/f2/ad6c76f0115a6ba5b00456a849810e7ec0af20 new file mode 100644 index 0000000000000000000000000000000000000000..a36463115dda02dbe173a6aac45d5809783e8e1b GIT binary patch literal 17 Ycmb= 2.28 now returns an error if base and head have become unrelated. - // previously it would return the results of git diff --shortstat base head so let's try that... - diffPaths = []string{opts.BeforeCommitID, opts.AfterCommitID} - diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...) + diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = gitRepo.GetShortStat(opts.BeforeCommitID, opts.AfterCommitID, !opts.DirectComparison) + if errors.Is(err, git.ErrNoMergebaseFound) { + diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = gitRepo.GetShortStat(opts.BeforeCommitID, opts.AfterCommitID, false) } if err != nil { return nil, err diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go index 64d3e5887d..3ce6a3413c 100644 --- a/services/repository/files/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -358,7 +358,7 @@ func (t *TemporaryUploadRepository) DiffIndex() (*gitdiff.Diff, error) { return nil, fmt.Errorf("unable to run diff-index pipeline in temporary repo: %w", err) } - diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(t.ctx, t.basePath, git.TrustedCmdArgs{"--cached"}, "HEAD") + diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetIndexShortStat(t.ctx, t.basePath, "HEAD") if err != nil { return nil, err }