doc/user/import/mapping/post_migration_mapping.md
{{< details >}}
{{< /details >}}
{{< history >}}
importer_user_mapping and bulk_import_importer_user_mapping. Disabled by default.importer_user_mapping and gitea_user_mapping, and for GitHub with flags named importer_user_mapping and github_user_mapping. Disabled by default.importer_user_mapping and bitbucket_server_user_mapping. Disabled by default.user_mapping_to_personal_namespace_owner. Disabled by default.bulk_import_importer_user_mapping removed.user_mapping_service_account_and_bots.
Enabled by default.gitea_user_mapping removed.user_mapping_to_personal_namespace_owner removed.github_user_mapping feature flag removed in GitLab 18.8.user_mapping_service_account_and_bots feature flag removed in GitLab 18.10.{{< /history >}}
With post-migration mapping, user contributions and memberships from source instances are initially assigned to placeholder users rather than real users on the destination instance.
Because you can defer assigning to real users, you have time to review the import and reassign contributions to the correct users. This process ensures accurate attribution while maintaining control over the mapping process.
Post-migration user contribution and membership mapping is available by default for migrations from:
When you import projects to a personal namespace, user contribution mapping and membership mapping is not supported and all contributions are assigned to the personal namespace owner. These contributions cannot be reassigned.
When using post-migration mapping, GitLab maps any memberships and contributions you import to placeholder users. Placeholder users are created on the destination instance even if users with the same email addresses exist on the destination instance. Until you reassign contributions on the destination instance, all contributions are associated with placeholder users.
After the import is complete and you've reviewed the results, you can update the mappings as follows:
You can also keep certain contributions assigned to placeholder users to preserve historical context.
When you reassign contributions to a user on the destination instance, the user can either:
{{< history >}}
{{< /history >}}
If your top-level group has at least one enterprise user, you can reassign contributions only to enterprise users in your organization.
This means you cannot accidentally reassign to users outside your organization.
Contributions on the source instance that were made by a now deleted user are mapped on the destination instance to a ghost user, except when:
With contribution and membership mapping, you don't immediately assign contributions and memberships to users on the destination instance. Instead, a placeholder user is created for any active, inactive, or bot user with imported contributions or memberships.
Both contributions and memberships are initially assigned to these placeholder users and can be reassigned after import to existing users on the destination instance.
Until they are reassigned, contributions are associated with the placeholder. Placeholder memberships do not display in member lists.
Placeholder users do not count towards license limits.
A placeholder user is not created in these scenarios:
Placeholder users are different to regular users and cannot:
To maintain a connection with a user on a source instance, placeholder users have:
source_user_id) used by the import process to determine if a new placeholder user is required.source_hostname).source_name) to help with reassignment of contributions.source_username) to facilitate group owners during the reassignment of the contribution.import_type) to distinguish which importer created the placeholder.created_at) in local time for migration tracking
(introduced in GitLab 17.10).To preserve historical context, the placeholder user name and username are derived from the source user name and username:
Placeholder <source user name>.%{source_username}_placeholder_user_%{incremental_number}.Prerequisites:
Placeholder users are created on the destination instance while a group or project is imported. To view placeholder users created during imports to a top-level group and its subgroups:
{{< details >}}
{{< /details >}}
{{< history >}}
{{< /history >}}
Prerequisites:
Placeholder users are created on the destination instance while a group or project is imported. To filter for placeholder users created during imports for an entire instance:
Placeholder users are created per import source and per top-level group:
[!note] Placeholder users are associated only with the top-level group. When you delete a subgroup or project, their placeholder users no longer reference any contributions in the top-level group. For testing, you should use a designated top-level group. Deleting placeholder users is proposed in issue 519391 and issue 537340.
When a user accepts the reassignment, subsequent imports from the same source instance to the same top-level group or subgroup on the destination instance do not create placeholder users. Instead, contributions are mapped automatically to the user.
{{< history >}}
{{< /history >}}
When you delete a top-level group that contains placeholder users, these users are automatically scheduled for removal. This process might take some time to complete. However, placeholder users remain in the system if they're also associated with other projects or groups.
[!note] There is no other way to delete placeholder users, but support for improvements is proposed in issue 519391 and issue 537340.
If importing to GitLab.com, placeholder users are limited per top-level group on the destination instance. The limits differ depending on your plan and seat count. Placeholder users do not count towards license limits.
| GitLab.com plan | Number of seats | Placeholder user limit on top-level group |
|---|---|---|
| Free and any trial | Any amount | 200 |
| Premium | < 100 | 500 |
| Premium | 101-500 | 2000 |
| Premium | 501 - 1000 | 4000 |
| Premium | > 1000 | 6000 |
| Ultimate and open source | < 100 | 1000 |
| Ultimate and open source | 101-500 | 4000 |
| Ultimate and open source | 501 - 1000 | 6000 |
| Ultimate and open source | > 1000 | 8000 |
For GitLab Self-Managed and GitLab Dedicated, no placeholder limits apply by default. A GitLab administrator can set a placeholder limit on their instance.
To view your current placeholder user usage and limits:
You cannot determine the number of placeholder users you need in advance.
When the placeholder user limit is reached, all contributions
are assigned to a single non-functional user called Import User.
Contributions assigned to Import User might be deduplicated,
and some contributions might not be created during the import.
For example, if multiple approvals from a merge request approver are assigned
to Import User, only the first approval is created and the others are ignored.
The contributions that might be deduplicated are:
Every change creates a system note, which is not affected by the placeholder user limit.
An alternative to post-migration mapping is a method that maps during a migration. This method is not recommended, and any problems found are unlikely to be fixed.
The alternative method of mapping:
*_user_mapping feature flags.For more information, see the alternative method of mapping documentation for each importer.