Skip to content

nip34: add refs to git repo event#1249

Merged
fiatjaf merged 1 commit into
nostr-protocol:masterfrom
DanConwayDev:nip34-refs
Aug 1, 2024
Merged

nip34: add refs to git repo event#1249
fiatjaf merged 1 commit into
nostr-protocol:masterfrom
DanConwayDev:nip34-refs

Conversation

@DanConwayDev
Copy link
Copy Markdown
Contributor

so that the event can be used as a source of truth for the state of refs such as branches and tags.

this could be useful as:

  1. a way to reduce trust in git server.(s) so they no longer act as a source of truth. A nip34 git remote-helper could proxy requests to git servers and only pull updates when they match the state listed in the repo event.
  2. a form of authorisation for nip34 git server implementations such as song
  3. a way of enabling experimentation with other protocols for hosting and accessing git data. eg a blossom git remote helper

@vitorpamplona
Copy link
Copy Markdown
Collaborator

Are you doing another array inside the tag array?

["refs", ["heads/<branch-name>","<commit-id>"], ...]

Is that possible? Tags are supposed to be strings not arrays.

Why not just multiple refs?

["refs", "heads/<branch-name>","<commit-id>"],
["refs", "heads/<branch-name>","<commit-id>"],

@fiatjaf
Copy link
Copy Markdown
Member

fiatjaf commented May 21, 2024

I like this, but I don't know if it's better than having a different kind like

{
  "kind": 1034,
  "tags": [
    ["r", "heads/master", "<commit-id>"]
  ]
}

and then we can have a bunch of these? But relays should probably delete old ones.

I guess the replaceable thing works better.

But then maybe we should have a different kind so the core repository metadata doesn't have to be updated every time we push a commit:

{
  "kind": 30618,
  "tags": [
    ["d", "<repo-id>"],
    ["refs", "<heads|tags>/<branch-or-tag-name>","<commit-id>"] // can appear multiple times for multiple refs
  ]
}

@DanConwayDev
Copy link
Copy Markdown
Contributor Author

@vitorpamplona, your right, I updated it to reflect your suggestion.

Less updates to the announcement event would be preferable. There may be a scenario where the author wasn't to stop tracking state using nostr but later changes there mind.

I've tried to address that with this update.

@DanConwayDev
Copy link
Copy Markdown
Contributor Author

I previously wrote some code that listed a number of <parent-commit-id> as additional values in the refs tag.

This improves the UX when the state event is ahead of the git server. Currently in this scenario git pull wouldn't know how far ahead / behind the state event is from the git server. Listing the parent ids would enable reporting such as 3 ahead 2 behind.

This could be added as an optional part of the nip. What do you think?

@lez
Copy link
Copy Markdown

lez commented May 21, 2024

If there can be multiple maintainers who are able to push the master branch, we need a mechanism to find out which maintainer has pushed the last time.
We should fetch all kind 30618 events, and use the latest one as source of truth about the ref "heads/master" points to.

@lez
Copy link
Copy Markdown

lez commented May 24, 2024

Why not just multiple refs?

["refs", "heads/<branch-name>","<commit-id>"],
["refs", "heads/<branch-name>","<commit-id>"],

Maybe we are better off staying closer to git internal representation of refs.
This one is easier to deal with in code, and it's easier to understand for devs who are already familiar with git.

["refs/heads/master", "<commit-id>"],
["refs/tags/v1.0.0", "<commit-id>"],
["HEAD", "ref: refs/heads/master"],

@fiatjaf
Copy link
Copy Markdown
Member

fiatjaf commented May 24, 2024

If there can be multiple maintainers who are able to push the master branch, we need a mechanism to find out which maintainer has pushed the last time.
We should fetch all kind 30618 events, and use the latest one as source of truth about the ref "heads/master" points to.

Many people can publish 30618 events pointing to the same git server, if that's what you mean. Should work fine, you can pick whatever you want -- although I think that users should get just the last one issued by the pubkey that they typed by default.

@fiatjaf
Copy link
Copy Markdown
Member

fiatjaf commented May 24, 2024

Maybe we are better off staying closer to git internal representation of refs.
This one is easier to deal with in code, and it's easier to understand for devs who are already familiar with git.

