# Pull requests

> Propose changes on a branch, review them round by round, and merge them.

import PullSelectors from "../../../components/PullSelectors.svelte";

A pull request is a proposal to merge one branch into another branch. It
tells other people about the changes that you pushed to a branch. Other
people can discuss the changes and review them. You can add more commits
before you merge the changes into the target branch.

On Tangled, a pull request is a series of immutable **rounds**. When you
create a pull request, Tangled makes round 0. To update the pull
request, push to the same branch and select **Resubmit**. This makes a
new round. Each round records a fixed base commit and a fixed head
commit. Reviewers can read earlier rounds. Thus they can see how the
pull request changes. A round cannot be modified once created, you can
only submit a new round.

## Opening a pull request

The **New pull** page (`/pulls/new`) asks for a source branch, a target
branch, a title, and a body in markdown. The target branch is the
default branch, unless you select a different branch. You cannot use the
default branch as the source.

The page shows the commits that the pull request includes, and the diff
against the target branch.

When you push a branch that is not the default branch, the push output
includes a link. The link opens the form with the two branches already
correct:

```sh
git push origin fix-parser
```

The link has this form:

`https://tangled.org/alice.tngl.sh/my-project/pulls/new?source=branch&sourceBranch=fix-parser&targetBranch=main`

When you submit the form, Tangled creates the pull request and its first
round, round 0. Round 0 records the merge base of the two branches and
the tip of the source branch.

## Rounds

Each round holds a base commit and a head commit. You cannot edit a
round after Tangled creates it.

This separates work on a branch from a request for review. You can push
fixups, squash, and rebase as often as you want. These actions do not
change what the reviewers read. When the branch is ready, submit a new
round. Earlier rounds stay available, together with the discussion that
occurred while they were current.

## Reviewing

Every round of a pull request has a URL. Thus you can send a reviewer a
link to the exact view that you want. Since rounds are immutable,
reviewers can always drop comments without them being outdated by an
update to the PR.

## Interdiffs and JJ VCS

As your PR evolves, reviewers might want to only review the part of the
PR that has changed across versions. To enable this form of review,
Tangled has native support for interdiff-style reviews:

- First, you must use the Jujustu version control system to manage your
  repository
- All commits in your PR must have [Jujutsu
  change-ids](https://docs.jj-vcs.dev/latest/glossary/#change-id)
  associated with them

When you submit a second version to your PR, you will see all submitted
versions in a version selector dropdown, here, you can use use
<kbd>Shift</kbd> + <kbd>Left Click</kbd> to compare against a previous
version, and Tangled will calculate an interdiff to show you exactly
what changed between the two rounds.

Tangled also shows Jujutsu change-ids across the UI if commits have an
associated change-id header.

<PullSelectors client:visible />

## Merging

The merge box checks the newest round against the current tip of the
target branch. It reports if the round applies cleanly. The repository
owner and the collaborators can then select **Merge**. Several merge
strategies are also available to choose from.

## URLs

| Path                                                    | Shows                                         |
| ------------------------------------------------------- | --------------------------------------------- |
| `/<owner>/<repo>/pulls/<id>`                            | A pull request, at its newest round           |
| `/<owner>/<repo>/pulls/<id>/latest`                     | The newest round                              |
| `/<owner>/<repo>/pulls/<id>/<round>`                    | One round                                     |
| `/<owner>/<repo>/pulls/<id>/<round>/<commit>..<commit>` | A range of commits in a round                 |
| `/<owner>/<repo>/pulls/<id>/<from>..<to>`               | The interdiff between two rounds              |
| `/<owner>/<repo>/pulls/<id>/<from>..<to>/<change-id>`   | That interdiff narrowed to one Jujutsu change |