diff --git a/integrations/dump_restore_test.go b/integrations/dump_restore_test.go
index c0e583293c..57968618bc 100644
--- a/integrations/dump_restore_test.go
+++ b/integrations/dump_restore_test.go
@@ -129,6 +129,7 @@ func TestDumpRestore(t *testing.T) {
 				assert.EqualValues(t, before[i].Created, after[i].Created)
 				assert.EqualValues(t, before[i].Updated, after[i].Updated)
 				assert.EqualValues(t, before[i].Labels, after[i].Labels)
+				assert.EqualValues(t, before[i].Reactions, after[i].Reactions)
 			}
 		}
 	})
diff --git a/models/user/user.go b/models/user/user.go
index 38352fe5e2..5ed850bdfa 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -1025,6 +1025,19 @@ func GetUserNamesByIDs(ids []int64) ([]string, error) {
 	return unames, err
 }
 
+// GetUserNameByID returns username for the id
+func GetUserNameByID(ctx context.Context, id int64) (string, error) {
+	var name string
+	has, err := db.GetEngine(db.DefaultContext).Table("user").Where("id = ?", id).Cols("name").Get(&name)
+	if err != nil {
+		return "", err
+	}
+	if has {
+		return name, nil
+	}
+	return "", nil
+}
+
 // GetUserIDsByNames returns a slice of ids corresponds to names.
 func GetUserIDsByNames(names []string, ignoreNonExistent bool) ([]int64, error) {
 	ids := make([]int64, 0, len(names))
diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go
index da085c0d8d..8f0505afc5 100644
--- a/services/migrations/gitea_uploader.go
+++ b/services/migrations/gitea_uploader.go
@@ -46,6 +46,7 @@ type GiteaLocalUploader struct {
 	issues         map[int64]*models.Issue
 	gitRepo        *git.Repository
 	prHeadCache    map[string]struct{}
+	sameApp        bool
 	userMap        map[int64]int64 // external user id mapping to user id
 	prCache        map[int64]*models.PullRequest
 	gitServiceType structs.GitServiceType
@@ -128,6 +129,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
 		MirrorInterval: opts.MirrorInterval,
 	}, NewMigrationHTTPTransport())
 
+	g.sameApp = strings.HasPrefix(repo.OriginalURL, setting.AppURL)
 	g.repo = r
 	if err != nil {
 		return err
@@ -256,7 +258,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
 			CreatedUnix:  timeutil.TimeStamp(release.Created.Unix()),
 		}
 
-		if err := g.remapExternalUser(release, &rel); err != nil {
+		if err := g.remapUser(release, &rel); err != nil {
 			return err
 		}
 
@@ -373,7 +375,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
 			UpdatedUnix: timeutil.TimeStamp(issue.Updated.Unix()),
 		}
 
-		if err := g.remapExternalUser(issue, &is); err != nil {
+		if err := g.remapUser(issue, &is); err != nil {
 			return err
 		}
 
@@ -386,7 +388,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
 				Type:        reaction.Content,
 				CreatedUnix: timeutil.TimeStampNow(),
 			}
