diff --git a/modules/context/repo.go b/modules/context/repo.go
index 395ccf4b10..18b6650b6e 100644
--- a/modules/context/repo.go
+++ b/modules/context/repo.go
@@ -776,6 +776,8 @@ const (
 	RepoRefBlob
 )
 
+const headRefName = "HEAD"
+
 // RepoRef handles repository reference names when the ref name is not
 // explicitly given
 func RepoRef() func(*Context) context.CancelFunc {
@@ -836,6 +838,14 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
 	case RepoRefBranch:
 		ref := getRefNameFromPath(ctx, repo, path, repo.GitRepo.IsBranchExist)
 		if len(ref) == 0 {
+
+			// check if ref is HEAD
+			parts := strings.Split(path, "/")
+			if parts[0] == headRefName {
+				repo.TreePath = strings.Join(parts[1:], "/")
+				return repo.Repository.DefaultBranch
+			}
+
 			// maybe it's a renamed branch
 			return getRefNameFromPath(ctx, repo, path, func(s string) bool {
 				b, exist, err := git_model.FindRenamedBranch(ctx, repo.Repository.ID, s)
@@ -864,6 +874,16 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
 			repo.TreePath = strings.Join(parts[1:], "/")
 			return parts[0]
 		}
+
+		if len(parts) > 0 && parts[0] == headRefName {
+			// HEAD ref points to last default branch commit
+			commit, err := repo.GitRepo.GetBranchCommit(repo.Repository.DefaultBranch)
+			if err != nil {
+				return ""
+			}
+			repo.TreePath = strings.Join(parts[1:], "/")
+			return commit.ID.String()
+		}
 	case RepoRefBlob:
 		_, err := repo.GitRepo.GetBlob(path)
 		if err != nil {
diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go
index 99a27d6a7f..f5417b100c 100644
--- a/tests/integration/repo_test.go
+++ b/tests/integration/repo_test.go
@@ -302,6 +302,10 @@ func TestViewRepoDirectoryReadme(t *testing.T) {
 	check("plain", "/user2/readme-test/src/branch/plain/", "README", "plain-text", "Birken my stocks gee howdy")
 	check("i18n", "/user2/readme-test/src/branch/i18n/", "README.zh.md", "markdown", "蛋糕是一个谎言")
 
+	// using HEAD ref
+	check("branch-HEAD", "/user2/readme-test/src/branch/HEAD/", "README.md", "markdown", "The cake is a lie.")
+	check("commit-HEAD", "/user2/readme-test/src/commit/HEAD/", "README.md", "markdown", "The cake is a lie.")
+
 	// viewing different subdirectories
 	check("subdir", "/user2/readme-test/src/branch/subdir/libcake", "README.md", "markdown", "Four pints of sugar.")
 	check("docs-direct", "/user2/readme-test/src/branch/special-subdir-docs/docs/", "README.md", "markdown", "This is in docs/")