diff --git a/models/action.go b/models/action.go
index 0253e2add0..ab8a657e0d 100644
--- a/models/action.go
+++ b/models/action.go
@@ -17,7 +17,6 @@ import (
 	"unicode"
 
 	"code.gitea.io/gitea/modules/base"
-	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	api "code.gitea.io/gitea/modules/structs"
@@ -441,6 +440,9 @@ func (pc *PushCommits) ToAPIPayloadCommits(repoLink string) []*api.PayloadCommit
 // AvatarLink tries to match user in database with e-mail
 // in order to show custom avatar, and falls back to general avatar link.
 func (pc *PushCommits) AvatarLink(email string) string {
+	if pc.avatars == nil {
+		pc.avatars = make(map[string]string)
+	}
 	avatar, ok := pc.avatars[email]
 	if ok {
 		return avatar
@@ -655,200 +657,6 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra
 	return nil
 }
 
-// CommitRepoActionOptions represent options of a new commit action.
-type CommitRepoActionOptions struct {
-	PusherName  string
-	RepoOwnerID int64
-	RepoName    string
-	RefFullName string
-	OldCommitID string
-	NewCommitID string
-	Commits     *PushCommits
-}
-
-// CommitRepoAction adds new commit action to the repository, and prepare
-// corresponding webhooks.
-func CommitRepoAction(opts CommitRepoActionOptions) error {
-	pusher, err := GetUserByName(opts.PusherName)
-	if err != nil {
-		return fmt.Errorf("GetUserByName [%s]: %v", opts.PusherName, err)
-	}
-
-	repo, err := GetRepositoryByName(opts.RepoOwnerID, opts.RepoName)
-	if err != nil {
-		return fmt.Errorf("GetRepositoryByName [owner_id: %d, name: %s]: %v", opts.RepoOwnerID, opts.RepoName, err)
-	}
-
-	refName := git.RefEndName(opts.RefFullName)
-
-	// Change default branch and empty status only if pushed ref is non-empty branch.
-	if repo.IsEmpty && opts.NewCommitID != git.EmptySHA && strings.HasPrefix(opts.RefFullName, git.BranchPrefix) {
-		repo.DefaultBranch = refName
-		repo.IsEmpty = false
-		if refName != "master" {
-			gitRepo, err := git.OpenRepository(repo.RepoPath())
-			if err != nil {
-				return err
-			}
-			if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
-				if !git.IsErrUnsupportedVersion(err) {
-					return err
-				}
-			}
-		}
-	}
-
-	// Change repository empty status and update last updated time.
-	if err = UpdateRepository(repo, false); err != nil {
-		return fmt.Errorf("UpdateRepository: %v", err)
-	}
-
-	isNewBranch := false
-	opType := ActionCommitRepo
-	// Check it's tag push or branch.
-	if strings.HasPrefix(opts.RefFullName, git.TagPrefix) {
-		opType = ActionPushTag
-		if opts.NewCommitID == git.EmptySHA {
-			opType = ActionDeleteTag
-		}
-		opts.Commits = &PushCommits{}
-	} else if opts.NewCommitID == git.EmptySHA {
-		opType = ActionDeleteBranch
-		opts.Commits = &PushCommits{}
-	} else {
-		// if not the first commit, set the compare URL.
-		if opts.OldCommitID == git.EmptySHA {
-			isNewBranch = true
-		} else {
-			opts.Commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID)
-		}
-
-		if err = UpdateIssuesCommit(pusher, repo, opts.Commits.Commits, refName); err != nil {
-			log.Error("updateIssuesCommit: %v", err)
-		}
-	}
-
-	if len(opts.Commits.Commits) > setting.UI.FeedMaxCommitNum {
-		opts.Commits.Commits = opts.Commits.Commits[:setting.UI.FeedMaxCommitNum]
-	}
-
-	data, err := json.Marshal(opts.Commits)
-	if err != nil {
-		return fmt.Errorf("Marshal: %v", err)
-	}
-
-	if err = NotifyWatchers(&Action{
-		ActUserID: pusher.ID,
-		ActUser:   pusher,
-		OpType:    opType,
-		Content:   string(data),
-		RepoID:    repo.ID,
-		Repo:      repo,
-		RefName:   refName,
-		IsPrivate: repo.IsPrivate,
-	}); err != nil {
-		return fmt.Errorf("NotifyWatchers: %v", err)
-	}
-
-	defer func() {
-		go HookQueue.Add(repo.ID)
-	}()
-
-	apiPusher := pusher.APIFormat()
-	apiRepo := repo.APIFormat(AccessModeNone)
-
-	var shaSum string
-	var isHookEventPush = false
-	switch opType {
-	case ActionCommitRepo: // Push
-		isHookEventPush = true
-
-		if isNewBranch {
-			gitRepo, err := git.OpenRepository(repo.RepoPath())
-			if err != nil {
-				log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
-			}
-
-			shaSum, err = gitRepo.GetBranchCommitID(refName)
-			if err != nil {
-				log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err)
-			}
-			if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
-				Ref:     refName,
-				Sha:     shaSum,
-				RefType: "branch",
-				Repo:    apiRepo,
-				Sender:  apiPusher,
-			}); err != nil {
-				return fmt.Errorf("PrepareWebhooks: %v", err)
-			}
-		}
-
-	case ActionDeleteBranch: // Delete Branch
-		isHookEventPush = true
-
-		if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
-			Ref:        refName,
-			RefType:    "branch",
-			PusherType: api.PusherTypeUser,
-			Repo:       apiRepo,
-			Sender:     apiPusher,
-		}); err != nil {
-			return fmt.Errorf("PrepareWebhooks.(delete branch): %v", err)
-		}
-
-	case ActionPushTag: // Create
-		isHookEventPush = true
-
-		gitRepo, err := git.OpenRepository(repo.RepoPath())
-		if err != nil {
-			log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
-		}
-		shaSum, err = gitRepo.GetTagCommitID(refName)
-		if err != nil {
-			log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err)
-		}
-		if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
-			Ref:     refName,
-			Sha:     shaSum,
-			RefType: "tag",
-			Repo:    apiRepo,
-			Sender:  apiPusher,
-		}); err != nil {
-			return fmt.Errorf("PrepareWebhooks: %v", err)
-		}
-	case ActionDeleteTag: // Delete Tag
-		isHookEventPush = true
-
-		if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
-			Ref:        refName,
-			RefType:    "tag",
-			PusherType: api.PusherTypeUser,
-			Repo:       apiRepo,
-			Sender:     apiPusher,
-		}); err != nil {
-			return fmt.Errorf("PrepareWebhooks.(delete tag): %v", err)
-		}
-	}
-
-	if isHookEventPush {
-		if err = PrepareWebhooks(repo, HookEventPush, &api.PushPayload{
-			Ref:        opts.RefFullName,
-			Before:     opts.OldCommitID,
-			After:      opts.NewCommitID,
-			CompareURL: setting.AppURL + opts.Commits.CompareURL,
-			Commits:    opts.Commits.ToAPIPayloadCommits(repo.HTMLURL()),
-			Repo:       apiRepo,
-			Pusher:     apiPusher,
-			Sender:     apiPusher,
-		}); err != nil {
-			return fmt.Errorf("PrepareWebhooks: %v", err)
-		}
-	}
-
-	return nil
-}
-
 func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err error) {
 	if err = notifyWatchers(e, &Action{
 		ActUserID: doer.ID,
diff --git a/models/action_test.go b/models/action_test.go
index da50ebce80..740976885e 100644
--- a/models/action_test.go
+++ b/models/action_test.go
@@ -6,7 +6,6 @@ import (
 	"strings"
 	"testing"
 
-	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/setting"
 
 	"github.com/stretchr/testify/assert"
@@ -409,119 +408,6 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
 	CheckConsistencyFor(t, &Action{})
 }
 
-func testCorrectRepoAction(t *testing.T, opts CommitRepoActionOptions, actionBean *Action) {
-	AssertNotExistsBean(t, actionBean)
-	assert.NoError(t, CommitRepoAction(opts))
-	AssertExistsAndLoadBean(t, actionBean)
-	CheckConsistencyFor(t, &Action{})
-}
-
-func TestCommitRepoAction(t *testing.T) {
-	samples := []struct {
-		userID                  int64
-		repositoryID            int64
-		commitRepoActionOptions CommitRepoActionOptions
-		action                  Action
-	}{
-		{
-			userID:       2,
-			repositoryID: 2,
-			commitRepoActionOptions: CommitRepoActionOptions{
-				RefFullName: "refName",
-				OldCommitID: "oldCommitID",
-				NewCommitID: "newCommitID",
-				Commits: &PushCommits{
-					avatars: make(map[string]string),
-					Commits: []*PushCommit{
-						{
-							Sha1:           "abcdef1",
-							CommitterEmail: "user2@example.com",
-							CommitterName:  "User Two",
-							AuthorEmail:    "user4@example.com",
-							AuthorName:     "User Four",
-							Message:        "message1",
-						},
-						{
-							Sha1:           "abcdef2",
-							CommitterEmail: "user2@example.com",
-							CommitterName:  "User Two",
-							AuthorEmail:    "user2@example.com",
-							AuthorName:     "User Two",
-							Message:        "message2",
-						},
-					},
-					Len: 2,
-				},
-			},
-			action: Action{
-				OpType:  ActionCommitRepo,
-				RefName: "refName",
-			},
-		},
-		{
-			userID:       2,
-			repositoryID: 1,
-			commitRepoActionOptions: CommitRepoActionOptions{
-				RefFullName: git.TagPrefix + "v1.1",
-				OldCommitID: git.EmptySHA,
-				NewCommitID: "newCommitID",
-				Commits:     &PushCommits{},
-			},
-			action: Action{
-				OpType:  ActionPushTag,
-				RefName: "v1.1",
-			},
-		},
-		{
-			userID:       2,
-			repositoryID: 1,
-			commitRepoActionOptions: CommitRepoActionOptions{
-				RefFullName: git.TagPrefix + "v1.1",
-				OldCommitID: "oldCommitID",
-				NewCommitID: git.EmptySHA,
-				Commits:     &PushCommits{},
-			},
-			action: Action{
-				OpType:  ActionDeleteTag,
-				RefName: "v1.1",
-			},
-		},
-		{
-			userID:       2,
-			repositoryID: 1,
-			commitRepoActionOptions: CommitRepoActionOptions{
-				RefFullName: git.BranchPrefix + "feature/1",
-				OldCommitID: "oldCommitID",
-				NewCommitID: git.EmptySHA,
-				Commits:     &PushCommits{},
-			},
-			action: Action{
-				OpType:  ActionDeleteBranch,
-				RefName: "feature/1",
-			},
-		},
-	}
-
-	for _, s := range samples {
-		PrepareTestEnv(t)
-
-		user := AssertExistsAndLoadBean(t, &User{ID: s.userID}).(*User)
-		repo := AssertExistsAndLoadBean(t, &Repository{ID: s.repositoryID, OwnerID: user.ID}).(*Repository)
-		repo.Owner = user
-
-		s.commitRepoActionOptions.PusherName = user.Name
-		s.commitRepoActionOptions.RepoOwnerID = user.ID
-		s.commitRepoActionOptions.RepoName = repo.Name
-
-		s.action.ActUserID = user.ID
-		s.action.RepoID = repo.ID
-		s.action.Repo = repo
-		s.action.IsPrivate = repo.IsPrivate
-
-		testCorrectRepoAction(t, s.commitRepoActionOptions, &s.action)
-	}
-}
-
 func TestTransferRepoAction(t *testing.T) {
 	assert.NoError(t, PrepareTestDatabase())
 
diff --git a/models/unit_tests.go b/models/unit_tests.go
index 330dc5ee4e..9dadf2e128 100644
--- a/models/unit_tests.go
+++ b/models/unit_tests.go
@@ -65,6 +65,13 @@ func MainTest(m *testing.M, pathToGiteaRoot string) {
 		fatalTestError("url.Parse: %v\n", err)
 	}
 
+	if err = removeAllWithRetry(setting.RepoRootPath); err != nil {
+		fatalTestError("os.RemoveAll: %v\n", err)
+	}
+	if err = com.CopyDir(filepath.Join(pathToGiteaRoot, "integrations", "gitea-repositories-meta"), setting.RepoRootPath); err != nil {
+		fatalTestError("com.CopyDir: %v\n", err)
+	}
+
 	exitStatus := m.Run()
 	if err = removeAllWithRetry(setting.RepoRootPath); err != nil {
 		fatalTestError("os.RemoveAll: %v\n", err)
diff --git a/modules/repofiles/action.go b/modules/repofiles/action.go
new file mode 100644
index 0000000000..ac5df9a14f
--- /dev/null
+++ b/modules/repofiles/action.go
@@ -0,0 +1,211 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package repofiles
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+
+	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
+)
+
+// CommitRepoActionOptions represent options of a new commit action.
+type CommitRepoActionOptions struct {
+	PusherName  string
+	RepoOwnerID int64
+	RepoName    string
+	RefFullName string
+	OldCommitID string
+	NewCommitID string
+	Commits     *models.PushCommits
+}
+
+// CommitRepoAction adds new commit action to the repository, and prepare
+// corresponding webhooks.
+func CommitRepoAction(opts CommitRepoActionOptions) error {
+	pusher, err := models.GetUserByName(opts.PusherName)
+	if err != nil {
+		return fmt.Errorf("GetUserByName [%s]: %v", opts.PusherName, err)
+	}
+
+	repo, err := models.GetRepositoryByName(opts.RepoOwnerID, opts.RepoName)
+	if err != nil {
+		return fmt.Errorf("GetRepositoryByName [owner_id: %d, name: %s]: %v", opts.RepoOwnerID, opts.RepoName, err)
+	}
+
+	refName := git.RefEndName(opts.RefFullName)
+
+	// Change default branch and empty status only if pushed ref is non-empty branch.
+	if repo.IsEmpty && opts.NewCommitID != git.EmptySHA && strings.HasPrefix(opts.RefFullName, git.BranchPrefix) {
+		repo.DefaultBranch = refName
+		repo.IsEmpty = false
+		if refName != "master" {
+			gitRepo, err := git.OpenRepository(repo.RepoPath())
+			if err != nil {
+				return err
+			}
+			if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
+				if !git.IsErrUnsupportedVersion(err) {
+					return err
+				}
+			}
+		}
+	}
+
+	// Change repository empty status and update last updated time.
+	if err = models.UpdateRepository(repo, false); err != nil {
+		return fmt.Errorf("UpdateRepository: %v", err)
+	}
+
+	isNewBranch := false
+	opType := models.ActionCommitRepo
+	// Check it's tag push or branch.
+	if strings.HasPrefix(opts.RefFullName, git.TagPrefix) {
+		opType = models.ActionPushTag
+		if opts.NewCommitID == git.EmptySHA {
+			opType = models.ActionDeleteTag
+		}
+		opts.Commits = &models.PushCommits{}
+	} else if opts.NewCommitID == git.EmptySHA {
+		opType = models.ActionDeleteBranch
+		opts.Commits = &models.PushCommits{}
+	} else {
+		// if not the first commit, set the compare URL.
+		if opts.OldCommitID == git.EmptySHA {
+			isNewBranch = true
+		} else {
+			opts.Commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID)
+		}
+
+		if err = models.UpdateIssuesCommit(pusher, repo, opts.Commits.Commits, refName); err != nil {
+			log.Error("updateIssuesCommit: %v", err)
+		}
+	}
+
+	if len(opts.Commits.Commits) > setting.UI.FeedMaxCommitNum {
+		opts.Commits.Commits = opts.Commits.Commits[:setting.UI.FeedMaxCommitNum]
+	}
+
+	data, err := json.Marshal(opts.Commits)
+	if err != nil {
+		return fmt.Errorf("Marshal: %v", err)
+	}
+
+	if err = models.NotifyWatchers(&models.Action{
+		ActUserID: pusher.ID,
+		ActUser:   pusher,
+		OpType:    opType,
+		Content:   string(data),
+		RepoID:    repo.ID,
+		Repo:      repo,
+		RefName:   refName,
+		IsPrivate: repo.IsPrivate,
+	}); err != nil {
+		return fmt.Errorf("NotifyWatchers: %v", err)
+	}
+
+	defer func() {
+		go models.HookQueue.Add(repo.ID)
+	}()
+
+	apiPusher := pusher.APIFormat()
+	apiRepo := repo.APIFormat(models.AccessModeNone)
+
+	var shaSum string
+	var isHookEventPush = false
+	switch opType {
+	case models.ActionCommitRepo: // Push
+		isHookEventPush = true
+
+		if isNewBranch {
+			gitRepo, err := git.OpenRepository(repo.RepoPath())
+			if err != nil {
+				log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
+			}
+
+			shaSum, err = gitRepo.GetBranchCommitID(refName)
+			if err != nil {
+				log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err)
+			}
+			if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{
+				Ref:     refName,
+				Sha:     shaSum,
+				RefType: "branch",
+				Repo:    apiRepo,
+				Sender:  apiPusher,
+			}); err != nil {
+				return fmt.Errorf("PrepareWebhooks: %v", err)
+			}
+		}
+
+	case models.ActionDeleteBranch: // Delete Branch
+		isHookEventPush = true
+
+		if err = models.PrepareWebhooks(repo, models.HookEventDelete, &api.DeletePayload{
+			Ref:        refName,
+			RefType:    "branch",
+			PusherType: api.PusherTypeUser,
+			Repo:       apiRepo,
+			Sender:     apiPusher,
+		}); err != nil {
+			return fmt.Errorf("PrepareWebhooks.(delete branch): %v", err)
+		}
+
+	case models.ActionPushTag: // Create
+		isHookEventPush = true
+
+		gitRepo, err := git.OpenRepository(repo.RepoPath())
+		if err != nil {
+			log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
+		}
+		shaSum, err = gitRepo.GetTagCommitID(refName)
+		if err != nil {
+			log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err)
+		}
+		if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{
+			Ref:     refName,
+			Sha:     shaSum,
+			RefType: "tag",
+			Repo:    apiRepo,
+			Sender:  apiPusher,
+		}); err != nil {
+			return fmt.Errorf("PrepareWebhooks: %v", err)
+		}
+	case models.ActionDeleteTag: // Delete Tag
+		isHookEventPush = true
+
+		if err = models.PrepareWebhooks(repo, models.HookEventDelete, &api.DeletePayload{
+			Ref:        refName,
+			RefType:    "tag",
+			PusherType: api.PusherTypeUser,
+			Repo:       apiRepo,
+			Sender:     apiPusher,
+		}); err != nil {
+			return fmt.Errorf("PrepareWebhooks.(delete tag): %v", err)
+		}
+	}
+
+	if isHookEventPush {
+		if err = models.PrepareWebhooks(repo, models.HookEventPush, &api.PushPayload{
+			Ref:        opts.RefFullName,
+			Before:     opts.OldCommitID,
+			After:      opts.NewCommitID,
+			CompareURL: setting.AppURL + opts.Commits.CompareURL,
+			Commits:    opts.Commits.ToAPIPayloadCommits(repo.HTMLURL()),
+			Repo:       apiRepo,
+			Pusher:     apiPusher,
+			Sender:     apiPusher,
+		}); err != nil {
+			return fmt.Errorf("PrepareWebhooks: %v", err)
+		}
+	}
+
+	return nil
+}
diff --git a/modules/repofiles/action_test.go b/modules/repofiles/action_test.go
new file mode 100644
index 0000000000..322c668dad
--- /dev/null
+++ b/modules/repofiles/action_test.go
@@ -0,0 +1,126 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package repofiles
+
+import (
+	"testing"
+
+	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/git"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func testCorrectRepoAction(t *testing.T, opts CommitRepoActionOptions, actionBean *models.Action) {
+	models.AssertNotExistsBean(t, actionBean)
+	assert.NoError(t, CommitRepoAction(opts))
+	models.AssertExistsAndLoadBean(t, actionBean)
+	models.CheckConsistencyFor(t, &models.Action{})
+}
+
+func TestCommitRepoAction(t *testing.T) {
+	samples := []struct {
+		userID                  int64
+		repositoryID            int64
+		commitRepoActionOptions CommitRepoActionOptions
+		action                  models.Action
+	}{
+		{
+			userID:       2,
+			repositoryID: 2,
+			commitRepoActionOptions: CommitRepoActionOptions{
+				RefFullName: "refName",
+				OldCommitID: "oldCommitID",
+				NewCommitID: "newCommitID",
+				Commits: &models.PushCommits{
+					Commits: []*models.PushCommit{
+						{
+							Sha1:           "abcdef1",
+							CommitterEmail: "user2@example.com",
+							CommitterName:  "User Two",
+							AuthorEmail:    "user4@example.com",
+							AuthorName:     "User Four",
+							Message:        "message1",
+						},
+						{
+							Sha1:           "abcdef2",
+							CommitterEmail: "user2@example.com",
+							CommitterName:  "User Two",
+							AuthorEmail:    "user2@example.com",
+							AuthorName:     "User Two",
+							Message:        "message2",
+						},
+					},
+					Len: 2,
+				},
+			},
+			action: models.Action{
+				OpType:  models.ActionCommitRepo,
+				RefName: "refName",
+			},
+		},
+		{
+			userID:       2,
+			repositoryID: 1,
+			commitRepoActionOptions: CommitRepoActionOptions{
+				RefFullName: git.TagPrefix + "v1.1",
+				OldCommitID: git.EmptySHA,
+				NewCommitID: "newCommitID",
+				Commits:     &models.PushCommits{},
+			},
+			action: models.Action{
+				OpType:  models.ActionPushTag,
+				RefName: "v1.1",
+			},
+		},
+		{
+			userID:       2,
+			repositoryID: 1,
+			commitRepoActionOptions: CommitRepoActionOptions{
+				RefFullName: git.TagPrefix + "v1.1",
+				OldCommitID: "oldCommitID",
+				NewCommitID: git.EmptySHA,
+				Commits:     &models.PushCommits{},
+			},
+			action: models.Action{
+				OpType:  models.ActionDeleteTag,
+				RefName: "v1.1",
+			},
+		},
+		{
+			userID:       2,
+			repositoryID: 1,
+			commitRepoActionOptions: CommitRepoActionOptions{
+				RefFullName: git.BranchPrefix + "feature/1",
+				OldCommitID: "oldCommitID",
+				NewCommitID: git.EmptySHA,
+				Commits:     &models.PushCommits{},
+			},
+			action: models.Action{
+				OpType:  models.ActionDeleteBranch,
+				RefName: "feature/1",
+			},
+		},
+	}
+
+	for _, s := range samples {
+		models.PrepareTestEnv(t)
+
+		user := models.AssertExistsAndLoadBean(t, &models.User{ID: s.userID}).(*models.User)
+		repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: s.repositoryID, OwnerID: user.ID}).(*models.Repository)
+		repo.Owner = user
+
+		s.commitRepoActionOptions.PusherName = user.Name
+		s.commitRepoActionOptions.RepoOwnerID = user.ID
+		s.commitRepoActionOptions.RepoName = repo.Name
+
+		s.action.ActUserID = user.ID
+		s.action.RepoID = repo.ID
+		s.action.Repo = repo
+		s.action.IsPrivate = repo.IsPrivate
+
+		testCorrectRepoAction(t, s.commitRepoActionOptions, &s.action)
+	}
+}
diff --git a/modules/repofiles/update.go b/modules/repofiles/update.go
index 1189704871..21df776060 100644
--- a/modules/repofiles/update.go
+++ b/modules/repofiles/update.go
@@ -497,7 +497,7 @@ func PushUpdate(repo *models.Repository, branch string, opts models.PushUpdateOp
 		commits = models.ListToPushCommits(l)
 	}
 
-	if err := models.CommitRepoAction(models.CommitRepoActionOptions{
+	if err := CommitRepoAction(CommitRepoActionOptions{
 		PusherName:  opts.PusherName,
 		RepoOwnerID: repo.OwnerID,
 		RepoName:    repo.Name,