NIP-34 ====== `git` stuff ----------- `draft` `optional` This NIP defines all the ways code collaboration using and adjacent to [`git`](https://git-scm.com/) can be done using Nostr. ## Repository announcements Git repositories are hosted in Git-enabled servers, but their existence can be announced using Nostr events, as well as their willingness to receive patches, bug reports and comments in general. ```jsonc { "kind": 30617, "content": "", "tags": [ ["d", ""], // usually kebab-case short name ["name", ""], ["description", "brief human-readable project description>"], ["web", "", ...], // a webpage url, if the git server being used provides such a thing ["clone", "", ...], // a url to be given to `git clone` so anyone can clone it ["relays", "", ...] // relays that this repository will monitor for patches and issues ["earliest-unique-commit", ""] // usually root commit but a recent commit for forks ["r", ""] // so clients can subscribe to all events related to a local git repo ["maintainers", "", ...] ] } ``` The tags `web`, `clone`, `relays`, `maintainers` can have multiple values. Except `d`, all tags are optional. ## Patches Patches can be sent by anyone to any repository. Patches to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch events SHOULD include an `a` tag pointing to that repository's announcement address. Patches in a patch set SHOULD include a NIP-10 `e` `reply` tag pointing to the previous patch. The first patch revision in a patch revision SHOULD include a NIP-10 `e` `reply` to the original root patch. ```jsonc { "kind": 1617, "content": "", // contents of "tags": [ ["a", "30617::"], ["r", ""] // so clients can subscribe to all patches sent to a local git repo ["p", ""], ["p", ""], // optionally send the patch to another user to bring it to their attention ["t", "root"], // ommited for additional patches in a series // for the first patch in a revision ["t", "root-revision"], // optional tags for when it is desirable that the merged patch has a stable commit id // these fields are necessary for ensuring that the commit resulting from applying a patch // has the same id as it had in the proposer's machine -- all these tags can be omitted // if the maintainer doesn't care about these things ["commit", ""], ["r", ""] // so clients can find existing patches for a specific commit ["parent-commit", ""], ["commit-pgp-sig", "-----BEGIN PGP SIGNATURE-----..."], // empty string for unsigned commit ["committer", "", "", "", ""], ] } ``` The first patch in a series MAY be a cover letter in the format produced by `git format-patch`. ## Issues Issues are Markdown text that is just human-readable conversational threads related to the repository: bug reports, feature requests, questions or comments of any kind. Like patches, these SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. ```jsonc { "kind": 1621, "content": "", "tags": [ ["a", "30617::"], ["p", ""] ] } ``` ## Replies Replies are also Markdown text. The difference is that they MUST be issued as replies to either a `kind:1621` _issue_ or a `kind:1617` _patch_ event. The threading of replies and patches should follow NIP-10 rules. ```jsonc { "kind": 1622, "content": "", "tags": [ ["a", "30617::", ""], ["e", "", "", "root"], // other "e" and "p" tags should be applied here when necessary, following the threading rules of NIP-10 ["p", "", "", "mention"], ["e", "", "", "reply"], // ... ] } ``` ## Status Root Patches and Issues have a Status that defaults to 'Open' and can be set by issuing Status events. ```jsonc { "kind": 1630, // Open "kind": 1631, // Applied / Merged for Patches; Resolved for Issues "kind": 1632, // Closed "kind": 1633, // Draft "content": "", "tags": [ ["e", "", "", "root"], ["e", "", "", "reply"], // for when revisions applied ["p", ""], ["p", ""], ["p", ""], // optional for improved subscription filter efficency ["a", "30617::", ""], ["r", ""] // optional for `1631` status ["e", "", "", "mention"], // for each // when merged ["merge-commit", ""] ["r", ""] // when applied ["applied-as-commits", "", ...] ["r", ""] // for each ] } ``` The Status event with the largest created_at date is valid. The Status of a patch-revision defaults to either that of the root-patch, or `1632` (Closed) if the root-patch's Status is `1631` and the patch-revision isn't tagged in the `1631` event. ## Possible things to be added later - "branch merge" kind (specifying a URL from where to fetch the branch to be merged) - inline file comments kind (we probably need one for patches and a different one for merged files)