vcspull import gitlab

Import repositories from GitLab or a self-hosted GitLab instance.

Command

Import repositories from GitLab (gitlab.com or self-hosted).

Usage

usage: vcspull import gitlab [-h] [-w DIR] [-l LANG] [--topics TOPICS]
                             [--min-stars N] [--archived] [--forks]
                             [--limit N] [-f FILE] [--dry-run] [--yes]
                             [--json] [--ndjson] [--https] [--sync] [--prune]
                             [--prune-untracked] [--color {auto,always,never}]
                             [--token TOKEN] [-m {user,org,search}]
                             [--url URL] [--flatten-groups] [--with-shared]
                             [--skip-group GROUP]
                             TARGET

Positional Arguments

target TARGET

User, org name, or search query. For GitLab, supports subgroups with slash notation (e.g., parent/child).

Default
None
Required

Options

-w, --workspace DIR

Workspace root directory (REQUIRED)

Default
None
--token TOKEN

API token (overrides env var; prefer env var for security)

Default
None
-m, --mode

Import mode: user (default), org, or search

Default
user
Choices
user, org, search
--url URL

Base URL for self-hosted GitLab (optional)

Default
None
--flatten-groups

For ``--mode org``, flatten subgroup repositories into the base workspace instead of preserving subgroup paths

Default
False
--with-shared

Include projects shared into the group from other namespaces (default: exclude shared projects)

Default
False
--skip-group GROUP

Exclude repos whose namespace contains GROUP as a path segment (repeatable: --skip-group bots --skip-group archived)

Default
None

Filtering

-l, --language LANG

Filter by programming language

Default
None
--topics TOPICS

Filter by topics (comma-separated)

Default
None
--min-stars N

Minimum stars (for search mode)

Default
0
Type
int
--archived

Include archived repositories

Default
False
--forks

Include forked repositories

Default
False
--limit N

Maximum repositories to fetch (default: 100, 0 = no limit)

Default
100
Type
int

Output

-f, --file FILE

Config file to write to (default: ~/.vcspull.yaml)

Default
None
--dry-run, -n

Preview without writing to config file

Default
False
--yes, -y

Skip confirmation prompt

Default
False
--json

Output as JSON

Default
False
--ndjson

Output as NDJSON (one JSON per line)

Default
False
--https

Use HTTPS clone URLs instead of SSH (default: SSH)

Default
False
--sync

Sync config with remote: update URLs for existing entries whose URL has changed, and remove entries no longer on the remote. Preserves all metadata (options, remotes, shell_command_after). Respects pinned entries (options.pin.import).

Default
False
--prune

Remove config entries tagged by a previous import that are no longer on the remote. Does not update URLs for existing entries (use --sync for that). Implied by --sync. Respects pinned entries.

Default
False
--prune-untracked

With --sync or --prune, also remove config entries in the target workspace that lack import provenance (e.g. manually added repos). Entries imported from other sources and pinned entries are preserved. Requires --sync or --prune.

Default
False
--color

When to use colors (default: auto)

Default
auto
Choices
auto, always, never

Subgroup targeting

Use slash notation to target a specific subgroup or sub-subgroup directly:

$ vcspull import gl my-group/my-subgroup \
    --mode org \
    --workspace ~/code/
$ vcspull import gl my-group/my-subgroup/my-leaf \
    --mode org \
    --workspace ~/code/

The TARGET argument accepts any depth of slash-separated group path.

Group flattening

When importing a GitLab group with --mode org, vcspull preserves subgroup structure as nested workspace directories by default. Use --flatten-groups to place all repositories directly in the base workspace:

$ vcspull import gl my-group \
    --mode org \
    --workspace ~/code/ \
    --flatten-groups

Workspace structure by target and flag

Given a group tree my-group sub leaf, importing from ~/code/:

Target

--flatten-groups

Workspace sections written

my-group

no

~/code/, ~/code/sub/, ~/code/sub/leaf/

my-group

yes

~/code/ only

my-group/sub

no

~/code/, ~/code/leaf/

my-group/sub

yes

~/code/ only

my-group/sub/leaf

no

~/code/ only (leaf — no further nesting)

my-group/sub/leaf

yes

~/code/ only

When the target is already the deepest group (a leaf), --flatten-groups has no effect — all repositories already land in the base workspace.

Including shared repositories

By default, repositories shared into a group from another namespace are excluded. Use --with-shared to include them when importing in --mode org:

$ vcspull import gl my-group \
    --mode org \
    --workspace ~/code/ \
    --with-shared

--with-shared has no effect in user mode or search mode; a warning is emitted if the flag is passed in those contexts.

Skipping subgroups

Use --skip-group to exclude all repositories whose owner path contains a specific group name segment. Matching is case-insensitive and segment-based:

$ vcspull import gl my-group \
    --mode org \
    --workspace ~/code/ \
    --skip-group bots

Repeat the flag to skip multiple groups:

$ vcspull import gl my-group \
    --mode org \
    --workspace ~/code/ \
    --skip-group bots \
    --skip-group archived

The flag matches any path segment: --skip-group bots skips repos owned by my-group/bots or my-group/bots/subteam but not my-group/robotics.

Note: Passing the root group name itself (--skip-group my-org when importing my-org) will silently exclude every repository, since all repo paths include the root group as a path segment.

Authentication

  • Env vars: GITLAB_TOKEN (primary), GL_TOKEN (fallback)

  • Token type: Personal access token

  • Scope: read_api (minimum for listing projects; required for search mode)

  • Create at: https://gitlab.com/-/user_settings/personal_access_tokens (self-hosted: https://<instance>/-/user_settings/personal_access_tokens)

Set the token:

$ export GITLAB_TOKEN=glpat-...

Then import:

$ vcspull import gl myuser --workspace ~/code/