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

45 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-11 21:12:52 +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
## Magic Remote Prefix
2018-01-11 21:14:33 +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-11 21:04:44 +00:00
2018-01-11 21:11:57 +00:00
```ts
export const ForkedRemotePrefix = 'github-desktop-'
```
[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
2018-01-12 17:39:26 +00:00
## Removing Remotes
2018-01-11 21:14:33 +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 following conditions.
2018-01-11 21:04:44 +00:00
* Start with our prefix
* The PR associated with the remote is closed
2018-01-11 21:11:57 +00:00
```ts
private forkedRemotesToDelete(
remotes: ReadonlyArray<IRemote>,
openPullRequests: ReadonlyArray<PullRequest>
): ReadonlyArray<IRemote> {
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
}
```
[Code](https://github.com/desktop/desktop/blob/34a05b155ff69bb19cc4da5b2caa89856e3e63fb/app/src/lib/stores/pull-request-store.ts#L91-L110)
2018-01-11 21:04:44 +00:00
## What does this mean for me?
2018-01-11 21:11:57 +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.