# Import and sync from GitHub

Bring repositories from GitHub into GitCafe with their issues, pull requests,
reviews and comments, and optionally keep both sides in sync. Imports use the
GitCafe GitHub App, including for public repositories. GitHub is optional:
repositories created in GitCafe need no GitHub account.

## What syncs

An imported repository keeps receiving changes from GitHub. Two-way sync also
writes GitCafe changes back to GitHub.

| What                                     | One-way (default) | Two-way     |
| ---------------------------------------- | ----------------- | ----------- |
| Branches and tags                        | From GitHub       | Both ways   |
| Issues and pull requests                 | From GitHub       | Both ways   |
| Reviews and comments                     | From GitHub       | Both ways   |
| Labels, milestones, assignees, reactions | From GitHub       | Both ways   |
| Checks and commit statuses               | From GitHub       | From GitHub |
| Releases                                 | Not synced        | Not synced  |

GitHub Actions results arrive as checks. Images in conversations are linked,
not copied; see [images and attachments](https://mn.staging.git.cafe/docs/integrations/github-sync.md#images-and-attachments).

## Create an account with GitHub

On the sign-up page, choose **Sync with GitHub** and approve GitCafe on GitHub.
If GitHub does not confirm your email address, verify it with the email
GitCafe sends before importing.

Your new account also gets the SSH and GPG keys on your GitHub profile, with
the default SSH access; keys GitCafe cannot use are skipped. Manage them
afterwards under [SSH keys](https://mn.staging.git.cafe/docs/account/ssh-keys.md) and
[GPG keys](https://mn.staging.git.cafe/docs/account/gpg-keys.md).

If your GitHub account is already linked to a GitCafe account, sign in to that
account instead; use **Reconnect GitHub** if the link needs refreshing.

## Import repositories

Open `/import/github`, or choose **Import from GitHub** on `/new`. The page
walks you through three steps.

1. **Connect GitHub**: authorize your GitHub account. You return to the import
   page afterwards.
2. **Choose repositories**: if the App is not installed yet, choose **Install
   GitCafe on GitHub**, pick the account or organization, and grant access to
   the repositories you want. An organization owner may need to approve. Back
   in GitCafe, the list refreshes; use **Check access** if it has not. Use
   **Modify repository access** to add repositories later, or **Use another
   account or organization** for another installation.
3. **Review and import**: choose the destination owner and name for each
   repository (up to ten at a time), check the settings and choose
   **Import N repositories**.

Imported repositories keep their GitHub visibility. Each repository shows its
own progress; **Sync status** opens the details. The code usually arrives
before the issues and pull requests.

Imports continue on the server if you close the page. Open the import page
again to see their progress, and use **Continue imports** if any stopped.

## Choose one-way or two-way sync

By default, an import copies from GitHub and never writes back. To keep both
sides in sync, select **Enable two-way sync, including writes to GitHub** for
the repository and choose which side wins when both change: **GitCafe wins** or
**GitHub wins**. Two-way sync needs write permission on GitHub.

After the import, changes made on GitHub arrive through the App's webhooks.
Pushes and merges made in GitCafe are sent to GitHub when two-way sync is on.

## Manage sync settings

Open the repository's **Settings → GitHub sync**. It shows the connected
GitHub repository, the sync direction, recent jobs and any changes still
waiting to reach GitHub. From there you can:

- **Renew authorization** when the connection asks for it.
- Change **When both sides change** for two-way sync.
- **Reconcile now** to check changes marked **Awaiting confirmation**, which may
  already be on GitHub.
- **Retry import** for an initial import that stopped. If it stopped because
  this repository has history GitHub does not (it started in GitCafe), choose
  **Two-way sync** instead to send that history to GitHub.

If your GitHub authorization expired or was revoked, open **Account
connection**, reconnect GitHub, and try again.

A repository stays synced with the one GitHub repository it was imported from;
connecting it to another GitHub repository is refused. To sync
another GitHub repository, import it as a new repository.

## Disconnect from GitHub

If you no longer use GitHub, a repository admin can disconnect the repository
under **Settings → GitHub sync** with **Disconnect from GitHub**, or with
`cafe repo github disconnect <owner>/<repo> --yes`. This works in any state,
including an import that stopped or needs attention. The repository becomes a
plain GitCafe repository: sync stops, unfinished sync work is cancelled, and
branches the mirror protected can be deleted again. Code, issues, pull requests
and comments already imported stay. Nothing on GitHub is changed or deleted;
uninstall the GitCafe App on GitHub separately if you want.

Disconnecting waits for any change that may already be on its way to GitHub
or into the repository: if one is still settling, it is refused. Use
**Reconcile now** or wait, then try again. To sync with GitHub again later,
connect the repository again under **Settings → GitHub sync**. After
disconnecting a repository with a very large sync backlog, the cancelled work
is cleared in the background, within about 12 hours; connecting again before
that is refused with a "previous disconnect is still finishing" message that
says how much is left; each attempt clears more, so try again later.

## Merge pull requests that come from GitHub

Pull requests opened on GitHub, including from contributors' forks, appear in
GitCafe without the contributor doing anything. Their commits are copied
separately, so a new or just-pushed pull request can say that GitCafe is still
copying its commits; **Files changed** loads on its own once they arrive. With
two-way sync, choose
**Merge with GitHub** in the pull request's merge controls: GitHub performs the
merge with the method you pick, subject to its own checks and branch
protection, and GitCafe then picks up the result. If GitHub refuses the merge,
the web merge panel and `cafe pr merge` (including `--operation` polling) show
GitHub's reason when available, for example when repository rules disallow the
selected merge method. Choose an allowed method or resolve the reported rule
violation before retrying.
**Retry merge** sends a new attempt, from the web or with `cafe pr merge`.

GitCafe observes GitHub's repository merge settings and effective target-branch
rules when it scans the repository's pull requests: at least every six hours, and soon after a repository, ruleset or branch protection change when the GitHub App receives those events. The web controls offer only the
observed allowed methods, falling back to the first allowed method when your
saved choice is unavailable. Without `--strategy`, `cafe pr merge` merges with a
merge commit when allowed, otherwise the first allowed method. An explicitly disallowed method is refused
before queuing a GitHub merge. Repository settings and branch rules intersect;
required linear history excludes merge commits. Observations can lag changes
on GitHub until the next scan. Before the first scan, or when GitHub does not
expose settings or branch rules, unknown restrictions do not hide methods:
GitHub still makes the final decision.

## Issue and pull request numbers

An imported issue or pull request keeps its GitHub number when that number is
free in GitCafe; otherwise it gets a number from 1000000000 up, so the GitHub
numbers after it still match. A pull request opened in GitCafe on a synced
repository starts with a number from that range. With two-way sync it takes
GitHub's number once GitHub has created it, and its first number no longer
finds it; it keeps the first number if a change to it is still waiting to
reach GitHub then. An issue opened in GitCafe takes the next number when
two-way sync creates it on GitHub, and a number from that range otherwise.
When text is written
to GitHub, references like `#5` become full GitCafe links, so `Fixes #5` cannot
close an unrelated GitHub issue. Use full URLs when you refer to an issue on
the other site.

Issues closed on GitHub as duplicate or not planned appear as canceled in
GitCafe.

GitHub bots appear with a **Bot** badge and their name without the `[bot]`
suffix. A suffixed bot login links to its GitHub App page; otherwise the name
is unlinked. Bots use their cached avatar when available, or an initial when
it is missing. They remain GitHub authors, not GitCafe accounts or native apps.

Apps installed in GitCafe can be assigned to synced issues and pull requests
and asked for reviews there. They have no GitHub account, so they stay in
GitCafe: two-way sync writes only the people to GitHub, and changes made on
GitHub leave the app assigned.

## Images and attachments

Images and videos from GitHub conversations display in GitCafe. When a comment
is written to GitHub, images attached in a public repository stay images;
images from a private repository become **View attachment in GitCafe** links,
so they stay private.

## When something is missing

- GitHub does not send events for reactions, so reactions made on GitHub
  update only when the related conversation changes again.
- If a change made on GitHub never arrives, open the App's webhook delivery
  history on GitHub and redeliver the failed event.
- A configured branch that has not synced for six hours is checked
  automatically.

To mirror a single branch with a server other than GitHub, use
[Git mirrors](https://mn.staging.git.cafe/docs/repositories/git-mirrors.md).
