diff --git a/modules/middleware/context.go b/modules/middleware/context.go
index d81ab999bf..a6aa58eebc 100644
--- a/modules/middleware/context.go
+++ b/modules/middleware/context.go
@@ -18,6 +18,7 @@ import (
 	"github.com/codegangsta/martini"
 
 	"github.com/gogits/cache"
+	"github.com/gogits/git"
 	"github.com/gogits/session"
 
 	"github.com/gogits/gogs/models"
@@ -41,11 +42,18 @@ type Context struct {
 	csrfToken string
 
 	Repo struct {
-		IsValid    bool
 		IsOwner    bool
 		IsWatching bool
+		IsBranch   bool
+		IsTag      bool
+		IsCommit   bool
 		Repository *models.Repository
 		Owner      *models.User
+		Commit     *git.Commit
+		GitRepo    *git.Repository
+		BranchName string
+		CommitId   string
+		RepoLink   string
 		CloneLink  struct {
 			SSH   string
 			HTTPS string
@@ -98,6 +106,10 @@ func (ctx *Context) Handle(status int, title string, err error) {
 	ctx.HTML(status, fmt.Sprintf("status/%d", status))
 }
 
+func (ctx *Context) Debug(msg string, args ...interface{}) {
+	log.Debug(msg, args...)
+}
+
 func (ctx *Context) GetCookie(name string) string {
 	cookie, err := ctx.Req.Cookie(name)
 	if err != nil {
diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go
index 54b735af07..d1b68b052c 100644
--- a/modules/middleware/repo.go
+++ b/modules/middleware/repo.go
@@ -11,6 +11,8 @@ import (
 
 	"github.com/codegangsta/martini"
 
+	"github.com/gogits/git"
+
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/modules/base"
 )
@@ -25,8 +27,12 @@ func RepoAssignment(redirect bool) martini.Handler {
 			err  error
 		)
 
+		userName := params["username"]
+		repoName := params["reponame"]
+		branchName := params["branchname"]
+
 		// get repository owner
-		ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == strings.ToLower(params["username"])
+		ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName)
 
 		if !ctx.Repo.IsOwner {
 			user, err = models.GetUserByName(params["username"])
@@ -51,10 +57,8 @@ func RepoAssignment(redirect bool) martini.Handler {
 			return
 		}
 
-		ctx.Repo.Owner = user
-
 		// get repository
-		repo, err := models.GetRepositoryByName(user.Id, params["reponame"])
+		repo, err := models.GetRepositoryByName(user.Id, repoName)
 		if err != nil {
 			if err == models.ErrRepoNotExist {
 				ctx.Handle(404, "RepoAssignment", err)
@@ -62,29 +66,69 @@ func RepoAssignment(redirect bool) martini.Handler {
 				ctx.Redirect("/")
 				return
 			}
-			ctx.Handle(200, "RepoAssignment", err)
+			ctx.Handle(404, "RepoAssignment", err)
 			return
 		}
+		ctx.Repo.Repository = repo
 
-		ctx.Repo.IsValid = true
-		if ctx.User != nil {
+		gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
+		if err != nil {
+			ctx.Handle(404, "RepoAssignment Invalid repo", err)
+			return
+		}
+		ctx.Repo.GitRepo = gitRepo
+
+	detect:
+		if len(branchName) > 0 {
+			// TODO check tag
+			if models.IsBranchExist(user.Name, repoName, branchName) {
+				ctx.Repo.IsBranch = true
+				ctx.Repo.BranchName = branchName
+
+				ctx.Repo.Commit, err = gitRepo.GetCommitOfBranch(branchName)
+				if err != nil {
+					ctx.Handle(404, "RepoAssignment invalid branch", nil)
+					return
+				}
+
+				ctx.Repo.CommitId = ctx.Repo.Commit.Oid.String()
+
+			} else if len(branchName) == 40 {
+				ctx.Repo.IsCommit = true
+				ctx.Repo.CommitId = branchName
+				ctx.Repo.BranchName = branchName
+
+				ctx.Repo.Commit, err = gitRepo.GetCommit(branchName)
+				if err != nil {
+					ctx.Handle(404, "RepoAssignment invalid commit", nil)
+					return
+				}
+			} else {
+				ctx.Handle(404, "RepoAssignment invalid repo", nil)
+				return
+			}
+
+		} else {
+			branchName = "master"
+			goto detect
+		}
+
+		if ctx.IsSigned {
 			ctx.Repo.IsWatching = models.IsWatching(ctx.User.Id, repo.Id)
 		}
-		ctx.Repo.Repository = repo
+
+		ctx.Repo.Owner = user
 		ctx.Repo.CloneLink.SSH = fmt.Sprintf("%s@%s:%s/%s.git", base.RunUser, base.Domain, user.LowerName, repo.LowerName)
 		ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("%s%s/%s.git", base.AppUrl, user.LowerName, repo.LowerName)
+		ctx.Repo.RepoLink = "/" + user.Name + "/" + repo.Name
 
-		if len(params["branchname"]) == 0 {
-			params["branchname"] = "master"
-		}
-		ctx.Data["Branchname"] = params["branchname"]
-
-		ctx.Data["IsRepositoryValid"] = true
+		ctx.Data["BranchName"] = ctx.Repo.BranchName
+		ctx.Data["CommitId"] = ctx.Repo.CommitId
 		ctx.Data["Repository"] = repo
 		ctx.Data["Owner"] = user
 		ctx.Data["Title"] = user.Name + "/" + repo.Name
 		ctx.Data["CloneLink"] = ctx.Repo.CloneLink
-		ctx.Data["RepositoryLink"] = ctx.Data["Title"]
+		ctx.Data["RepoLink"] = ctx.Repo.RepoLink
 		ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
 		ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching
 	}