# GitHub import

Point virta at a repo and it pulls in what it can: the project's description,
homepage, package name and version (from `package.json`), and every issue as
a task — title, body, labels as tags, open or closed, attributed to the
GitHub author and dated when it was opened. That is how a real repo is
onboarded, by UI or by the `import` verb.

Every event an import writes has a deterministic id (`gh:owner/repo#12:created`),
and the [sync log](/log/) is idempotent by id, so importing again — to pick up
new issues, or after a failed run — cannot duplicate anything. Once a repo is
imported, virta is the source of truth for its tasks; GitHub issues become a
place virta renders to.

**Writing back** (`pushToGitHub`, `virta project push`): an issue's reporter
waits on GitHub, so a task that came *from* GitHub carries its outcome back —
closed in virta, its issue is closed with the close reason as a comment
(a task that ended obsolete or rejected closes it as *not planned*); reopened, it is reopened. Only imported tasks (`gh:` ids) are
touched; an internal task never mirrors out. It reconciles against the
issues' live state, so running it again changes nothing, and a dry run
prints exactly what it would post.

The import uses GitHub's public API without a token (60 requests an hour per
address); pass one for private repos or bigger backlogs.
