(cli-add)=

# vcspull add

The `vcspull add` command registers a repository in your configuration by
pointing vcspull at a checkout on disk. The command inspects the directory,
merges duplicate workspace roots by default, and prompts before writing unless
you pass `--yes`.

```{note}
This command replaces the old `vcspull import <name> <url>` from v1.36--v1.39.
For bulk scanning of local repositories, see {ref}`cli-discover`.
For bulk import from remote services (GitHub, GitLab, etc.), see {ref}`cli-import`.
```

## Command

```{eval-rst}
.. argparse::
    :module: vcspull.cli
    :func: create_parser
    :prog: vcspull
    :path: add
```

## Basic usage

Point to an existing checkout to add it under its parent workspace:

```vcspull-console
$ vcspull add ~/study/python/pytest-docker
Found new repository to import:
  + pytest-docker (https://github.com/avast/pytest-docker)
  • workspace: ~/study/python/
  ↳ path: ~/study/python/pytest-docker
? Import this repository? [y/N]: y
Successfully added 'pytest-docker' (git+https://github.com/avast/pytest-docker) to ~/.vcspull.yaml under '~/study/python/'.
```

The parent directory (`~/study/python/` in this example) becomes the workspace
root. vcspull shortens paths under `$HOME` to `~/...` in its log output so the
preview stays readable.

## Overriding detected information

### Choose a different name

Override the derived repository name with `--name` when the directory name
isn't the label you want stored in the configuration:

```console
$ vcspull add ~/study/python/pytest-docker --name docker-pytest
```

### Override the remote URL

vcspull reads the Git `origin` remote automatically. Supply `--url` when you
need to register a different remote or when the checkout does not have one yet:

```console
$ vcspull add ~/study/python/example --url https://github.com/org/example
```

URLs follow [pip's VCS format][pip vcs url]; vcspull inserts the `git+` prefix
for HTTPS URLs so the resulting configuration matches `vcspull fmt` output.

### Select a workspace explicitly

The workspace defaults to the checkout's parent directory. Pass
`--workspace`/`--workspace-root` to store the repository under a different
section:

```console
$ vcspull add ~/scratch/tmp-project --workspace ~/projects/python/
```

## Confirmation and dry runs

`vcspull add` asks for confirmation before writing. Use `--yes` to skip the
prompt in automation, or `--dry-run`/`-n` to preview the changes without
modifying any files:

```console
$ vcspull add ~/study/python/pytest-docker --dry-run
```

Dry runs still show duplicate merge diagnostics so you can see what would
change.

## Choosing configuration files

vcspull searches for configuration files in this order:

1. `./.vcspull.yaml`
2. `~/.vcspull.yaml`
3. `~/.config/vcspull/*.yaml`

Specify a file explicitly with `-f/--file`:

```console
$ vcspull add ~/study/python/pytest-docker \
    --file ~/configs/python.yaml
```

## Handling duplicates

vcspull merges duplicate workspace sections before writing so existing
repositories stay intact. When it collapses multiple sections, the command logs
a summary of the merge. Prefer to inspect duplicates yourself? Add
`--no-merge` to keep every section untouched.

## Pinned entries

Repositories whose configuration includes a pin on the `add` operation are
skipped with a warning. For example, given this configuration:

```yaml
~/code/:
  internal-fork:
    repo: "git+git@github.com:myorg/internal-fork.git"
    options:
      pin: true
      pin_reason: "pinned to company fork — update manually"
```

Attempting to add a repo that matches an existing pinned entry produces a
warning and leaves the entry untouched:

```vcspull-console
$ vcspull add ~/code/internal-fork
⚠ Repository 'internal-fork' is pinned (pinned to company fork — update manually) — skipping
```

Both `options.pin: true` (global) and `options.pin.add: true` (per-operation)
block the `add` command. The `pin_reason` (if set) is included in the warning.
See {ref}`config-pin` for full pin configuration.

## After adding repositories

1. Run `vcspull fmt --write` to normalize your configuration (see
   {ref}`cli-fmt`).
2. Run `vcspull list` to verify the new entry (see {ref}`cli-list`).
3. Run `vcspull sync` to clone or update the working tree (see {ref}`cli-sync`).

## Migration from the old vcspull import

The `vcspull import <name> <url>` command from v1.36--v1.39 has been replaced
by `vcspull add`:

```diff
- $ vcspull import flask https://github.com/pallets/flask.git -c ~/.vcspull.yaml
+ $ vcspull add ~/code/flask --url https://github.com/pallets/flask.git --file ~/.vcspull.yaml
```

Key differences:

- `vcspull add` derives the name from the filesystem unless you pass `--name`.
- The parent directory becomes the workspace automatically; use `--workspace`
  to override.
- Use `--url` to record a remote when the checkout does not have one.

```{note}
Starting with v1.55, `vcspull import` is a *different* command that bulk-imports
repositories from remote services (GitHub, GitLab, etc.). See {ref}`cli-import`
for details.
```

[pip vcs url]: https://pip.pypa.io/en/stable/topics/vcs-support/
