quinjet 0.0.10

A fast, live, keyboard-first Git source-control interface for the terminal
# `quinjet branch switch`

Moves HEAD to an existing branch.

Usage:

```bash
quinjet branch switch <NAME> [-C <DIR>] [--json]
```

Arguments:

| Name | Type / values | Default | What it does |
| --- | --- | --- | --- |
| `<NAME>` | string | required | The branch to switch to. A short name, not a full ref. |

Options:

| Name | Type / values | Default | What it does |
| --- | --- | --- | --- |
| `-C, --path <DIR>` | path | `.` | The repository to act on. Any directory inside the worktree works. |
| `--json` | flag | off | Prints `{"message": ...}` on stdout instead of the sentence. |
| `-h, --help` | flag | off | Prints this verb's help on stdout and exits 0. |

Underneath this is one command:

```bash
git switch -- <NAME>
```

and nothing else. Quinjet adds no validation, no flags and no confirmation. The
`--` is there so that a name is always read as a name, never as an option, and
Quinjet passes arguments as an array rather than through a shell, so a name
containing a space or a quote survives intact. Git's own commentary,
`Switched to branch 'main'` and the branch-status lines that follow it, is
captured and discarded; the only thing printed is Quinjet's sentence,
`Switched to <NAME>`.

Because it is plain `git switch`, Git's guessing is still on. If `<NAME>` is not
a local branch but exactly one remote has a branch by that name, Git creates a
local branch from it and sets its upstream. So `quinjet branch switch newthing`
in a repository that only has `origin/newthing` both creates and switches, and
still reports `Switched to newthing`. Use
[`quinjet branch list --all`](./list.md) first if you want to know which of the
two is about to happen.

What it will not do:

- A remote-tracking name is refused. `quinjet branch switch origin/main` exits 1
  with Git's `fatal: a branch is expected, got remote branch 'origin/main'`.
  Switch to `main`, or use [`quinjet branch create`]./create.md with
  `origin/main` as the start point.
- A tag or a raw commit is refused the same way. There is no `--detach` here,
  so detaching HEAD is a thing to do with Git itself.
- A branch checked out in another worktree of this repository is refused by
  Git, even though it appears in the listing.

Uncommitted work is carried, not stashed. `git switch` takes your changes with
you when the two branches agree on those files, and refuses the whole switch
when they do not, leaving you exactly where you were. There is no `--force` and
no `--merge` in this verb, so the refusal is final until you stage, commit,
discard or stash the changes. See [`quinjet stash`](../stash/README.md) for the
usual way out.

Switching is not gated by `--yes`, unlike [`delete`](./delete.md). It happens
the moment you run it.

`--json` shape, an object with one key:

```json
{
  "message": "Switched to main"
}
```

The sentence is generated by Quinjet, not by Git, and it always names the
branch you asked for. It says the same thing when you were already on that
branch, because `git switch` treats that as success.

Examples:

```bash
quinjet branch switch main
quinjet branch switch feat/cli-command-surface --json
quinjet branch switch -C ~/code/project main
quinjet branch switch -- -weird-name
```

```console
$ quinjet branch switch main
Switched to main
```

A refusal is Git's, reported on stderr with Quinjet's prefix, and exits 1:

```console
$ quinjet branch switch nosuch
error: Git command failed: fatal: invalid reference: nosuch
```

Everything after the `Git command failed:` prefix is Git's own text, passed through
unchanged.

## Where to go next

- [`quinjet branch`]./README.md, the rest of this group
- [All `quinjet` commands]../README.md