> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wit.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Remote Operations

> Clone, fetch, pull, and push to remote repositories

wit provides full support for remote Git operations, allowing you to collaborate with others using any Git hosting service including GitHub, GitLab, Bitbucket, or self-hosted servers.

## Quick Reference

| Command                       | Description                  |
| ----------------------------- | ---------------------------- |
| `wit clone <url>`             | Clone a repository           |
| `wit remote add <name> <url>` | Add a remote                 |
| `wit fetch [remote]`          | Download objects from remote |
| `wit pull [remote]`           | Fetch and merge              |
| `wit push [remote] [branch]`  | Upload changes to remote     |

## Clone

Clone a repository from a remote URL:

```bash theme={null}
# Clone into a new directory
wit clone https://github.com/user/repo.git

# Clone into a specific directory
wit clone https://github.com/user/repo.git my-project

# Clone into current directory
wit clone https://github.com/user/repo.git .
```

### Clone Options

```bash theme={null}
# Clone a specific branch
wit clone -b develop https://github.com/user/repo.git

# Shallow clone (faster, less history)
wit clone --depth 1 https://github.com/user/repo.git

# Bare clone (no working directory)
wit clone --bare https://github.com/user/repo.git

# Clone without checking out
wit clone -n https://github.com/user/repo.git
```

| Option                | Description                                           |
| --------------------- | ----------------------------------------------------- |
| `--depth <n>`         | Create a shallow clone with only n commits of history |
| `-b, --branch <name>` | Clone only the specified branch                       |
| `--bare`              | Create a bare repository (no working directory)       |
| `-n, --no-checkout`   | Don't checkout HEAD after cloning                     |
| `-o, --origin <name>` | Use `<name>` instead of 'origin' for the remote       |
| `--single-branch`     | Clone only one branch                                 |

## Remotes

Manage remote repository connections:

```bash theme={null}
# List all remotes
wit remote

# List remotes with URLs
wit remote -v

# Add a new remote
wit remote add origin https://github.com/user/repo.git
wit remote add upstream https://github.com/original/repo.git

# Remove a remote
wit remote remove upstream

# Rename a remote
wit remote rename origin github

# Show remote details
wit remote show origin

# Update remote URL
wit remote set-url origin https://github.com/user/new-repo.git

# Get remote URL
wit remote get-url origin
```

## Fetch

Download objects and refs from a remote without merging:

```bash theme={null}
# Fetch from origin (default remote)
wit fetch

# Fetch from a specific remote
wit fetch upstream

# Fetch all remotes
wit fetch --all

# Fetch and prune deleted remote branches
wit fetch --prune

# Fetch with tags
wit fetch --tags
```

### Fetch Options

| Option          | Description                                                    |
| --------------- | -------------------------------------------------------------- |
| `--all`         | Fetch from all configured remotes                              |
| `-p, --prune`   | Remove remote-tracking refs that no longer exist on the remote |
| `-t, --tags`    | Fetch all tags from the remote                                 |
| `--depth <n>`   | Deepen a shallow clone to n commits                            |
| `-v, --verbose` | Be more verbose                                                |
| `-n, --dry-run` | Show what would be done without making changes                 |

After fetching, you can see what changed:

```bash theme={null}
# Compare local and remote
wit log main..origin/main

# See all remote branches
wit branch -r
```

## Pull

Fetch from remote and merge into current branch:

```bash theme={null}
# Pull from tracking branch
wit pull

# Pull from specific remote/branch
wit pull origin main

# Pull with rebase instead of merge
wit pull --rebase

# Pull and auto-stash local changes
wit pull --autostash

# Only fast-forward (fail if not possible)
wit pull --ff-only
```

### Pull Options

| Option          | Description                                    |
| --------------- | ---------------------------------------------- |
| `-r, --rebase`  | Rebase local commits on top of fetched commits |
| `--ff-only`     | Only update if fast-forward is possible        |
| `--no-ff`       | Create a merge commit even for fast-forward    |
| `--autostash`   | Automatically stash/unstash local changes      |
| `-v, --verbose` | Be more verbose                                |

### Pull Strategies

<Tabs>
  <Tab title="Merge (default)">
    ```bash theme={null}
    # Creates a merge commit if branches have diverged
    wit pull
    ```

    Best for: Preserving complete history of parallel development
  </Tab>

  <Tab title="Rebase">
    ```bash theme={null}
    # Replays your commits on top of remote changes
    wit pull --rebase
    ```

    Best for: Keeping a linear, clean history
  </Tab>

  <Tab title="Fast-forward only">
    ```bash theme={null}
    # Only succeeds if no local commits exist
    wit pull --ff-only
    ```

    Best for: Ensuring you don't accidentally create merge commits
  </Tab>
</Tabs>

### Pull Conflicts

If there are conflicts during pull:

```bash theme={null}
# See conflicts
wit merge --conflicts

# Resolve and continue
wit merge --continue

# Or abort
wit merge --abort
```

## Push

Upload local commits to a remote repository:

```bash theme={null}
# Push current branch to tracking remote
wit push

# Push to specific remote/branch
wit push origin main

# Push and set upstream tracking
wit push -u origin main

# Push all branches
wit push --all

# Push tags
wit push --tags

# Delete remote branch
wit push --delete origin old-branch

# Force push (use with caution!)
wit push --force
wit push -f

# Safer force push
wit push --force-with-lease
```

