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 94e5f2f9c8..6c57dc03ad 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 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 @@
 			</div>
 		</div>
 		{{template "repo/commits_table" .}}
+		{{if .OldFilename}}
+			<div class="ui bottom attached header">
+				<span>{{.locale.Tr "repo.commits.renamed_from" .OldFilename}} (<a href="{{.OldFilenameHistory}}">{{.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 567284ef1c..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/40/8bbd3bd1f96950f8cf2f98c479557f6b18817a and /dev/null differ
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 f23960f4cc..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/5d/5c87a90af64cc67f22d60a942d5efaef8bc96b and /dev/null differ
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 46cc9e3e5e..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/88/3e2970ed6937cbb63311e941adb97df0ae3a52 and /dev/null differ
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 5a1e79326f..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/8c/ac7a8f434451410cc91ab9c04d07baff974ad8 and /dev/null differ
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 3b71228a7e..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/a0/ccafed39086ef520be6886d9395eb2100d317e and /dev/null differ
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 dcbd3b3eb9..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/ab/e2a9ddfd7f542ff89bc13960a929dc8ca86c99 and /dev/null differ
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 cd9cea6797..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/cd/879fb6cf5b7bbe0fbc3a0ef44c8695fde89a56 and /dev/null differ
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 bea28c9f69..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/d8/f53dfb33f6ccf4169c34970b5e747511c18beb and /dev/null differ
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 b6803eb5a2..0000000000
Binary files a/tests/gitea-repositories-meta/user2/repo59.git/objects/f3/c1ec36c0e7605be54e71f24035caa675b7ba41 and /dev/null differ
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 0000000000..d151dc87e6
Binary files /dev/null and b/tests/gitea-repositories-meta/user2/repo59.git/objects/info/commit-graph differ
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 0000000000..aaa9981cf5
Binary files /dev/null and b/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.idx differ
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 0000000000..ddb8c16caf
Binary files /dev/null and b/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.pack differ
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 0000000000..81554dba74
Binary files /dev/null and b/tests/gitea-repositories-meta/user2/repo59.git/objects/pack/pack-6dd3a6fe138f1d77e14c2e6b8e6c41e5ae242adf.rev differ
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)
+	})
+}