From bb694684a4045150924c15aa5647e8e112321f02 Mon Sep 17 00:00:00 2001 From: Gusted Date: Thu, 14 Sep 2023 21:53:57 +0200 Subject: [PATCH] [GITEA] Detect file rename and show in history - Add a indication to the file history if the file has been renamed, this indication contains a link to browse the history of the file further. - Added unit testing. - Added integration testing. - Resolves https://codeberg.org/forgejo/forgejo/issues/1279 (cherry picked from commit 72c297521b1830360aab4b50e37efcc7e67e0d5d) (cherry picked from commit 283f9648947f8dd2f315ecca19566ccca2b49c18) Conflicts: options/locale/locale_en-US.ini https://codeberg.org/forgejo/forgejo/pulls/1550 (cherry picked from commit 7c30af7fdee08efd02041c01abca47394a69bb8b) (cherry picked from commit f3be6eb269526a9f4ea7861189f07977f2d4a32f) (cherry picked from commit 78e1755b94c18c043e0c8f8c2849803cc8069feb) (cherry picked from commit 9f30b92009e8911c99412944bcd7cff55a7b98dc) --- modules/git/commit.go | 56 ++++++++++++++++++ modules/git/commit_test.go | 27 +++++++++ options/locale/locale_en-US.ini | 2 + routers/web/repo/commit.go | 16 +++++ templates/repo/commits.tmpl | 5 ++ .../40/8bbd3bd1f96950f8cf2f98c479557f6b18817a | Bin 63 -> 0 bytes .../5d/5c87a90af64cc67f22d60a942d5efaef8bc96b | Bin 50 -> 0 bytes .../88/3e2970ed6937cbb63311e941adb97df0ae3a52 | Bin 49 -> 0 bytes .../8c/ac7a8f434451410cc91ab9c04d07baff974ad8 | Bin 120 -> 0 bytes .../a0/ccafed39086ef520be6886d9395eb2100d317e | Bin 102 -> 0 bytes .../ab/e2a9ddfd7f542ff89bc13960a929dc8ca86c99 | Bin 36 -> 0 bytes .../cd/879fb6cf5b7bbe0fbc3a0ef44c8695fde89a56 | Bin 108 -> 0 bytes .../d8/f53dfb33f6ccf4169c34970b5e747511c18beb | Bin 784 -> 0 bytes .../f3/c1ec36c0e7605be54e71f24035caa675b7ba41 | Bin 48 -> 0 bytes .../repo59.git/objects/info/commit-graph | Bin 0 -> 1292 bytes .../user2/repo59.git/objects/info/packs | 2 + ...d3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.idx | Bin 0 -> 1660 bytes ...3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.pack | Bin 0 -> 6316 bytes ...d3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.rev | Bin 0 -> 136 bytes .../user2/repo59.git/packed-refs | 3 +- .../user2/repo59.git/refs/heads/cake-recipe | 1 - tests/integration/repo_test.go | 30 ++++++++++ 22 files changed, 140 insertions(+), 2 deletions(-) delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/40/8bbd3bd1f96950f8cf2f98c479557f6b18817a delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/5d/5c87a90af64cc67f22d60a942d5efaef8bc96b delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/88/3e2970ed6937cbb63311e941adb97df0ae3a52 delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/8c/ac7a8f434451410cc91ab9c04d07baff974ad8 delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/a0/ccafed39086ef520be6886d9395eb2100d317e delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/ab/e2a9ddfd7f542ff89bc13960a929dc8ca86c99 delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/cd/879fb6cf5b7bbe0fbc3a0ef44c8695fde89a56 delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/d8/f53dfb33f6ccf4169c34970b5e747511c18beb delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/f3/c1ec36c0e7605be54e71f24035caa675b7ba41 create mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/info/commit-graph create mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/info/packs create mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.idx create mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.pack create mode 100644 tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.rev delete mode 100644 tests/gitea-repositories-meta/user2/repo59.git/refs/heads/cake-recipe diff --git a/modules/git/commit.go b/modules/git/commit.go index b09be25ba0..bc22d52b45 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -509,6 +509,62 @@ func GetCommitFileStatus(ctx context.Context, repoPath, commitID string) (*Commi return fileStatus, nil } +func parseCommitRenames(renames *[][2]string, stdout io.Reader) { + rd := bufio.NewReader(stdout) + for { + // Skip (R || three digits || NULL byte) + _, err := rd.Discard(5) + if err != nil { + if err != io.EOF { + log.Error("Unexpected error whilst reading from git log --name-status. Error: %v", err) + } + return + } + oldFileName, err := rd.ReadString('\x00') + if err != nil { + if err != io.EOF { + log.Error("Unexpected error whilst reading from git log --name-status. Error: %v", err) + } + return + } + newFileName, err := rd.ReadString('\x00') + if err != nil { + if err != io.EOF { + log.Error("Unexpected error whilst reading from git log --name-status. Error: %v", err) + } + return + } + oldFileName = strings.TrimSuffix(oldFileName, "\x00") + newFileName = strings.TrimSuffix(newFileName, "\x00") + *renames = append(*renames, [2]string{oldFileName, newFileName}) + } +} + +// GetCommitFileRenames returns the renames that the commit contains. +func GetCommitFileRenames(ctx context.Context, repoPath, commitID string) ([][2]string, error) { + renames := [][2]string{} + stdout, w := io.Pipe() + done := make(chan struct{}) + go func() { + parseCommitRenames(&renames, stdout) + close(done) + }() + + stderr := new(bytes.Buffer) + err := NewCommand(ctx, "show", "--name-status", "--pretty=format:", "-z", "--diff-filter=R").AddDynamicArguments(commitID).Run(&RunOpts{ + Dir: repoPath, + Stdout: w, + Stderr: stderr, + }) + w.Close() // Close writer to exit parsing goroutine + if err != nil { + return nil, ConcatenateError(err, stderr.String()) + } + + <-done + return renames, nil +} + // GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository. func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) { commitID, _, err := NewCommand(ctx, "rev-parse").AddDynamicArguments(shortID).RunStdString(&RunOpts{Dir: repoPath}) diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go index ac586fdf09..a095ac9844 100644 --- a/modules/git/commit_test.go +++ b/modules/git/commit_test.go @@ -278,3 +278,30 @@ func TestGetCommitFileStatusMerges(t *testing.T) { assert.Equal(t, commitFileStatus.Removed, expected.Removed) assert.Equal(t, commitFileStatus.Modified, expected.Modified) } + +func TestParseCommitRenames(t *testing.T) { + testcases := []struct { + output string + renames [][2]string + }{ + { + output: "R090\x00renamed.txt\x00history.txt\x00", + renames: [][2]string{{"renamed.txt", "history.txt"}}, + }, + { + output: "R090\x00renamed.txt\x00history.txt\x00R000\x00corruptedstdouthere", + renames: [][2]string{{"renamed.txt", "history.txt"}}, + }, + { + output: "R100\x00renamed.txt\x00history.txt\x00R001\x00readme.md\x00README.md\x00", + renames: [][2]string{{"renamed.txt", "history.txt"}, {"readme.md", "README.md"}}, + }, + } + + for _, testcase := range testcases { + renames := [][2]string{} + parseCommitRenames(&renames, strings.NewReader(testcase.output)) + + assert.Equal(t, testcase.renames, renames) + } +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index f47f25e2cd..0f9a154088 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1278,6 +1278,8 @@ commits.find = Search commits.search_all = All Branches commits.author = Author commits.message = Message +commits.browse_further = Browse further +commits.renamed_from = Renamed from %s commits.date = Date commits.older = Older commits.newer = Newer diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index a6eb7efeb0..fd47aa5ba5 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -239,6 +239,22 @@ func FileHistory(ctx *context.Context) { ctx.ServerError("CommitsByFileAndRange", err) return } + oldestCommit := commits[len(commits)-1] + + renamedFiles, err := git.GetCommitFileRenames(ctx, ctx.Repo.GitRepo.Path, oldestCommit.ID.String()) + if err != nil { + ctx.ServerError("GetCommitFileRenames", err) + return + } + + for _, renames := range renamedFiles { + if renames[1] == fileName { + ctx.Data["OldFilename"] = renames[0] + ctx.Data["OldFilenameHistory"] = fmt.Sprintf("%s/commits/commit/%s/%s", ctx.Repo.RepoLink, oldestCommit.ID.String(), renames[0]) + break + } + } + ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository) ctx.Data["Username"] = ctx.Repo.Owner.Name diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl index 42004c2610..b3d983029b 100644 --- a/templates/repo/commits.tmpl +++ b/templates/repo/commits.tmpl @@ -13,6 +13,11 @@ {{template "repo/commits_table" .}} + {{if .OldFilename}} +
+ {{.locale.Tr "repo.commits.renamed_from" .OldFilename}} ({{.locale.Tr "repo.commits.browse_further"}}) +
+ {{end}} {{template "base/footer" .}} diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/40/8bbd3bd1f96950f8cf2f98c479557f6b18817a b/tests/gitea-repositories-meta/user2/repo59.git/objects/40/8bbd3bd1f96950f8cf2f98c479557f6b18817a deleted file mode 100644 index 567284ef1c21f472841f3d729cbfe024d78c448c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63 zcmV-F0Korv0ZYosPf{>3XHZrMN-fAQ&Me6)6NNXyJgE!N}W0ssfX5``$?8bAO5 diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/5d/5c87a90af64cc67f22d60a942d5efaef8bc96b b/tests/gitea-repositories-meta/user2/repo59.git/objects/5d/5c87a90af64cc67f22d60a942d5efaef8bc96b deleted file mode 100644 index f23960f4cc8c09af29fc4765f683b697a4547d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50 zcmV-20L}k+0V^p=O;s>9VK6ZO0)@QP;*!j~bcW9d-8WL<+jltv I07;Az9utceGXMYp diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/88/3e2970ed6937cbb63311e941adb97df0ae3a52 b/tests/gitea-repositories-meta/user2/repo59.git/objects/88/3e2970ed6937cbb63311e941adb97df0ae3a52 deleted file mode 100644 index 46cc9e3e5ec14999b5424f35c1c548db9e9e33c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 zcmb7FlR6{FfcPQQ3!H%bn$i7%S~Z$=-z96@n>ehkMsI7j#P%$ zXG=6znHT_pLP~0C0Yhv|`%12FKF8{nu5nG#jr;Y!`(!rMjI`9mlG377y^@L&h7LQ; ag14FGr?(jkzI0r>v-ZO}s~`Z9QY~(zy*Y~j diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/a0/ccafed39086ef520be6886d9395eb2100d317e b/tests/gitea-repositories-meta/user2/repo59.git/objects/a0/ccafed39086ef520be6886d9395eb2100d317e deleted file mode 100644 index 3b71228a7ec7b91f1066cda387ef6efa28c2ae68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102 zcmV-s0Ga=I0V^p=O;xb4U@$Z=Ff%bx2y%6F@paY9O<`F5Xyx6%^&$E{W*@XnSgCoZ zXGP9TsG{Q3M6>2AdT%A&7_dRgi_+j`HiK;pmmM?MU`7Mx>)%bH?6OHM zk5sBnouqA=Y63LcbH7YOmH|GAl4Hc@EW@%K&C)1I1Uia^1hFYP#!;RNM>a}%Dtb?4 zJAn6?4K(;YO4A`5NBYlfjhe2`eoNZs4?rJ;J;Mr|fWQvz5u(27_uQ2I-(JxbV^x4( z|B6Ty%>s_%fUBlh_~u>6-<$#zs9bFmF%~6^Q@J9f=}|(LabtH3q_NxV$YbR02+h-Wy>8SN zL-n>NnOHxD1_ktBKMTFMF~Oeo44c$Nx1zjPg-n1^s{~0y49o8@?{IqT_1l9FDBH+tz~X}{gyB7!qm$KrCW*^)AW)NzRtpG4}}%%=|SNs z@Nz?3mnX@zAyYKZV*tH#nR{bxS}d9i?M(85HRz`|j6_MUVShjg2W|Ppe8h&7*MdL7JHfOBCJr|RNl?>o$nk$Jg%Kk7Ay z>ilZ^!I!SZjq{9}32tH%t54`QEQTUns*)fL4hA0LId@WGsHUmmoZfJs-`Nc O!MB&yMEwL3??r>^yMtc< diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/f3/c1ec36c0e7605be54e71f24035caa675b7ba41 b/tests/gitea-repositories-meta/user2/repo59.git/objects/f3/c1ec36c0e7605be54e71f24035caa675b7ba41 deleted file mode 100644 index b6803eb5a271b9d33c981d1ba24fa4126ae409db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 zcmV-00MGw;0V^p=O;s>9W-u`T0)@2voRrieh6QKVzqRDZ`>L=nqwS_;+$I5D!#V&X Gkq<4~#T1zU diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/info/commit-graph b/tests/gitea-repositories-meta/user2/repo59.git/objects/info/commit-graph new file mode 100644 index 0000000000000000000000000000000000000000..d151dc87e63b6d2485029740163c1cd02c7d41d0 GIT binary patch literal 1292 zcmZ>E5Aa}QWMT04ba7*V02hBx7as_d#l_jhF$BtPaCdPug0kO0Xb@oefncKmMh1pa zJVL^NiGg7h(=ZH}85jmHW?h@{I>e{p(Ilthmpdg4+k&d68a3>&iD^GR*29GUEs@6-kthJjovw(qt z0fa$?ODYTdPBG7N8}{FP{e}xJ^*DF4@~4^}JO+}4s^LgwVZYR~rmElBCD4)Qq}0v> rzU;gHPxrckY);C3lW7nmAz+1fOPj{y?c!V|&P9^bzsN*Ih1385j^ literal 0 HcmV?d00001 diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/info/packs b/tests/gitea-repositories-meta/user2/repo59.git/objects/info/packs new file mode 100644 index 0000000000..0374746b5e --- /dev/null +++ b/tests/gitea-repositories-meta/user2/repo59.git/objects/info/packs @@ -0,0 +1,2 @@ +P pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.pack + diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.idx b/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.idx new file mode 100644 index 0000000000000000000000000000000000000000..aaa9981cf5982e0cdf26f13d8095020ce465ddef GIT binary patch literal 1660 zcmdVZdn^u9rIRJDW#p>EWg$d3ETh>B!x>GS`dB zJT8~eOLeMSlu9vE%_PmcnDh`5lcxS@tMpiF_1ixG{{H(;#CU}QP{X%34ft)7pOdEl zC)9yIN(1;IP2iuQ1x!gBfX){Pz?5`>@6rRlVgP(X1b&DF{1t}4l#GC%HUs!A#=tK# z0e+1}Nmw6;ozjuHEV@@owGsIy$`%?2DHli2-@?^bt(c|KjVb80;JhKb$2)0_8Axq% zA4phY4dQ0|%G<8u>q{Em^Snpu8AomjxXIzv-3c83(fn?;)VWxFu^^$$G_}Mf^XR(Z zGzDRpeLHz}BO%KwWb~D|COqYeQ}7=1o2QwYZMz55@=p1?+!ds|SZ?pv9^o5s$>=&js}Blk!-x@n19od z^O)^$?I1bF?yzo1Osrw0xbNBVj_mUdjjXj|%hLG3rm8N9-@&()FBaW+z9FdFGit!q z{+>Mca)nzY$=iEO7C;}E$#boy-tn@tBX+UM|M)|wRte&tJ(frBH~~P0961`M1V;HKr95v-2i0=pt%a5)B`#kfYJ{b)c{l}K)%Xo002M*005-9a?spNm}*^>5=rFkBhC%0mw+(WjuZykASj2D zs&4`hY2Al`=5T-QMQnd7T(QGqn3taHe2iUWs`{Srf-Ou8Q(+?D2A^L`3&V2oJ$ftS zh3zPUcy=}DLTc)L2RL2h8|$kI;HwzX@K2Jm6yNzLN7IL86BY7H{+@n!4Z4>~%`biV z0XEf+4u67i-Xf|-PMww?AKxmYW{5I+38IMt$_d;my%=BSjUfX%q*orHE_GB0&Gu+@ zEQAfm#=!i`28rhHOt5>9;$l^NIyJk6hb5i8`idxZx1C7M!T__@e8jxVU7;ZP#}r#d zuKcyo+~Vu(^K+KsNvrSQEI%o+QrUjxA=#BaWo=iLae;`bJ;*H--0og+{ zTeg>HF8z0=6ol#-*1Ii2C+XOEaZq@#`Wi!7Ion+* ze4fq3OV{`m#gWpSTWf0XL`V&%YV6Dfy^owk&&bfbe=FdXbN4gEB>Rm+ZkPvRS~?g+ zEx+qcKrNeSdNGmOT@$_8CDX0l;;0&TP8_0hMG$<5bGVM&Z@#G-(1~#_8ftQ>=mzA| z>Exunhvr7XhH9%!2o?8&F??q5upS7%-kN=k)uPbgwZY6nW8QQ5bF`f2z~zgV)mS=J zxpW!JhnVxMj#gS;MajJH2VctCRNWs*7|nUvsBrnO_TjDaQe&WF)Z zW?faiMP;vgJ?&`m&?=V>yB?bBk4>+t#5#*(=!UtA+mSwaOdz=~)?(B*HTi5cMb=chH4E zrqF>~zr+tZ3)5Q+r(>F+X0W?a)icO-B7=<^7jZ&XGrHj1?toxx67GoV#0-^8{K-2{ zkzp;L_MlVKUfdcsNh@&q~3AL1&A-ygi;_b=NF~-f)iE{s)?l;}}3pG)#dKAB|ICtAZTigbXRr6b)C6FE>u= zA5*PuRLipuaQ*Q{qSMz{`tcG80DnzdhrmSyYa*u>zQZW=nX9SkJVO z`PHZPdvav}YGGADI;&be>n?eDkb+Xq4YkdsgPJ9adFqMassvV-e=rcGdwDkHziKmwoF3u<>QpE+ zb%_N$kAvO2T2URayjs$+X<2nbobtPaOsVnYvRVU>0aMDywfUKbiRe#NL$pXV6y>_L zth#t;jLF-2{7ax7OpH68G#A^c^h|N|IaYJzWK4b48vv2bW2UCQ09lxsO4^uG0b6(pa1 z(Azz9<=}lqbXF@E-`7L9B*AXe$0f*TEKzU+F?h1hgpHf_gKJ%Q@Ai7}NaLxkE}cCw z@(yA0viwyas*T{KZoHZn(z)A6zkCA5m0!GmO80ON4mfm)1I)XoG~i32T5dHI@3Q*cyrfIIcxM>MS*_f8KsKbRrQJE0xQQv zi8)>VKRs%szC?*c;Wk+D1Uo07JT?R$S2tGfHL)C8yDc}LHu3(^Lz6_u<)D9n`v-Ua zi3JvHoezqd*lEO3oB^%aPZMEug{p$6I zXnFz+KBISh5#Fe;b#=O}fbhYNgI+<#PC!Vi=wFx(;j@;5UX%R=c*Y&xRhXwCr**+bhs@t!Ie@OKb{X6>yJ`Ag#S2GANHwUP4OjPhufy_r?c za7bB>#%RcBGcpD4MetThow-P_#V9icIAB%NuzAG;2Cy&o2KspFW19r|IeyJK-tbZ? zI7vkYO<1N(>a!0I`WFBCl$(^a^a#adJJ@*hIRgdF1E1)Mwx!l`!rbTnYKVlzS)aQg zSid%<+1BE1RrCX~8V^d@sZb19|NB$MXD!z`;P9Qqe6C*z_ekgD5}|R-B}h0~NJ>rD z`7bm}V#EmaYpg5{A;{xP?CDZ^n#JI$oWfgZEHVn6!H#Nc9^=q@a`o3GD(~A&26YbR z+Q-|c#JkxAO)mCEQQQ&%HikDdXr4L3e9IYikK@6pL zGt1N0CwuwCI`@evMIwuvS5&{Cc#MRDL${!IK(_T{zIF96`irk-HXNRM z5Vj{pvi1XZslO+h334}sfaPX{u+Ktp=yyBkDF!7Hse1QQ?{-B|tX22qryl@B(CjcGv$bj-mPzBa;8bMqZWcj}MhA7MKbo zcSQMuTj`O*s>H#a_U)2Kag&~TOF@nE;^Y{Fj{TkxlmN0R5?N23LW*!3ABC@C<`)>U zS)kE(C{)v}`^I#IK>Ak!`DHlqg^tOJv4nK+21+f8hGCpR{SSI;V! z!Q7uQo=rQZ-CYyb8;TyV={SOM=m^9-8B`*Aq#LW|oBnmTI#+*gL+yV0m|jeYe!oF}0tDmg(KBBax7oH2D#xu6*TDnPgP z&5KMjN~zTO6E1k*AUKC!4X=jI*w?J{eLGpR2U$`_Zpo#Xu=hE?+~Qc5>R?mVsW=;X znHzVtz+liF)(-Jsr_oR%8tC|Ndj@y|D^(7t?TTqUzt60Q?tr{TQYK-Zo&F)Rg_-OBd zH{e$1xi^|EF`0?$1VP&EQ7kxBf9KO{-GZ6vbt##)*6@7SOn#f^&x>3WR94hycWf$`>ayAX_pcq4*XcK;=hPreL&nn#I-ma3(8#W0M$ zm^Lk7n@G!ZY4hc9;8=I9U|YGbVZ3H(f6QX0z{&!qYEu{~RdEw%dQIW@`>aU><23nM zmtg7xgy%4z8fB;esI?FkQ|2}3qF$dadBb^T7leC#6))m$Ss!@ol=@py(6XaSLR;n) zVtH|7W;8xV*K-Y#Ja^-Vy%|#yC}JgMX^ZU!GZUAm{@h&p=B|O&-|B-@Yk$oGwZ4tR z!CPL_vyUFLA4=!-uZ)VX>4Aq;Wi@Bb=$V}jrx{PsJtUdfIxpc-@D9ExI5I`43(R8b zCv~L|S1gRhCy@)KrdAFJnVkC97{CDe_>6@a5<8M>{UTl>x@SfCsp6Wd`a#q>6lDlq zTLktVn(GD|sVy-ADBK1QteQLRsvai4;e}DUGTQ|Wjob55{II^f4hT^7t1vuJX<|Fz z)YlD*9QNiXkCQ7L%|OD^>AjOT6=hZ6dL)!>U$N;o1UO~Yr8EG@0fmSH)qL#%NmzG+ z|5S>_`8%q68I+MY5@c+(N*J0f5&Df{&=1Z5bci62B7R76U&qymaY2aj`u@;ELnser z{<{FRM}O0#Ss=&R(0ZETDx_DjJFI8Mf-N!lI>!!x_DjIuH2s5Ox;I{>^9uuiz1G8} z%GP#B^;tXIp&;H!LKb$fk}0gLS2_2PV)y>UvuM>*Qjme>rmaZgpoCF**AvKQ2j&l2 z`Z-0=I6Rvn9&c=#iRZx-=l7LK+`#AJ!w6_>I6VCl6leWaaI>#9HWg2Rrh9j~BTZLw-NVxyI`Ly& zM>w#p=*KqLeuTYKNPbtMIw2hDPXRxnQs0&LvcvFM=@83lI`$i?$knb<)VKaArSI)D ze6&iFg>TIKn|<_#;(?q1EvZ~UXR&O+hNV3)lR-q-FL&U~w0ewJN0*B&X#B@CYq_yH zt)SX;3gUb2+VQn>BPymRwy(uUGn>%|Dys<#yG~9wSIKQrFjo%SL(?}VYNA)}aFc3QO7AUN zmTYNpTyGVje+uLlM< zw%5hRjQTLqTIbm^*-cGd&6-`S0?yy8vbl(lstFp-%4`xzL36H{`)=jj52DcyX=z)f zcoVfTr7<06P18mfn!x!k4x5;5q6kb$#NIzwqebT*{#8F^bX}CmTir!z?7Ml-a08Db zp0*MXXw_R6MQuN`(?txnl104Q{VP z6ygU&78YtSTwLA34E+3I9s!kIt76md*$5jLmsxCkeI$9lNhZ{5*uo4(2@6U-W|KrU z?!iDG(&r7Nu+H8b^hC&{OVaL()`w0pIkiVW=SwXYgsrNYCugB!hvO|V^aoEj=QH1j zhT0n^`(lSY1o8g{VnMU9CZc!$sCzQJcw+Jv-Xs|gni%m;%x0%HD^r@6)+~FaS`aWj z@=qP>dw(S|T(QI%di<#taQm_aq{EXGm(CD8y7EpmNkAvX^hvkv$~^8j{^s2qvq`-~ zKzyS`3Mn~nzOwFw#S!Q`^7SM(H_VK2kh|UWc&qCB;j#x>6ccOYn`Jchd;i2w$hStw zcCYoTXx`-W6fS=SVZl-A)GxVLS?v9hu_7BA!+GaA1XxUejg?~x@HV=e^8-5V`^T+^ z$&&&Ftd#zVhA444Ch!oFHR0sBgb7Csi;zR?m#NcC&D}mcLEYH&!`_$oJi+ zEeJF@w=vB4XzAgA`3k$^Bx<{{p>fk}_-KB_xN_B-dmArvrM9{BURLmn{`!uIz`0wd zK?O|N?(^~KNT40ybDxVA*wFoK;1^hxN5*!?=2D(ZDmXsVe92+9I2cI;UX~U9Iizd0 zQUodHl5k`|qX|jOIV@b@-X6W_O0o8=j<N-R0q##vv7Yob7X}5A_ib`* z+Q-ue%jH9Fk1n?s35vYAdE~5xK#;Ts1DPt9#y{sygs)dKPOQah8vCdk#K}CA zBy)gaUaP?!ZL;+y70SZy|Edc!@=2?zp8P}75>)x=9wV-Ux<3g`jZ|0Vlim(;mBqsa z-dn5&?R9$uHPBiVoqdqMZICC$H162(-f)|_RJ;~0Wu|fy*1kl%lc6|!_ukR^*)3W$ z#)`CWCMB>Eh8b*ZtUYeUBO*s!hzrdX5ai_*;M0BO?F%{gogLG(@!Vf?`FIX?=t;S} z7f3dUo&&238o?<5;c{xu&M5M(8V_o<9@0aHnYCV;zmp!WyB z#}h~6OCTd!;Jalll(=0GPX_L~AMb!fPhzcqp@!xYKF!pf!9E>S*q1K*i=hI}(+Kv8{ukT$n42-f z5RCzz>u%Z}eyIG$Q*wf^UtvbE>=Oqd&w#h(82^tZCQpt#tKHZ1_c9K&jT$Bu0cBvt z2@Uz!;?0@u;+gb+oBdPUGyjTbw#Os>M}dZu%a**9+O?tXq4?7T?d6$n9)~Ct0N!V& zl~a^(-~XmJCR${`P$!yM^#4=reFa1~MbQ5*6tW4#1`ze4McYRR{pa>Yik=F9sfbF^ zjS9`xH+rSUHOw=?Il@zEz&gn}qN8Gfx_S7$RC*49@U8&~C;+uB40 zWNs0fH=_La{nROE1)gtOCpJ;Q3h?CwcFB%P(N;nc@KTsV0YxklS8r~T z!#%ti3?}7l6^xC5F@)F?xFB(tO&MFiqe62pRk+j)d5l;mCN&LJ)HONTxYP_)RJpXc zM>$zX#wVw@Pyu6?xDQg$+{+OSEhLAQ;qbWn*d8i?{ttRKFEkeo0000`+@=xFuT!Y~ RH#E3il3itYY8lzr{|kxUI}!i@ literal 0 HcmV?d00001 diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.rev b/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.rev new file mode 100644 index 0000000000000000000000000000000000000000..81554dba7405b86a5e8db6c52a81b9c6590b0f0e GIT binary patch literal 136 zcmXZQs}4Z{0D$4o{eC^FL?MW}O<|JF<{dEc6hYH?0#!KSyo_oyL6Kz>__we8^T~LL z#9!90D(e4NLK8(KkwFV(q)|ZuDb&zF4tWHd>*W)i+Tmk1SRL1+XWZ@Ir>$V07@j-5 NC|VqLarl01Z(m%N6!HK7 literal 0 HcmV?d00001 diff --git a/tests/gitea-repositories-meta/user2/repo59.git/packed-refs b/tests/gitea-repositories-meta/user2/repo59.git/packed-refs index 114c84d2aa..77fedbf67d 100644 --- a/tests/gitea-repositories-meta/user2/repo59.git/packed-refs +++ b/tests/gitea-repositories-meta/user2/repo59.git/packed-refs @@ -1,3 +1,4 @@ # pack-refs with: peeled fully-peeled sorted -d8f53dfb33f6ccf4169c34970b5e747511c18beb refs/heads/master +d8f53dfb33f6ccf4169c34970b5e747511c18beb refs/heads/cake-recipe +80b83c5c8220c3aa3906e081f202a2a7563ec879 refs/heads/master d8f53dfb33f6ccf4169c34970b5e747511c18beb refs/tags/v1.0 diff --git a/tests/gitea-repositories-meta/user2/repo59.git/refs/heads/cake-recipe b/tests/gitea-repositories-meta/user2/repo59.git/refs/heads/cake-recipe deleted file mode 100644 index 63bbea6692..0000000000 --- a/tests/gitea-repositories-meta/user2/repo59.git/refs/heads/cake-recipe +++ /dev/null @@ -1 +0,0 @@ -d8f53dfb33f6ccf4169c34970b5e747511c18beb diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go index d044174df1..2ac1632188 100644 --- a/tests/integration/repo_test.go +++ b/tests/integration/repo_test.go @@ -690,3 +690,33 @@ func TestDangerZoneConfirmation(t *testing.T) { }) }) } + +func TestRenamedFileHistory(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + t.Run("Renamed file", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/user2/repo59/commits/branch/master/license") + resp := MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + + renameNotice := htmlDoc.doc.Find(".ui.bottom.attached.header") + assert.Equal(t, 1, renameNotice.Length()) + assert.Contains(t, renameNotice.Text(), "Renamed from licnse (Browse further)") + + oldFileHistoryLink, ok := renameNotice.Find("a").Attr("href") + assert.True(t, ok) + assert.Equal(t, "/user2/repo59/commits/commit/80b83c5c8220c3aa3906e081f202a2a7563ec879/licnse", oldFileHistoryLink) + }) + + t.Run("Non renamed file", func(t *testing.T) { + req := NewRequest(t, "GET", "/user2/repo59/commits/branch/master/README.md") + resp := MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + + htmlDoc.AssertElement(t, ".ui.bottom.attached.header", false) + }) +}