github-desktop/docs/technical/pull-requests.md

64 lines
2.4 KiB
Markdown
Raw Normal View History

2018-01-11 21:04:44 +00:00
# Checking out pull requests from a forked repository
2018-01-31 22:39:42 +00:00
PR [#3602](https://github.com/desktop/desktop/pull/3602) introduced the ability
to checkout a branch from a forked repository. In order to accomplish this, we
needed a way to manage remotes on your behalf. This document is intended to
detail the process we developed to make checking out PRs as frictionless as
possible.
2018-01-11 21:04:44 +00:00
2018-01-12 17:39:26 +00:00
## Removing Remotes
2018-01-31 22:39:42 +00:00
One of the goals of our design was to ensure that we dont cause your remotes —
`.git/refs/remotes` — to grow unbounded. We prevent this by cleaning up after
ourselves. We determined that a remote is a candidate for removal when it meets
the certain conditions:
2018-01-11 21:04:44 +00:00
* Start with our prefix
* The PR associated with the remote is closed
2018-01-31 22:39:42 +00:00
The implementation of the function that does this work can be found
[here](https://github.com/desktop/desktop/blob/34a05b155ff69bb19cc4da5b2caa89856e3e63fb/app/src/lib/stores/pull-request-store.ts#L91-L110).
2018-01-12 17:48:57 +00:00
2018-01-11 21:11:57 +00:00
```ts
2018-01-12 17:48:57 +00:00
forkedRemotesToDelete(
remotes: ReadonlyArray<IRemote>,
openPullRequests: ReadonlyArray<PullRequest>
): ReadonlyArray<IRemote> {
2018-01-11 21:11:57 +00:00
const forkedRemotes = remotes.filter(remote =>
remote.name.startsWith(ForkedRemotePrefix)
)
const remotesOfPullRequests = new Set<string>()
openPullRequests.forEach(openPullRequest => {
const { gitHubRepository } = openPullRequest.head
if (gitHubRepository != null && gitHubRepository.cloneURL != null) {
remotesOfPullRequests.add(gitHubRepository.cloneURL)
}
})
const forkedRemotesToDelete = forkedRemotes.filter(
forkedRemote => !remotesOfPullRequests.has(forkedRemote.url)
)
return forkedRemotesToDelete
}
```
2018-01-12 18:43:17 +00:00
## Magic Remote Prefix
2018-01-31 22:39:42 +00:00
One of the main problems we needed to solve was determining which remotes are no
longer needed and can be cleaned. We decided to prefix the remotes we add on
your behalf with a magic string: `github-desktop-`
2018-01-12 18:43:17 +00:00
```ts
export const ForkedRemotePrefix = 'github-desktop-'
```
2018-01-31 22:39:42 +00:00
2018-01-12 18:43:17 +00:00
[Code](https://github.com/desktop/desktop/blob/34a05b155ff69bb19cc4da5b2caa89856e3e63fb/app/src/lib/stores/pull-request-store.ts#L26)
2018-01-11 21:04:44 +00:00
## What does this mean for me?
2018-01-31 22:39:42 +00:00
Doing this essentially gives us a namespace that we can safely work in. We chose
the prefix `github-desktop-` because we are confident that your own remote names
will never start with this prefix. This means that in order for GitHub Desktop
to work as expected, you should never add a remote that starts with our prefix.
We feel that this is an acceptable compromise.