Mapping users and contributions after a GitLab import

Imported commits, issues and comments land on placeholder users in GitLab before owners reassign them to real accounts. This page explains how that works, what does not map cleanly, and why placeholder limits matter for large migrations.

On this page

How contribution mapping after a GitLab import works and what it takes

Teams moving repositories and issues into self-managed GitLab need authorship to survive the move, or the history of who wrote what and who reviewed it becomes unreadable. GitLab does not attach imported contributions to real accounts directly. It assigns them to placeholder users first, even when an imported author's email address matches an existing GitLab user, and an owner then reassigns each placeholder to a real user. The real user must accept the reassignment before the contribution is attributed to them. Until that happens, the contribution stays with the placeholder, so the mapping step is part of the migration rather than an optional cleanup.

For the direct transfer, GitHub, Bitbucket Server and Gitea importers, post-migration mapping is on by default. On a self-managed instance, no placeholder limit applies unless an administrator sets one. When a limit is reached, further contributions go to a single non-functional Import User, which means the attribution is lost for those items. Effort therefore scales with three things: the number of people whose contributions must be claimed, the source system (each importer produces its own identity data), and how many contributions need a human decision, such as authors who left the organization or used several accounts. Confirm with your own data how many distinct authors exist in each source before you schedule reviews.

This section covers four sources: GitHub, Bitbucket Server, Gitea, and direct transfer from another GitLab instance. Each one handles identities differently, so the first task is an inventory of source accounts, their emails and their roles, reviewed against the GitLab user list. The GitLab user mapping documentation sets out the exact mapping behavior for each importer, and you should read it against the version you plan to run before deciding who approves reassignments and whether a placeholder limit is needed.

Which contribution types map cleanly to real users and which do not

This table compares common source contribution types with how they land in GitLab before and after placeholder reassignment. Read each row as a starting assumption to test, since behavior can differ by source importer and GitLab version. The main takeaway is that authorship of content usually survives import, while acceptance, review history and memberships need explicit checks in a pilot import.

Contribution typeHow it lands after importReader action
CommitsGit history is pushed with original author names and emails, but commit authors are not linked to user accounts until mappingConfirm author text in a pilot project and check that reassigned commits link to the right user
IssuesCreated under placeholder users first, with original author text kept in the bodyReassign to real users and verify titles, labels and timestamps on a sample set
Comments on issuesPlaceholder authorship until reassigned, and original text is preservedTest threads with mixed authors to confirm attribution after acceptance
Merge or pull requestsCreated with placeholder authors and imported review context where the importer supports itCheck the importer documentation for your source and test an open and a merged request
Reviews and approvalsApproval state and reviewer identity may not carry over as native GitLab approvalsConfirm approval rules are rebuilt and do not assume past sign-off is enforced
Memberships and rolesImported as placeholder membership until a user accepts the reassignmentPlan who must accept before access decisions depend on the imported roles

Documented import paths that carry contribution mapping

GitLab's import documentation lists several source types, and each one reaches the mapping step differently. The cards below cover the documented paths, the behavior to expect on each, and the checks to run before a large batch starts.

GitHub importer

The GitHub importer brings repositories, issues, pull requests and wikis into GitLab. Post-migration mapping is on by default for this path, so imported authors and comment owners start as placeholder users. Before you start, confirm which GitHub objects your team relies on, list the authors who will need reassignment, and decide who in each group will accept or reject those claims. GitHub Actions workflows do not move with the importer and need a separate rewrite.

Bitbucket Server importer

The Bitbucket Server importer maps pull requests, comments and authors into GitLab, and post-migration mapping is on by default for it. Because Bitbucket Server instances often hold years of users, many of whom have left the company, the reassignment list can be long. Export the user list from the source before the run so owners can match people to accounts and identify contributors who will need the Import User fallback.

Bitbucket Cloud importer

The Bitbucket Cloud importer follows its own data model, so the set of objects and contributor records it creates differs from the Server path. Confirm with the GitLab import documentation which pull request and comment details carry across, and test one representative repository before mapping a full workspace. Plan reassignment against the actual placeholder list the import produces, not against an assumed list from the source account directory.

Gitea importer

The Gitea importer moves repositories and issues from a lightweight Git server into GitLab. Teams often run Gitea with local accounts that do not match corporate identities, which makes the placeholder reassignment step the main manual task. Check how many Gitea accounts map to people still in your identity provider, and agree on a rule for accounts that belong to bots or former staff before the run.

Direct transfer from another GitLab

Direct transfer moves groups and projects from one GitLab instance to another and is one of the paths where post-migration mapping is on by default. Because source users can already exist on the destination, check whether your identity setup links them before the transfer so that reassignment is not repeated for people who already have accounts. Confirm the admin setting and the import source configuration on your instance version.

