From ea23594cdbb12c32dc28638f65bf40e37d344e5f Mon Sep 17 00:00:00 2001
From: Gusted <postmaster@gusted.xyz>
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 73799479e0fb68534dac10f809ee246dbc809b62)
(cherry picked from commit 938359b94120b7ea7bcdfbfda265ada691620da1)
(cherry picked from commit b168a9c081f93c10d40319333fc24d68a4f9763c)

[GITEA] Detect file rename and show in history (squash) ctx.Locale

(cherry picked from commit 40447752ff97aa306295685dcf4ddd3b13f48320)
---
 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 ebd5171f80..a8c00bcb49 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1280,6 +1280,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 3587d287fc..f8508dbf68 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..7b3b27af1d 100644
--- a/templates/repo/commits.tmpl
+++ b/templates/repo/commits.tmpl
@@ -13,6 +13,11 @@
 			</div>
 		</div>
 		{{template "repo/commits_table" .}}
+		{{if .OldFilename}}
+			<div class="ui bottom attached header">
+				<span>{{ctx.Locale.Tr "repo.commits.renamed_from" .OldFilename}} (<a href="{{.OldFilenameHistory}}">{{ctx.Locale.Tr "repo.commits.browse_further"}}</a>)</span>
+			</div>
+		{{end}}
 	</div>
 </div>
 {{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<s#GY?EXhzvR7lB8OG_<E%_~vJ&df_G
VR>)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-<TbEo)G=iuke$D>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
zcmb<m^geacKghr=?SqG|SEzoN#<}ypp&s78I-0s(p&p*PetM^LG)|s5fB7*JgWNSf
F1pvu25=;O9

diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/8c/ac7a8f434451410cc91ab9c04d07baff974ad8 b/tests/gitea-repositories-meta/user2/repo59.git/objects/8c/ac7a8f434451410cc91ab9c04d07baff974ad8
deleted file mode 100644
index 5a1e79326f2c2ee1a4c451167389f5096eabdf72..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 120
zcmV-;0Ehp00V^p=O;s>7FlR6{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{Q3<f7D)_~OLU<ka}0)a1;9RK1dl5{9$w^S7OkuHMJL$BOTZPutYLFJ^@S
I0N_g~9D6=E761SM

diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/ab/e2a9ddfd7f542ff89bc13960a929dc8ca86c99 b/tests/gitea-repositories-meta/user2/repo59.git/objects/ab/e2a9ddfd7f542ff89bc13960a929dc8ca86c99
deleted file mode 100644
index dcbd3b3eb9f03f5d60d082bd174cf3e8d07c6e8a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 36
rcmb<m^geacKghr+As~$7q(`WRpRb;mZlH#rj;~+n6DEer296E@-c1XM

diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/cd/879fb6cf5b7bbe0fbc3a0ef44c8695fde89a56 b/tests/gitea-repositories-meta/user2/repo59.git/objects/cd/879fb6cf5b7bbe0fbc3a0ef44c8695fde89a56
deleted file mode 100644
index cd9cea6797da4bacfae03d6da3b053b81d969db2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 108
zcmV-y0F(cC0VRwv4udcd1XKGJ+abA#LWg(<d4O#eumBtRE|K_sPD(jDtBFUA=wHKQ
z+6ZB4R5Yf1adggmyi14&p%t^q`_d8rXPMbLvGto1u?0b?YK5Zs2-IpjZ^2TVK^B}8
O2`iuQ-u(dQ948US(J)2;

diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/d8/f53dfb33f6ccf4169c34970b5e747511c18beb b/tests/gitea-repositories-meta/user2/repo59.git/objects/d8/f53dfb33f6ccf4169c34970b5e747511c18beb
deleted file mode 100644
index bea28c9f69b13925696567043b55ee3a544ce94c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 784
zcmV+r1MmEJ0hN=<uB%1>M6>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_<N6zqB~{6bz|(
z88^4w(!a1&Jl%ge1xO9gmJ0>NxV$YbR02+h-W<i4Z3HuNB`n?WDPMf^Mf~0>y>8SN
zL-n>NnOHxD1_ktBKMTFMF~Oeo44c$Nx1zjPg-n1^s{~0y49o8@?{IqT_1l9F<ml+Q
z9C}RBeGn<|zST=%w;6q?N4)b-XXc8BYB)(@zga5$><Ig{cl7%sA$kIRHm~J}{?`20
z`NP{m$x&d*S7)08xz__Sb<D?XcDfv)v6OGKxlD#%XJSAuT`t5cYAfG8x2j*Vewi12
zTJ2^Ea1neQx#)5*l>DBH+t<aF%ENli#a$-YU1bW@izqP7T$`cw$TekB##S1PNpyTh
z+k*mF^zUgl%VLdhnmP+=@!?Ac>z~X}{gyB7!qm$KrCW*^)AW)NzRtpG4}}%%=|SNs
z@Nz?3mnX@zAyYKZV*tH#nR{bxS}d9i?M(85HRz`|j6_MUVShjg2W|Ppe8h&<LkhU9
z`dWpstae%^_i+Gs#s*K5<(k3j78iSEG>7*MdL7JHfOBCJr|RNl?>o$nk$Jg%Kk7Ay
z>ilZ^!I!SZjq{9}32tH%t5<moRy?*E(a}TN4~8WWew8kHGc1@^G5^rQS*HLDtNP<q
zH4^z!KGR{%CV7@+SIOuqcS&zzJ_#CxU$9z^2UsDM%&P1dVXr;XOwv;d$eaD_+~sl9
z`_bldN7Pg|IhDS5$9pE_7Ok3Zva>4`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^<eyvma8LE|T;
zMa#qNPE_9bYWv&x+nFz7b4;dl$CZ={9_)S{683BHQ>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^<I>

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^<H0LSrP@;r|_;_le4Tx*${j*w1>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?p<Io!WwYuM{n
zqTKbm)X{feGkux6lj1^SC_P^-?x4Jr$D&KlBuH7yecbeF%#=4gv??YJuW8CEk7*Yf
zTWgux%lKzYBKNDmD^h0PKSxb>v9^o5s$<kxRpWVr9@?2(Th`Ciju<jmg^3<BL(Y@*
zZG^dXv;#ei^5#MPje_)x@3WR#XC&p7wo|LpmKQFu61GP<N3py)kuAj?il^hr9L7j?
zC3AzqvPDv~?P#@L-B4%-z3){)(o4VWV&dZ*d-J-qlb7m)5>>=&js}Blk!-x@n19od
z^O)^$?I1bF?yzo1Osrw0xbNBVj_mUdjjXj|%hLG3rm8N9-@&()FBaW+z9FdFGit!q
z{+>Mca)nzY$=iEO7C;}E$#boy-tn@tBX+UM<rR6w+%A5eGmm6QIxQ!R-x6}IxwGD+
z`8)|E@Xh#4m5}zxmKH!O>|M)|wRte&tJ(frBH~~<Qng+POm_hEgaCOfKsf|ZRsv+{
z=RT>P0961`M1V;HKr95v-2i0=pt%a5)B`#kfYJ{b)c{l}K)%X<DE}}+N{er2F9_ei
f&8@q1&b-!E0i)O?P-5}YAXv6@)7-u4snLp$L}?<G

literal 0
HcmV?d00001

diff --git a/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.pack b/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.pack
new file mode 100644
index 0000000000000000000000000000000000000000..ddb8c16caf1f0600bf22af94b7f41c3799679617
GIT binary patch
literal 6316
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
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)
+	})
+}