10 Branching

Forge provides commands for creating and checking out a new branch or work tree from a pull-request. These commands are available from the same transient prefix commands as the suffix commands, used to create and check out branches and work trees in a more generic fashion (magit-branch on b and magit-worktree on %).

b F (forge-branch-pullreq)

This command creates and configures a new branch from a pull-request, creating and configuring a new remote if necessary.

The name of the local branch is the same as the name of the remote branch that you are being asked to merge, unless the contributor could not be bothered to properly name the branch before opening the pull-request. The most likely such case is when you are being asked to merge something like "fork/master" into "origin/master". In such cases the local branch will be named "pr-N", where N is the pull-request number.

These variables are always set by this command:

  • branch.<name>.pullRequest is set to the pull-request number.
  • branch.<name>.pullRequestRemote is set to the remote on which the pull-request branch is located.
  • branch.<name>.pushRemote is set to the same remote as branch.<name>.pullRequestRemote if that is possible, otherwise it is set to the upstream remote.
  • branch.<name>.description is set to the pull-request title.
  • branch.<name>.rebase is set to true because there should be no merge commits among the commits in a pull-request.

This command also configures the upstream and the push-remote of the local branch that it creates.

The branch against which the pull-request was opened is always used as the upstream. This makes it easy to see what commits you are being asked to merge in the section titled something like "Unmerged into origin/master".

Like for other commands that create a branch, it depends on the option magit-branch-prefer-remote-upstream whether the remote branch itself or the respective local branch is used as the upstream, so this section may also be titled, e.g., "Unmerged into master".

When necessary and possible, the remote pull-request branch is configured to be used as the push-target. This makes it easy to see what further changes the contributor has made since you last reviewed their changes in the section titled something like "Unpulled from origin/new-feature" or "Unpulled from fork/new-feature".

  • If the pull-request branch is located in the upstream repository, then you probably have set remote.pushDefault to that repository. However some users like to set that variable to their personal fork, even if they have push access to the upstream, so branch.<name>.pushRemote is set anyway.
  • The push-remote is configured using branch.<name>.pushRemote, even if the used value is identical to that of remote.pushDefault, just in case you change the value of the latter later on. Additionally the variable branch.<name>.pullRequestRemote is set to the remote on which the pull-request branch is located.
  • If the pull-request branch is located on the contributor’s fork, then you, as a maintainer of the upstream repository, are usually allowed to push to that branch anyway. (However, the contributor could explicitly disallow this, but in my experience that rarely happens.)
  • As mentioned above, contributors sometimes fail to use a dedicated branch for their pull-requests and this command is thus forced to make up a branch name such as "pr-313".

    Usually a maintainer would use magit-push-current-to-pushremote (on p) to push to the contributor’s pull-request branch on their fork. For a branch named "pr-313" that does not work. (Instead of pushing to "fork/main", it would unsuccessfully attempt to create a new branch "pr-313" on the fork.) In such situations the magit-push menu offers an alternative command for pushing to the pull-request branch: forge-push-to-unnamed-pullreq (on N).

b f (forge-checkout-pullreq)

This command creates and configures a new branch from a pull-request the same way forge-branch-pullreq does. Additionally it checks out the new branch.

Z n (forge-checkout-worktree)

This command creates and configures a new branch from a pull-request the same way forge-branch-pullreq does. Additionally it checks out the new branch, using a new working tree.

User Option: forge-checkout-worktree-read-directory-function

This function is used by forge-checkout-worktree, to read the new worktree directory where it checks out the pull-request. It takes the pull-request as the only argument and must return a directory.

When you delete a pull-request branch, which was created using one of the above three commands, then magit-branch-delete usually offers to also delete the corresponding remote. It does not offer to delete a remote if (1) the remote is the upstream remote, and/or (2) if other branches are being fetched from the remote.

Note that you have to delete the local branch (e.g., "feature") for this to work. If you delete the tracking branch (e.g., "fork/feature"), then the remote is never removed.