diff --git a/models/access.go b/models/access.go
index 3cdfc62f2..213efe08a 100644
--- a/models/access.go
+++ b/models/access.go
@@ -246,6 +246,55 @@ func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err
 	return repo.refreshAccesses(e, accessMap)
 }
 
+// recalculateUserAccess recalculates new access for a single user
+// Usable if we know access only affected one user
+func (repo *Repository) recalculateUserAccess(e Engine, uid int64) (err error) {
+	minMode := AccessModeRead
+	if !repo.IsPrivate {
+		minMode = AccessModeWrite
+	}
+
+	accessMode := AccessModeNone
+	collaborator, err := repo.getCollaboration(e, uid)
+	if err != nil {
+		return err
+	} else if collaborator != nil {
+		accessMode = collaborator.Mode
+	}
+
+	if err = repo.getOwner(e); err != nil {
+		return err
+	} else if repo.Owner.IsOrganization() {
+		var teams []Team
+		if err := e.Join("INNER", "team_repo", "team_repo.team_id = team.id").
+			Join("INNER", "team_user", "team_user.team_id = team.id").
+			Where("team.org_id = ?", repo.OwnerID).
+			And("team_repo.repo_id=?", repo.ID).
+			And("team_user.uid=?", uid).
+			Find(&teams); err != nil {
+			return err
+		}
+
+		for _, t := range teams {
+			if t.IsOwnerTeam() {
+				t.Authorize = AccessModeOwner
+			}
+
+			accessMode = maxAccessMode(accessMode, t.Authorize)
+		}
+	}
+
+	// Delete old user accesses and insert new one for repository.
+	if _, err = e.Delete(&Access{RepoID: repo.ID, UserID: uid}); err != nil {
+		return fmt.Errorf("delete old user accesses: %v", err)
+	} else if accessMode >= minMode {
+		if _, err = e.Insert(&Access{RepoID: repo.ID, UserID: uid, Mode: accessMode}); err != nil {
+			return fmt.Errorf("insert new user accesses: %v", err)
+		}
+	}
+	return nil
+}
+
 func (repo *Repository) recalculateAccesses(e Engine) error {
 	if repo.Owner.IsOrganization() {
 		return repo.recalculateTeamAccesses(e, 0)
diff --git a/models/org_team.go b/models/org_team.go
index 9170ea2c2..10d53e3a8 100644
--- a/models/org_team.go
+++ b/models/org_team.go
@@ -723,7 +723,7 @@ func AddTeamMember(team *Team, userID int64) error {
 
 	// Give access to team repositories.
 	for _, repo := range team.Repos {
-		if err := repo.recalculateTeamAccesses(sess, 0); err != nil {
+		if err := repo.recalculateUserAccess(sess, userID); err != nil {
 			return err
 		}
 		if setting.Service.AutoWatchNewRepos {
@@ -768,7 +768,7 @@ func removeTeamMember(e *xorm.Session, team *Team, userID int64) error {
 
 	// Delete access to team repositories.
 	for _, repo := range team.Repos {
-		if err := repo.recalculateTeamAccesses(e, 0); err != nil {
+		if err := repo.recalculateUserAccess(e, userID); err != nil {
 			return err
 		}
 
diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go
index 40ddf6a28..3d6447c19 100644
--- a/models/repo_collaboration.go
+++ b/models/repo_collaboration.go
@@ -41,12 +41,7 @@ func (repo *Repository) AddCollaborator(u *User) error {
 		return err
 	}
 
-	if repo.Owner.IsOrganization() {
-		err = repo.recalculateTeamAccesses(sess, 0)
-	} else {
-		err = repo.recalculateAccesses(sess)
-	}
-	if err != nil {
+	if err = repo.recalculateUserAccess(sess, u.ID); err != nil {
 		return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err)
 	}
 
@@ -89,6 +84,18 @@ func (repo *Repository) GetCollaborators() ([]*Collaborator, error) {
 	return repo.getCollaborators(x)
 }
 
+func (repo *Repository) getCollaboration(e Engine, uid int64) (*Collaboration, error) {
+	collaboration := &Collaboration{
+		RepoID: repo.ID,
+		UserID: uid,
+	}
+	has, err := e.Get(collaboration)
+	if !has {
+		collaboration = nil
+	}
+	return collaboration, err
+}
+
 func (repo *Repository) isCollaborator(e Engine, userID int64) (bool, error) {
 	return e.Get(&Collaboration{RepoID: repo.ID, UserID: userID})
 }