### Push Options

| Option               | Description                                   |
| -------------------- | --------------------------------------------- |
| `-u, --set-upstream` | Set upstream tracking for the branch          |
| `-f, --force`        | Force push (overwrites remote history)        |
| `--force-with-lease` | Force push only if remote hasn't changed      |
| `--tags`             | Push all local tags                           |
| `-d, --delete`       | Delete the specified remote branch            |
| `--all`              | Push all branches                             |
| `-n, --dry-run`      | Show what would be pushed without pushing     |
| `-v, --verbose`      | Be more verbose                               |
| `--also <remote>`    | Also push to an additional remote (dual-push) |
| `--all-remotes`      | Push to all configured remotes                |

<Warning>
  **Force Push Warning**: Using `--force` can overwrite remote history and cause problems for collaborators. Prefer `--force-with-lease` which checks that the remote hasn't changed before pushing.
</Warning>

### Dual-Push (Multiple Remotes)

Push to multiple remotes simultaneously. This is useful when you want to keep both a wit server and GitHub (or another Git host) in sync:

```bash theme={null}
# Push to origin and also to github remote
wit push --also github

# Push to a specific remote and also another
wit push origin main --also github

# Push to ALL configured remotes
wit push --all-remotes
```

<Tip>
  **Use Case**: If you're using wit as your primary version control but need to sync with GitHub for CI/CD or deployment providers (Vercel, Netlify, etc.), dual-push keeps both remotes in sync with a single command.
</Tip>

Example workflow:

```bash theme={null}
# Set up remotes
wit remote add origin git@wit-server:user/repo.git
wit remote add github git@github.com:user/repo.git

# Push to both with one command
wit push origin main --also github

# Or push to all remotes
wit push --all-remotes
```

### Push Rejections

If your push is rejected, it usually means the remote has changes you don't have:

```bash theme={null}
# Push rejected - remote has new commits
wit push
# ! [rejected]        main -> main (non-fast-forward)
# error: failed to push some refs

# Solution: Pull first, then push
wit pull
wit push

# Or if you're sure, force push
wit push --force-with-lease
```

## Authentication

### GitHub Authentication

The recommended way to authenticate with GitHub:

```bash theme={null}
# Login with OAuth (opens browser)
wit github login

# Check authentication status
wit github status

# Logout
wit github logout
```

### Environment Variables

You can also use environment variables:

```bash theme={null}
# GitHub token
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx

# Or use GH CLI token
export GH_TOKEN=ghp_xxxxxxxxxxxx
```

### Personal Access Tokens

For other Git hosts, use personal access tokens:

```bash theme={null}
# Token in URL (not recommended for shared machines)
wit clone https://token@github.com/user/repo.git

# Or set in environment
export WIT_TOKEN=your-token
```

## Working with Forks

Common fork workflow:

```bash theme={null}
# Clone your fork
wit clone https://github.com/you/repo.git
cd repo

# Add upstream remote
wit remote add upstream https://github.com/original/repo.git

# Fetch upstream changes
wit fetch upstream

# Merge upstream into your branch
wit merge upstream/main

# Push to your fork
wit push origin main
```

## Tracking Branches

Set up tracking between local and remote branches:

```bash theme={null}
# Push and set upstream
wit push -u origin feature

# After this, you can just use:
wit push
wit pull

# See tracking configuration
wit branch -vv

# Set up tracking manually
wit branch --set-upstream-to=origin/main main
```

## Complete Workflow Example

```bash theme={null}
# 1. Clone a repository
wit clone https://github.com/user/repo.git my-project
cd my-project

# 2. Check remotes
wit remote -v
# origin    https://github.com/user/repo.git (fetch)
# origin    https://github.com/user/repo.git (push)

# 3. Create a feature branch and make changes
wit switch -c feature-x
echo "new feature" > feature.txt
wit add feature.txt
wit commit -m "Add new feature"

# 4. Push the new branch
wit push -u origin feature-x

# 5. Later, get updates from origin
wit fetch origin

# 6. Merge updates into your branch
wit pull origin main

# 7. Push your updated branch
wit push

# 8. After merge, clean up
wit switch main
wit pull
wit branch -d feature-x
wit push --delete origin feature-x
```

## Troubleshooting

### "Authentication failed"

```bash theme={null}
# Check if logged in
wit github status

# Re-login
wit github logout
wit github login
```

### "Updates were rejected"

Your local branch is behind the remote:

```bash theme={null}
# Option 1: Pull first
wit pull
wit push

# Option 2: Force push (if you know what you're doing)
wit push --force
```

### "No upstream branch"

```bash theme={null}
# Set upstream when pushing
wit push -u origin branch-name
```

## Tips

<AccordionGroup>
  <Accordion title="Keep fetched data fresh">
    Run `wit fetch` regularly to stay up-to-date with remote changes without affecting your working directory.
  </Accordion>

  <Accordion title="Use upstream tracking">
    Set up tracking with `wit push -u` so future pushes/pulls just work with `wit push` and `wit pull`.
  </Accordion>

  <Accordion title="Prefer --force-with-lease">
    When you need to force push, use `--force-with-lease` to prevent accidentally overwriting someone else's work.
  </Accordion>

  <Accordion title="Clean up stale branches">
    Use `wit fetch --prune` to remove tracking branches for remote branches that have been deleted.
  </Accordion>
</AccordionGroup>