File export and Subversion conversion

File exports carry a package of project data that GitLab imports from a file rather than from a live source. Subversion has no direct importer, so history must first be converted to Git with external tools, and the author identities produced by that conversion become the input to your mapping. Build the author mapping file during conversion, since it determines who the placeholder users represent once the converted repository is imported.

User contribution mapping reference

Each supported path follows the same placeholder model, but the defaults and the exact objects covered depend on the source. Use the user mapping documentation as the reference for the defaults and for the placeholder limit behavior on Self-Managed instances before you run a batch. Record which path you used for each project so later audits can trace who was reassigned and when.

Why placeholder limits matter for large migrations

On a self-managed GitLab instance, no placeholder user limit applies by default. Imported contributions and memberships are assigned to placeholder users first, and the instance keeps creating them as the import runs. For a small import, this default is usually easy to live with, because owners can review and reassign each placeholder in the time available. For a large import, the absence of a limit means the number of placeholders is set by the source data, not by your team's capacity to review them. Confirm the current behavior for your GitLab version in the user mapping documentation before you rely on it.

  • No limit until you set one: administrators can configure a placeholder limit, but nothing stops placeholder creation until that setting exists.
  • Placeholders come before matching: GitLab assigns contributions to placeholders even when a matching email address already exists on the instance.
  • Mapping is on by default for some importers: post-migration mapping is enabled by default for direct transfer, GitHub, Bitbucket Server and Gitea imports.
  • Review scales with source data: the number of placeholders grows with contributors in the source history, not with the number of repositories you planned to move.
  • Ask your administrator to confirm the setting: check the instance configuration and the version in use before the rehearsal import.

Check the default, the setting location and the importer you plan to use on a test instance before you size the reassignment work.

Sequence for mapping users in a pilot, parallel run and cutover

This sequence moves user mapping from a guess to a tested, owned process, so that contributions land on the right GitLab accounts when the source host is switched off. Each phase ends with a checkpoint that the next phase depends on.

  1. Inventory source users and contributors

    Export the list of accounts that authored commits, opened or commented on issues and merge requests, and held project memberships on the source host. Compare each account with the people who will exist in your GitLab identity source, and flag accounts that are bots, former staff, shared logins or contractors. The team lead for the migration owns this list, and your HR or identity team confirms who is current. The step is done when every source account has a named owner or an explicit decision to leave it unmapped.

  2. Confirm user provisioning before importing

    Decide how real users will exist in self-managed GitLab before the first import, through SAML, LDAP, SCIM or manual creation, as your authentication design allows. Reassignment only works against accounts that already exist, so accounts must be provisioned, active and able to sign in before owners are asked to accept contributions. Ask your identity team to confirm the source of truth for each active employee. The checkpoint is a list of active target accounts that matches the inventory from the previous step.

  3. Run a pilot import of representative projects

    Choose a small set of projects that cover your hardest cases: heavy contributor histories, projects with many former members, issues with comments, and at least one project from each source host you plan to import from. Import them into a non-production GitLab instance, using the same importer settings you plan to use at cutover. Compare the imported placeholder users and contribution counts with the source. The checkpoint is a written pilot report that lists which contributions were attributed to placeholders and why.

  4. Test reassignment and acceptance with real owners

    Ask a small group of real users, who represent different roles and contribution histories, to log in and review the placeholder contributions assigned to them. Have each person accept or reject the reassignment, and confirm that accepted contributions display under their accounts. Record any cases where the matching was wrong, where a user declined, or where an account could not be found. The checkpoint is a signed-off list of reassignment outcomes and a decision on how unresolved contributions will be handled.

  5. Set placeholder limits and the import user policy

    On Self-Managed no placeholder limit applies by default, but administrators can set one. Decide whether to set a limit based on the pilot's volume and your number of contributors, and document what happens when it is reached, because remaining contributions go to a single non-functional Import User. Confirm this behavior in the current GitLab user mapping documentation for your version before cutover. The checkpoint is a documented limit value, or a documented decision to run without one, approved by the migration owner.

  6. Run a parallel period

    Keep the source host available for read access while teams begin working in self-managed GitLab on the imported projects. Ask owners to complete reassignment for their contributions during this period and track the number of contributions still on placeholders. Watch for new work that was created on the source after the import, since it will need a second import or manual transfer. The checkpoint is a dated tracker showing the count of unmapped contributions decreasing and a confirmed list of projects that will not receive further changes on the source.

  7. Perform cutover and decommission the source

    Freeze writes on the source host, run the final import of any changes made since the last pass, and repeat the reassignment check for new contributions. Confirm with project owners that the accepted mappings are correct, then switch developers' remotes and links to the self-managed instance. Keep the source in read-only mode until the mapping report is archived. The step is done when the cutover record shows that all projects are imported, all remaining placeholder contributions have an owner, and the source host has been decommissioned under your retention policy.