["refs/heads/master", "<commit-id>"],
["refs/tags/v1.0.0", "<commit-id>"],
["HEAD", "ref: refs/heads/master"],

Either way is fine to me. This looks more elegant, but the other is easier to write simple functions that parse and list all refs.

@DanConwayDev
Copy link
Copy Markdown
Contributor Author

listing additional maintainers in the announcement event signals trust in the announcement and state events they publish against the same identifier.

clients should fetch events published by all of these pubkeys and use the one with the largest non-future created_at parameter.

I touched on the reason in the original nip34 PR:

Should I have to wait for the specific maintainer that I am referencing to update their repo event before I can pull the latest changes that another maintainer pushed a day or so ago? This is not a good UX and user may bypass the nostr event and trust the pgp signed commits on the git server.

#997 (comment)

@DanConwayDev
Copy link
Copy Markdown
Contributor Author

["refs/heads/master", "<commit-id>"],
["refs/tags/v1.0.0", "<commit-id>"],
["HEAD", "ref: refs/heads/master"],

Either way is fine to me. This looks more elegant, but the other is easier to write simple functions that parse and list all refs.

I think lez is right. staying closer to git internals is probably better. Clients would want to selectively filter the tags anyway to avoid using refs/remote/*, etc.

@lez
Copy link
Copy Markdown

lez commented May 26, 2024

["refs/heads/master", "<commit-id>"],
["refs/tags/v1.0.0", "<commit-id>"],
["HEAD", "ref: refs/heads/master"],

Either way is fine to me. This looks more elegant, but the other is easier to write simple functions that parse and list all refs.

I think lez is right. staying closer to git internals is probably better. Clients would want to selectively filter the tags anyway to avoid using refs/remote/*, etc.

We could get the best of both approaches by using

["ref", "refs/heads/master", "<commit-id>"],
["ref", "refs/tags/RELEASE_v1.0", "<commit-id>"],
["HEAD", "ref: refs/heads/master"]

@fiatjaf
Copy link
Copy Markdown
Member

fiatjaf commented Jun 6, 2024

Is this ready to merge?

so that the event can be used as a source of truth for the state of refs
such as branches and tags

this could be useful as:

1. a way to reduce trust in git server(s) so they no longer act as a
   source of truth. a nip34 git remote-helper could proxy requests to
   git servers and only pull updates when they match the state listed in
   the repo event.
2. a form of authorisation for nip34 git server implementations
   such as song
3. a way of enabling experimentation with other protocols for hosting
   and accessing git data. eg a blossom git remote helper
@DanConwayDev
Copy link
Copy Markdown
Contributor Author

I just made the suggested changes. Don't we need some production implementations to merge this?

@lez
Copy link
Copy Markdown

lez commented Jun 9, 2024

I just made the suggested changes. Don't we need some production implementations to merge this?

the implementation I'm aware of (far from production): https://github.com/lez/git-remote-nostr

@DanConwayDev
Copy link
Copy Markdown
Contributor Author

I've implemented this in a git remote helper.

The vision here is for git servers to act just as dumb data relays.

I plan to release it once, I've added some features around pulling and pushing nip34 patches.

Feel free to try it out by building from the main branch.

---more details---
It uses the state announcement as the source of truth and downloads commits from one of the git servers listed in the clone tag of the repo announcement.

If a state announcement doesn't exist it falls back to proxying the first git server listed the repo announcement.

If it successfully pushes to one of the git server, it then updates the state announcement, before attempting to push to the remain git severs.

@fiatjaf let me know if you plan to implement this as an alternative authorization for song and I'll get it to broadcast the event first.

@fiatjaf
Copy link
Copy Markdown
Member

fiatjaf commented Aug 1, 2024

I plan many things, but I haven't touched the git stuff in a while. I have to understand it better before implementing but these sound like good ideas. We should just merge this if you tell me it's still up-to-date.

@DanConwayDev
Copy link
Copy Markdown
Contributor Author

I plan many things, but I haven't touched the git stuff in a while. I have to understand it better before implementing but these sound like good ideas. We should just merge this if you tell me it's still up-to-date.

I implemented it as written and it seems to work alright.

@fiatjaf fiatjaf merged commit 788ffb0 into nostr-protocol:master Aug 1, 2024
@AsaiToshiya AsaiToshiya mentioned this pull request Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants