diff --git a/modules/context/repo.go b/modules/context/repo.go index 44ae624568..861df4af59 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -773,6 +773,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 { @@ -833,6 +835,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) @@ -861,6 +871,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/")