diff --git a/models/models.go b/models/models.go
index d6a6200eb360..2e0bb759d414 100644
--- a/models/models.go
+++ b/models/models.go
@@ -88,7 +88,8 @@ func setEngine() {
 
 func init() {
 	setEngine()
-	if err := orm.Sync(new(User), new(PublicKey), new(Repository), new(Access), new(Action)); err != nil {
+	if err := orm.Sync(new(User), new(PublicKey), new(Repository), new(Access),
+		new(Action), new(Watch)); err != nil {
 		fmt.Printf("sync database struct error: %v\n", err)
 		os.Exit(2)
 	}
diff --git a/models/repo.go b/models/repo.go
index fce7d7f53045..187862fe27f5 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -43,11 +43,20 @@ type Repository struct {
 	Updated     time.Time `xorm:"updated"`
 }
 
-type Star struct {
-	Id      int64
-	RepoId  int64
-	UserId  int64
-	Created time.Time `xorm:"created"`
+// Watch is connection request for receiving repository notifycation.
+type Watch struct {
+	Id     int64
+	RepoId int64 `xorm:"UNIQUE(watch)"`
+	UserId int64 `xorm:"UNIQUE(watch)"`
+}
+
+func WatchRepo(userId, repoId int64, watch bool) (err error) {
+	if watch {
+		_, err = orm.Insert(&Watch{RepoId: repoId, UserId: userId})
+	} else {
+		_, err = orm.Delete(&Watch{0, repoId, userId})
+	}
+	return err
 }
 
 var (
diff --git a/routers/repo/single.go b/routers/repo/single.go
index 3d0447edddf3..141a6cdae29f 100644
--- a/routers/repo/single.go
+++ b/routers/repo/single.go
@@ -208,3 +208,25 @@ func Pulls(ctx *middleware.Context) {
 	ctx.Data["IsRepoToolbarPulls"] = true
 	ctx.HTML(200, "repo/pulls", ctx.Data)
 }
+
+func Action(ctx *middleware.Context, params martini.Params) {
+	var err error
+	switch params["action"] {
+	case "watch":
+		err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true)
+	case "unwatch":
+		err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
+	}
+
+	if err != nil {
+		log.Error("repo.Action(%s): %v", params["action"], err)
+		ctx.JSON(200, map[string]interface{}{
+			"ok":  false,
+			"err": err.Error(),
+		})
+		return
+	}
+	ctx.JSON(200, map[string]interface{}{
+		"ok": true,
+	})
+}
diff --git a/routers/user/setting.go b/routers/user/setting.go
index 719e0c1919db..053f327f0f22 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -93,7 +93,6 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
 	if ctx.Req.Method == "DELETE" || ctx.Query("_method") == "DELETE" {
 		id, err := strconv.ParseInt(ctx.Query("id"), 10, 64)
 		if err != nil {
-			ctx.Data["ErrorMsg"] = err
 			log.Error("ssh.DelPublicKey: %v", err)
 			ctx.JSON(200, map[string]interface{}{
 				"ok":  false,
@@ -107,7 +106,6 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
 		}
 
 		if err = models.DeletePublicKey(k); err != nil {
-			ctx.Data["ErrorMsg"] = err
 			log.Error("ssh.DelPublicKey: %v", err)
 			ctx.JSON(200, map[string]interface{}{
 				"ok":  false,
diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl
index 8b4e41f74858..2e67a1200a94 100644
--- a/templates/repo/commits.tmpl
+++ b/templates/repo/commits.tmpl
@@ -26,7 +26,7 @@
                 {{$r := List .Commits}}
                 {{range $r}}
                 <tr>
-                    <td class="author"><img class="avatar" src="{{AvatarLink .Committer.Email}}" alt=""/>{{.Committer.Name}}</td>
+                    <td class="author"><img class="avatar" src="{{AvatarLink .Committer.Email}}" alt=""/><a href="/user/{{.Committer.Name}}">{{.Committer.Name}}</a></td>
                     <td class="sha"><a class="label label-success" href="/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 7}} </a></td>
                     <td class="message">{{.Message}} </td>
                     <td class="date">{{TimeSince .Committer.When}}</td>
diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl
index 8dca29ffe3fa..2d76d9bf01b6 100644
--- a/templates/user/profile.tmpl
+++ b/templates/user/profile.tmpl
@@ -3,8 +3,8 @@
 <div id="gogs-body" class="container" data-page="user">
     <div id="gogs-user-profile" class="col-md-3">
         <div class="profile-avatar text-center">
-            <a href="{{.Owner.HomeLink}}" class="center-block" data-toggle="tooltip" data-placement="bottom" title="Change Avatar">
-                <img id="gogs-user-avatar" src="{{.Owner.AvatarLink}}?s=200" alt="user-avatar" title="username"/>
+            <a href="http://gravatar.com/emails/" class="center-block" data-toggle="tooltip" data-placement="bottom" title="Change your avatar at gravatar.com">
+                <img id="gogs-user-avatar" src="{{.Owner.AvatarLink}}?s=200" alt="user-avatar" title="{{.Owner.Name}}"/>
             </a>
             <span id="gogs-user-name" class="center-block">{{.Owner.Name}}</span>
         </div>
diff --git a/web.go b/web.go
index 2a9df17c8d1d..f793518a18c6 100644
--- a/web.go
+++ b/web.go
@@ -73,8 +73,8 @@ func runWeb(*cli.Context) {
 
 	m.Use(middleware.InitContext())
 
-	ignSignIn := middleware.SignInRequire(false)
-	reqSignIn, reqSignOut := middleware.SignInRequire(true), middleware.SignOutRequire()
+	reqSignIn, ignSignIn := middleware.SignInRequire(true), middleware.SignInRequire(false)
+	reqSignOut := middleware.SignOutRequire()
 	// Routers.
 	m.Get("/", ignSignIn, routers.Home)
 	m.Get("/issues", reqSignIn, user.Issues)
@@ -106,6 +106,7 @@ func runWeb(*cli.Context) {
 	m.Get("/:username/:reponame/issues", ignSignIn, middleware.RepoAssignment(true), repo.Issues)
 	m.Get("/:username/:reponame/pulls", ignSignIn, middleware.RepoAssignment(true), repo.Pulls)
 	m.Get("/:username/:reponame/branches", ignSignIn, middleware.RepoAssignment(true), repo.Branches)
+	m.Get("/:username/:reponame/action/:action", reqSignIn, middleware.RepoAssignment(true), repo.Action)
 	m.Get("/:username/:reponame/tree/:branchname/**",
 		ignSignIn, middleware.RepoAssignment(true), repo.Single)
 	m.Get("/:username/:reponame/tree/:branchname",