-			if err := g.remapExternalUser(reaction, &res); err != nil {
+			if err := g.remapUser(reaction, &res); err != nil {
 				return err
 			}
 			is.Reactions = append(is.Reactions, &res)
@@ -437,7 +439,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {
 			UpdatedUnix: timeutil.TimeStamp(comment.Updated.Unix()),
 		}
 
-		if err := g.remapExternalUser(comment, &cm); err != nil {
+		if err := g.remapUser(comment, &cm); err != nil {
 			return err
 		}
 
@@ -447,7 +449,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {
 				Type:        reaction.Content,
 				CreatedUnix: timeutil.TimeStampNow(),
 			}
-			if err := g.remapExternalUser(reaction, &res); err != nil {
+			if err := g.remapUser(reaction, &res); err != nil {
 				return err
 			}
 			cm.Reactions = append(cm.Reactions, &res)
@@ -471,7 +473,7 @@ func (g *GiteaLocalUploader) CreatePullRequests(prs ...*base.PullRequest) error
 			return err
 		}
 
-		if err := g.remapExternalUser(pr, gpr.Issue); err != nil {
+		if err := g.remapUser(pr, gpr.Issue); err != nil {
 			return err
 		}
 
@@ -626,7 +628,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
 		UpdatedUnix: timeutil.TimeStamp(pr.Updated.Unix()),
 	}
 
-	if err := g.remapExternalUser(pr, &issue); err != nil {
+	if err := g.remapUser(pr, &issue); err != nil {
 		return nil, err
 	}
 
@@ -636,7 +638,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
 			Type:        reaction.Content,
 			CreatedUnix: timeutil.TimeStampNow(),
 		}
-		if err := g.remapExternalUser(reaction, &res); err != nil {
+		if err := g.remapUser(reaction, &res); err != nil {
 			return nil, err
 		}
 		issue.Reactions = append(issue.Reactions, &res)
@@ -710,7 +712,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
 			UpdatedUnix: timeutil.TimeStamp(review.CreatedAt.Unix()),
 		}
 
-		if err := g.remapExternalUser(review, &cm); err != nil {
+		if err := g.remapUser(review, &cm); err != nil {
 			return err
 		}
 
@@ -773,7 +775,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
 				UpdatedUnix: timeutil.TimeStamp(comment.UpdatedAt.Unix()),
 			}
 
-			if err := g.remapExternalUser(review, &c); err != nil {
+			if err := g.remapUser(review, &c); err != nil {
 				return err
 			}
 
@@ -816,23 +818,52 @@ func (g *GiteaLocalUploader) Finish() error {
 	return repo_model.UpdateRepositoryCols(g.repo, "status")
 }
 
-func (g *GiteaLocalUploader) remapExternalUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) (err error) {
-	userid, ok := g.userMap[source.GetExternalID()]
-	tp := g.gitServiceType.Name()
-	if !ok && tp != "" {
-		userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%d", source.GetExternalID()))
-		if err != nil {
-			log.Error("GetUserIDByExternalUserID: %v", err)
-		}
-		if userid > 0 {
-			g.userMap[source.GetExternalID()] = userid
-		}
+func (g *GiteaLocalUploader) remapUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) error {
+	var userid int64
+	var err error
+	if g.sameApp {
+		userid, err = g.remapLocalUser(source, target)
+	} else {
+		userid, err = g.remapExternalUser(source, target)
+	}
+
+	if err != nil {
+		return err
 	}
 
 	if userid > 0 {
-		err = target.RemapExternalUser("", 0, userid)
-	} else {
-		err = target.RemapExternalUser(source.GetExternalName(), source.GetExternalID(), g.doer.ID)
+		return target.RemapExternalUser("", 0, userid)
 	}
-	return
+	return target.RemapExternalUser(source.GetExternalName(), source.GetExternalID(), g.doer.ID)
+}
+
+func (g *GiteaLocalUploader) remapLocalUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) (int64, error) {
+	userid, ok := g.userMap[source.GetExternalID()]
+	if !ok {
+		name, err := user_model.GetUserNameByID(g.ctx, source.GetExternalID())
+		if err != nil {
+			return 0, err
+		}
+		// let's not reuse an ID when the user was deleted or has a different user name
+		if name != source.GetExternalName() {
+			userid = 0
+		} else {
+			userid = source.GetExternalID()
+		}
+		g.userMap[source.GetExternalID()] = userid
+	}
+	return userid, nil
+}
+
+func (g *GiteaLocalUploader) remapExternalUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) (userid int64, err error) {
+	userid, ok := g.userMap[source.GetExternalID()]
+	if !ok {
+		userid, err = user_model.GetUserIDByExternalUserID(g.gitServiceType.Name(), fmt.Sprintf("%d", source.GetExternalID()))
+		if err != nil {
+			log.Error("GetUserIDByExternalUserID: %v", err)
+			return 0, err
+		}
+		g.userMap[source.GetExternalID()] = userid
+	}
+	return userid, nil
 }
diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go
index 7552245d74..0a35b5a632 100644
--- a/services/migrations/gitea_uploader_test.go
+++ b/services/migrations/gitea_uploader_test.go
@@ -117,6 +117,56 @@ func TestGiteaUploadRepo(t *testing.T) {
 	assert.Len(t, pulls[0].Issue.Comments, 2)
 }
 
+func TestGiteaUploadRemapLocalUser(t *testing.T) {
+	unittest.PrepareTestEnv(t)
+	doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+
+	repoName := "migrated"
+	uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName)
+	// call remapLocalUser
+	uploader.sameApp = true
+
+	externalID := int64(1234567)
+	externalName := "username"
+	source := base.Release{
+		PublisherID:   externalID,
+		PublisherName: externalName,
+	}
+
+	//
+	// The externalID does not match any existing user, everything
+	// belongs to the doer
+	//
+	target := models.Release{}
+	uploader.userMap = make(map[int64]int64)
+	err := uploader.remapUser(&source, &target)
+	assert.NoError(t, err)
+	assert.EqualValues(t, doer.ID, target.GetUserID())
+
+	//
+	// The externalID matches a known user but the name does not match,
+	// everything belongs to the doer
+	//
+	source.PublisherID = user.ID
+	target = models.Release{}
+	uploader.userMap = make(map[int64]int64)
+	err = uploader.remapUser(&source, &target)
+	assert.NoError(t, err)
+	assert.EqualValues(t, doer.ID, target.GetUserID())
+
+	//
+	// The externalID and externalName match an existing user, everything
+	// belongs to the existing user
+	//
+	source.PublisherName = user.Name
+	target = models.Release{}
+	uploader.userMap = make(map[int64]int64)
+	err = uploader.remapUser(&source, &target)
+	assert.NoError(t, err)
+	assert.EqualValues(t, user.ID, target.GetUserID())
+}
+
 func TestGiteaUploadRemapExternalUser(t *testing.T) {
 	unittest.PrepareTestEnv(t)
 	doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
@@ -124,9 +174,11 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
 	repoName := "migrated"
 	uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName)
 	uploader.gitServiceType = structs.GiteaService
+	// call remapExternalUser
+	uploader.sameApp = false
 
 	externalID := int64(1234567)
-	externalName := "url.or.something"
+	externalName := "username"
 	source := base.Release{
 		PublisherID:   externalID,
 		PublisherName: externalName,
@@ -136,8 +188,9 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
 	// When there is no user linked to the external ID, the migrated data is authored
 	// by the doer
 	//
+	uploader.userMap = make(map[int64]int64)
 	target := models.Release{}
-	err := uploader.remapExternalUser(&source, &target)
+	err := uploader.remapUser(&source, &target)
 	assert.NoError(t, err)
 	assert.EqualValues(t, doer.ID, target.GetUserID())
 
@@ -158,8 +211,9 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
 	// When a user is linked to the external ID, it becomes the author of
 	// the migrated data
 	//
+	uploader.userMap = make(map[int64]int64)
 	target = models.Release{}
-	err = uploader.remapExternalUser(&source, &target)
+	err = uploader.remapUser(&source, &target)
 	assert.NoError(t, err)
-	assert.EqualValues(t, target.GetUserID(), linkedUser.ID)
+	assert.EqualValues(t, linkedUser.ID, target.GetUserID())
 }