What drives the effort of contribution mapping

This table compares the main drivers of mapping effort after a GitLab import, who typically carries each piece of work, and whether it is one-time or recurring. Read it before scoping, because the largest effort usually comes from owner review time and historical authors who have left, not from the import itself.

DriverWhy it changes effortWho usually paysOne-time or recurring
Number of source usersEach historical author becomes a placeholder that someone must match to a real account or leave unassigned, so effort grows with the author list.Internal owners for review, partner for scripted matching if scopedOne-time
Contributions per projectHeavy history means more commits, issues and comments to check, especially where a few authors dominate and others are one-off.Partner for analysis and reporting, internal owners for sign-offOne-time
Whether emails matchMatching emails can point placeholders at real accounts, but GitLab still assigns to placeholders first, so matches must be confirmed by someone.Internal owners, with partner support for match reportsOne-time
Share of authors who leftFormer staff cannot accept reassignments, so their contributions need a decision on whether to keep the placeholder, reassign to an owner or leave as is.Internal HR and engineering leads, with an owner decision recordedOne-time, with ongoing questions from new requests
Placeholder limit settingOn Self-Managed no limit applies by default, but a set limit can send later contributions to a single non-functional Import User, which needs cleanup.Internal GitLab administrators decide, partner may configureSetting is ongoing, cleanup is one-time
Number of owners who must reviewMore owners means more coordination, more handoffs and more places where acceptances are missed or delayed.Internal project and group ownersOne-time during cutover, then occasional
Accept and reject follow-upUsers must accept or reject reassignments themselves, so unanswered invitations keep work open after the import.Internal users and ownersRecurring until closed

What usually goes wrong with contribution mapping and how to prevent it

Most contribution mapping problems come from placeholder users that never get claimed, limits that quietly redirect work, and source systems that keep changing while the import runs. Each card below names one failure, what it looks like in the GitLab instance, and the check that catches it before cutover.

Contributions landing on the Import User

If you set a placeholder user limit and the import reaches it, remaining contributions go to a single non-functional Import User instead of named placeholders. Those commits, issues and comments then lose their individual authorship in the instance. Before the import, decide whether a limit is needed at all, set it deliberately, and compare the placeholder count from a dry run against the limit so the cap is not hit in production.

Unreassigned placeholders blocking ownership

Placeholder users hold contributions and memberships until an owner reassigns them, so projects can show authors and assignees who have no real account. Ownership and approval workflows that depend on those people stall. Assign a named owner for the reassignment queue, and review the list of unreassigned placeholders on each project before the cutover date is set.

Mismatched emails

GitLab assigns imported contributions to placeholders even when a matching email address already exists, so matching does not happen silently. Owners then have to reassign each placeholder by hand, and a wrong match can attach history to the wrong person. Export the source author list with email addresses, compare it against the directory, and resolve duplicates such as personal and work addresses before reassignment starts.

Departed authors with no reachable account

Former employees and contractors often hold a large share of historical commits and reviews, and their placeholders may never be claimed. Decide in advance whether those contributions stay attributed to a placeholder, move to a team or service account, or are recorded in a documented mapping file. Ask the business owner to sign off on that rule so the decision is not made project by project.

Reassignments nobody accepts

A reassignment is a proposal: the real user must accept it before the contributions are attributed to them. Reassignments that stay pending leave history looking unclaimed, even though the owner did the work. Send acceptance requests with a deadline, give users a short guide to accepting them, and track the pending count as a cutover metric rather than assuming the work is done once the reassignment is sent.

Running the source system in parallel without a freeze

If developers keep pushing, commenting and merging on the source host during the import, new contributions arrive after the mapping was prepared and need their own reassignment. Freezing writes on the source for the import window and documenting the cutover time keeps the mapped set stable. Confirm with the source team which activities are blocked, and plan a delta import only where your chosen method supports it.

Questions buyers ask about user mapping after a GitLab import

What drives the cost of user mapping after a GitLab import?

The main driver is the number of placeholder users and the number of contributions that need an owner's decision. Each imported contribution is first attached to a placeholder user, so a repository history with many authors creates more reassignment work than a small project with a few. Cost also depends on how many people must confirm their own mappings, how much cleanup your identity data needs before the import, and whether your team or a partner does the coordination. Ask any partner for a written scope that lists the import sources, the approximate number of users and repositories, the placeholder limit you plan to set, and who will contact each contributor. Mapping work is largely one-time for each import wave, while later support requests tend to be small.

