diff --git a/models/fixtures/repo_unit.yml b/models/fixtures/repo_unit.yml
index c22eb8c2a2..98b1f47401 100644
--- a/models/fixtures/repo_unit.yml
+++ b/models/fixtures/repo_unit.yml
@@ -649,3 +649,10 @@
   repo_id: 49
   type: 2
   created_unix: 946684810
+
+-
+  id: 98
+  repo_id: 59
+  type: 1
+  config: "{}"
+  created_unix: 946684810
diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml
index 373c1caa62..f4e8376735 100644
--- a/models/fixtures/repository.yml
+++ b/models/fixtures/repository.yml
@@ -1693,3 +1693,16 @@
   size: 0
   is_fsck_enabled: true
   close_issues_via_commit_in_any_branch: false
+
+-
+  id: 59
+  owner_id: 2
+  owner_name: user2
+  lower_name: test_commit_revert
+  name: test_commit_revert
+  default_branch: main
+  is_empty: false
+  is_archived: false
+  is_private: true
+  status: 0
+  num_issues: 0
diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml
index fd51379816..79fbb981f6 100644
--- a/models/fixtures/user.yml
+++ b/models/fixtures/user.yml
@@ -66,7 +66,7 @@
   num_followers: 2
   num_following: 1
   num_stars: 2
-  num_repos: 14
+  num_repos: 15
   num_teams: 0
   num_members: 0
   visibility: 0
