diff --git a/models/update.go b/models/update.go
index 5675a94cf4..188e6cb9c7 100644
--- a/models/update.go
+++ b/models/update.go
@@ -16,6 +16,8 @@ import (
 )
 
 func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) {
+	//fmt.Println(refName, oldCommitId, newCommitId)
+	//fmt.Println(userName, repoUserName, repoName)
 	isNew := strings.HasPrefix(oldCommitId, "0000000")
 	if isNew &&
 		strings.HasPrefix(newCommitId, "0000000") {
@@ -74,11 +76,40 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
 		log.GitLogger.Fatal("runUpdate.GetRepositoryByName userId: %v", err)
 	}
 
+	// if tags push
+	if strings.HasPrefix(refName, "refs/tags/") {
+		tagName := git.RefEndName(refName)
+		tag, err := repo.GetTag(tagName)
+		if err != nil {
+			log.GitLogger.Fatal("runUpdate.GetTag: %v", err)
+		}
+
+		var actEmail string
+		if tag.Tagger != nil {
+			actEmail = tag.Tagger.Email
+		} else {
+			cmt, err := tag.Commit()
+			if err != nil {
+				log.GitLogger.Fatal("runUpdate.GetTag Commit: %v", err)
+			}
+			actEmail = cmt.Committer.Email
+		}
+
+		commit := &base.PushCommits{}
+
+		if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
+			repos.Id, repoUserName, repoName, refName, commit); err != nil {
+			log.GitLogger.Fatal("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
+		}
+		return
+	}
+
 	commits := make([]*base.PushCommit, 0)
 	var maxCommits = 3
 	var actEmail string
 	for e := l.Front(); e != nil; e = e.Next() {
 		commit := e.Value.(*git.Commit)
+
 		if actEmail == "" {
 			actEmail = commit.Committer.Email
 		}
diff --git a/routers/repo/http.go b/routers/repo/http.go
index 08bbfc99a5..2f28742bb9 100644
--- a/routers/repo/http.go
+++ b/routers/repo/http.go
@@ -7,6 +7,7 @@ package repo
 import (
 	"bytes"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"net/http"
 	"os"
@@ -130,21 +131,49 @@ func Http(ctx *middleware.Context, params martini.Params) {
 		}
 	}
 
-	config := Config{setting.RepoRootPath, "git", true, true, func(rpc string, input []byte) {
-		if rpc == "receive-pack" {
-			firstLine := bytes.IndexRune(input, '\000')
-			if firstLine > -1 {
-				fields := strings.Fields(string(input[:firstLine]))
-				if len(fields) == 3 {
-					oldCommitId := fields[0][4:]
-					newCommitId := fields[1]
-					refName := fields[2]
+	var f func(rpc string, input []byte)
 
-					models.Update(refName, oldCommitId, newCommitId, authUsername, username, reponame, authUser.Id)
+	f = func(rpc string, input []byte) {
+		if rpc == "receive-pack" {
+			var lastLine int64 = 0
+
+			for {
+				head := input[lastLine : lastLine+2]
+				if head[0] == '0' && head[1] == '0' {
+					size, err := strconv.ParseInt(string(input[lastLine+2:lastLine+4]), 16, 32)
+					if err != nil {
+						log.Error("%v", err)
+						return
+					}
+
+					if size == 0 {
+						//fmt.Println(string(input[lastLine:]))
+						break
+					}
+
+					line := input[lastLine : lastLine+size]
+					idx := bytes.IndexRune(line, '\000')
+					if idx > -1 {
+						line = line[:idx]
+					}
+					fields := strings.Fields(string(line))
+					if len(fields) >= 3 {
+						oldCommitId := fields[0][4:]
+						newCommitId := fields[1]
+						refName := fields[2]
+
+						models.Update(refName, oldCommitId, newCommitId, authUsername, username, reponame, authUser.Id)
+					}
+					lastLine = lastLine + size
+				} else {
+					//fmt.Println("ddddddddddd")
+					break
 				}
 			}
 		}
-	}}
+	}
+
+	config := Config{setting.RepoRootPath, "git", true, true, f}
 
 	handler := HttpBackend(&config)
 	handler(ctx.ResponseWriter, ctx.Req)
@@ -237,8 +266,14 @@ func serviceRpc(rpc string, hr handler) {
 	w.Header().Set("Content-Type", fmt.Sprintf("application/x-git-%s-result", rpc))
 	w.WriteHeader(http.StatusOK)
 
-	input, _ := ioutil.ReadAll(r.Body)
-	br := bytes.NewReader(input)
+	var input []byte
+	var br io.Reader
+	if hr.Config.OnSucceed != nil {
+		input, _ = ioutil.ReadAll(r.Body)
+		br = bytes.NewReader(input)
+	} else {
+		br = r.Body
+	}
 
 	args := []string{rpc, "--stateless-rpc", dir}
 	cmd := exec.Command(hr.Config.GitBinPath, args...)