How long does user mapping take after an import?

The duration depends less on the tooling than on how fast project owners and contributors respond. GitLab attaches imported work to placeholder users, and an owner then reassigns each one to a real user, who must accept or reject it. Teams with a small number of projects and responsive owners can finish quickly, while large organizations with many contributors who have left, changed teams or use several email addresses take longer. Plan the mapping window as its own phase after the import, and confirm with your partner or internal team how they will track which placeholders remain open at each cutover milestone.

What must our team provide before mapping users?

Before the import, prepare a current list of users from your source system with their names, usernames and email addresses, and mark people who have left or changed roles. Confirm who owns each project or group, since owners perform reassignment and need time to do it. Decide whether your instance will set a placeholder user limit, and what should happen when the limit is reached. Also confirm how your GitLab users will sign in, because accepted mappings are tied to accounts that exist in your instance. Owners should be available during the mapping window, and someone should be named to answer contributor questions.

Can our internal engineers handle user mapping without a partner?

Yes, if you have enough capacity and clear ownership. The work is mostly coordination and administration: preparing user lists, checking import results, asking owners to reassign placeholders and tracking acceptances. Internal teams with a small number of repositories and an engaged set of owners often manage it alone. A partner can help when the volume is large, when the source system has many inactive or duplicate accounts, or when the mapping must be completed on a fixed schedule. Whichever route you choose, agree on who makes the final decisions about contributors who cannot be matched.

What happens to contributions that nobody accepts?

Contributions that are never reassigned and accepted remain attached to placeholder users. Ownership of that history stays with the placeholder rather than moving to an active account, so the record of who wrote the work is incomplete. If you set a placeholder user limit and it is reached, further contributions go to a single non-functional Import User instead of separate placeholders. Decide in advance how long the mapping window stays open, who reviews unclaimed placeholders, and whether unclaimed history is acceptable for audit or licensing purposes. Ask your compliance team whether attribution gaps must be documented.

Why do placeholder limits matter for large migrations?

Placeholder limits control how many placeholder users the import can create. On Self-Managed instances no limit applies by default, but administrators can set one. When a limit is reached, contributions are assigned to one non-functional Import User, which means those contributions cannot be individually reassigned to real people through the normal placeholder flow. For a large migration with many historical authors, set the limit deliberately, estimate the placeholder count from your source data before import, and test the limit on a single repository first. Confirm the exact behavior for your GitLab version in the official mapping documentation before you rely on it.

Does user mapping require a particular GitLab license tier?

User mapping is part of the import feature set and is not described in the supplied facts as tier-specific, so confirm it with your GitLab account team or the documentation for your version before you plan around it. Licensing matters separately because the number of billed users in your instance affects cost. Placeholder users are not the same as billed seats, so ask your partner and GitLab how imported placeholders are counted before the import starts. Premium lists a price of 29 US dollars per user per month billed annually, as stated on GitLab's pricing page, but the pricing page does not settle how placeholders are counted.

How DeployOpen scopes and delivers a GitLab import with user mapping

DeployOpen starts every GitLab import with a written, fixed scope that names the source systems, the number of projects and groups, the contribution history to be preserved and the people who will sign off on reassignment. The first phase is an inventory: which repositories, issues, merge requests and memberships exist on the source, which authors appear in commit history, and how many of those authors still have active accounts in your identity provider. That inventory decides the placeholder limit question. On Self-Managed no placeholder user limit applies by default, but administrators can set one, and when the limit is reached further contributions go to a single non-functional Import User. DeployOpen recommends that you decide the limit, and who approves any exceptions, before the pilot runs, and confirm the setting in your own instance before the first production batch.

The pilot imports a representative subset of projects, including one with heavy contribution history and one with unusual membership, so the team can test reassignment end to end. Your project owners reassign placeholder users to real accounts, and each reassigned user accepts or rejects the mapping, so the pilot must include people who can actually do this in your environment. DeployOpen documents the reassignment outcome per project, supports the owners through the process and records which contributions remain unassigned. A parallel run then keeps the source system read-only or mirrored while the team checks imported data against it, followed by a cutover that is scheduled and communicated in advance. Ongoing support, including upgrades and help with late reassignment requests, is available as a retainer after the import closes.

DeployOpen does not publish a price list. A quote follows from the written scope, so it reflects the number of source instances, projects, contributors, identity integrations and the decisions still open at the start. Ask for the cost of each phase separately, which parts are one-time (inventory, pilot, cutover) and which recur (retainer support), and what changes if the placeholder limit or the number of reassignment rounds changes. Ask also who on your side owns each approval, because delays in acceptance are a common cause of extended timelines.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.