diff --git a/services/packages/cargo/index.go b/services/packages/cargo/index.go
index 8164ffb01c..e580de2fe0 100644
--- a/services/packages/cargo/index.go
+++ b/services/packages/cargo/index.go
@@ -267,7 +267,7 @@ func alterRepositoryContent(ctx context.Context, doer *user_model.User, repo *re
 	defer t.Close()
 
 	var lastCommitID string
-	if err := t.Clone(repo.DefaultBranch); err != nil {
+	if err := t.Clone(repo.DefaultBranch, true); err != nil {
 		if !git.IsErrBranchNotExist(err) || !repo.IsEmpty {
 			return err
 		}
diff --git a/services/repository/files/cherry_pick.go b/services/repository/files/cherry_pick.go
index c1c5bfb617..5e9a0900a7 100644
--- a/services/repository/files/cherry_pick.go
+++ b/services/repository/files/cherry_pick.go
@@ -31,12 +31,15 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod
 		log.Error("%v", err)
 	}
 	defer t.Close()
-	if err := t.Clone(opts.OldBranch); err != nil {
+	if err := t.Clone(opts.OldBranch, false); err != nil {
 		return nil, err
 	}
 	if err := t.SetDefaultIndex(); err != nil {
 		return nil, err
 	}
+	if err := t.RefreshIndex(); err != nil {
+		return nil, err
+	}
 
 	// Get the commit of the original branch
 	commit, err := t.GetBranchCommit(opts.OldBranch)
diff --git a/services/repository/files/diff.go b/services/repository/files/diff.go
index 373249b114..bf8b938e21 100644
--- a/services/repository/files/diff.go
+++ b/services/repository/files/diff.go
@@ -21,7 +21,7 @@ func GetDiffPreview(ctx context.Context, repo *repo_model.Repository, branch, tr
 		return nil, err
 	}
 	defer t.Close()
-	if err := t.Clone(branch); err != nil {
+	if err := t.Clone(branch, true); err != nil {
 		return nil, err
 	}
 	if err := t.SetDefaultIndex(); err != nil {
diff --git a/services/repository/files/patch.go b/services/repository/files/patch.go
index fdf0b32f1a..5bd59251df 100644
--- a/services/repository/files/patch.go
+++ b/services/repository/files/patch.go
@@ -108,7 +108,7 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user
 		log.Error("%v", err)
 	}
 	defer t.Close()
-	if err := t.Clone(opts.OldBranch); err != nil {
+	if err := t.Clone(opts.OldBranch, true); err != nil {
 		return nil, err
 	}
 	if err := t.SetDefaultIndex(); err != nil {
diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go
index 7f6b8137ae..4c8cfb2481 100644
--- a/services/repository/files/temp_repo.go
+++ b/services/repository/files/temp_repo.go
@@ -51,8 +51,13 @@ func (t *TemporaryUploadRepository) Close() {
 }
 
 // Clone the base repository to our path and set branch as the HEAD
-func (t *TemporaryUploadRepository) Clone(branch string) error {
-	if _, _, err := git.NewCommand(t.ctx, "clone", "-s", "--bare", "-b").AddDynamicArguments(branch, t.repo.RepoPath(), t.basePath).RunStdString(nil); err != nil {
+func (t *TemporaryUploadRepository) Clone(branch string, bare bool) error {
+	cmd := git.NewCommand(t.ctx, "clone", "-s", "-b").AddDynamicArguments(branch, t.repo.RepoPath(), t.basePath)
+	if bare {
+		cmd.AddArguments("--bare")
+	}
+
+	if _, _, err := cmd.RunStdString(nil); err != nil {
 		stderr := err.Error()
 		if matched, _ := regexp.MatchString(".*Remote branch .* not found in upstream origin.*", stderr); matched {
 			return git.ErrBranchNotExist{
@@ -98,6 +103,14 @@ func (t *TemporaryUploadRepository) SetDefaultIndex() error {
 	return nil
 }
 
+// RefreshIndex looks at the current index and checks to see if merges or updates are needed by checking stat() information.
+func (t *TemporaryUploadRepository) RefreshIndex() error {
+	if _, _, err := git.NewCommand(t.ctx, "update-index", "--refresh").RunStdString(&git.RunOpts{Dir: t.basePath}); err != nil {
+		return fmt.Errorf("RefreshIndex: %w", err)
+	}
+	return nil
+}
+
 // LsFiles checks if the given filename arguments are in the index
 func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, error) {
 	stdOut := new(bytes.Buffer)
diff --git a/services/repository/files/update.go b/services/repository/files/update.go
index f01092d360..9d32876eff 100644
--- a/services/repository/files/update.go
+++ b/services/repository/files/update.go
@@ -141,7 +141,7 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
 	}
 	defer t.Close()
 	hasOldBranch := true
-	if err := t.Clone(opts.OldBranch); err != nil {
+	if err := t.Clone(opts.OldBranch, true); err != nil {
 		for _, file := range opts.Files {
 			if file.Operation == "delete" {
 				return nil, err
diff --git a/services/repository/files/upload.go b/services/repository/files/upload.go
index f4e1da7bb1..c893c5c43e 100644
--- a/services/repository/files/upload.go
+++ b/services/repository/files/upload.go
@@ -87,7 +87,7 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
 	defer t.Close()
 
 	hasOldBranch := true
-	if err = t.Clone(opts.OldBranch); err != nil {
+	if err = t.Clone(opts.OldBranch, true); err != nil {
 		if !git.IsErrBranchNotExist(err) || !repo.IsEmpty {
 			return err
 		}
diff --git a/tests/gitea-repositories-meta/user2/test_commit_revert.git/HEAD b/tests/gitea-repositories-meta/user2/test_commit_revert.git/HEAD
new file mode 100644
index 0000000000..b870d82622
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/test_commit_revert.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/main
diff --git a/tests/gitea-repositories-meta/user2/test_commit_revert.git/config b/tests/gitea-repositories-meta/user2/test_commit_revert.git/config
new file mode 100644
index 0000000000..57bbcba5be
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/test_commit_revert.git/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+	ignorecase = true
+	precomposeunicode = true
+[remote "origin"]
+	url = https://try.gitea.io/me-heer/test_commit_revert.git
diff --git a/tests/gitea-repositories-meta/user2/test_commit_revert.git/description b/tests/gitea-repositories-meta/user2/test_commit_revert.git/description
new file mode 100644
index 0000000000..498b267a8c
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/test_commit_revert.git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/tests/gitea-repositories-meta/user2/test_commit_revert.git/info/exclude b/tests/gitea-repositories-meta/user2/test_commit_revert.git/info/exclude
new file mode 100644
index 0000000000..a5196d1be8
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/test_commit_revert.git/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/tests/gitea-repositories-meta/user2/test_commit_revert.git/objects/pack/pack-91200c8e6707636a6cc3e0d8101fba08b19dcb91.idx b/tests/gitea-repositories-meta/user2/test_commit_revert.git/objects/pack/pack-91200c8e6707636a6cc3e0d8101fba08b19dcb91.idx
new file mode 100644
index 0000000000..77bcbe7fb4
Binary files /dev/null and b/tests/gitea-repositories-meta/user2/test_commit_revert.git/objects/pack/pack-91200c8e6707636a6cc3e0d8101fba08b19dcb91.idx differ
diff --git a/tests/gitea-repositories-meta/user2/test_commit_revert.git/objects/pack/pack-91200c8e6707636a6cc3e0d8101fba08b19dcb91.pack b/tests/gitea-repositories-meta/user2/test_commit_revert.git/objects/pack/pack-91200c8e6707636a6cc3e0d8101fba08b19dcb91.pack
new file mode 100644
index 0000000000..7271cdaeb8
Binary files /dev/null and b/tests/gitea-repositories-meta/user2/test_commit_revert.git/objects/pack/pack-91200c8e6707636a6cc3e0d8101fba08b19dcb91.pack differ
diff --git a/tests/gitea-repositories-meta/user2/test_commit_revert.git/packed-refs b/tests/gitea-repositories-meta/user2/test_commit_revert.git/packed-refs
new file mode 100644
index 0000000000..1f546d7fd5
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/test_commit_revert.git/packed-refs
@@ -0,0 +1,3 @@
+# pack-refs with: peeled fully-peeled sorted 
+46aa6ab2c881ae90e15d9ccfc947d1625c892ce5 refs/heads/develop
+deebcbc752e540bab4ce3ee713d3fc8fdc35b2f7 refs/heads/main
diff --git a/tests/integration/repo_mergecommit_revert_test.go b/tests/integration/repo_mergecommit_revert_test.go
new file mode 100644
index 0000000000..4d612bdcdb
--- /dev/null
+++ b/tests/integration/repo_mergecommit_revert_test.go
@@ -0,0 +1,34 @@
+package integration
+
+import (
+	"net/http"
+	"testing"
+
+	"code.gitea.io/gitea/tests"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRepoMergeCommitRevert(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	session := loginUser(t, "user2")
+
+	req := NewRequest(t, "GET", "/user2/test_commit_revert/_cherrypick/deebcbc752e540bab4ce3ee713d3fc8fdc35b2f7/main?ref=main&refType=branch&cherry-pick-type=revert")
+	resp := session.MakeRequest(t, req, http.StatusOK)
+
+	htmlDoc := NewHTMLParser(t, resp.Body)
+	req = NewRequestWithValues(t, "POST", "/user2/test_commit_revert/_cherrypick/deebcbc752e540bab4ce3ee713d3fc8fdc35b2f7/main", map[string]string{
+		"_csrf":           htmlDoc.GetCSRF(),
+		"last_commit":     "deebcbc752e540bab4ce3ee713d3fc8fdc35b2f7",
+		"page_has_posted": "true",
+		"revert":          "true",
+		"commit_summary":  "reverting test commit",
+		"commit_message":  "test message",
+		"commit_choice":   "direct",
+		"new_branch_name": "test-revert-branch-1",
+	})
+	resp = session.MakeRequest(t, req, http.StatusSeeOther)
+
+	// A successful revert redirects to the main branch
+	assert.EqualValues(t, "/user2/test_commit_revert/src/branch/main", resp.Header().Get("Location"))
+}