ngit 2.4.1

nostr plugin for git
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
# Changelog

All notable changes to ngit will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [2.4.1] - 2026-04-22

### Fixed

- `fatal` errors during clone/fetch when an open PR's git data isn't available on the repository's specified git servers

## [2.4.0] - 2026-04-10

### Added

- git worktree support (a3b0bf6) - thanks to new contributor m0wer

### Fixed

- more robust patch parsing and gracefully handle errors (7a36aed, e1dd109, 6a2245d)
- panic when cloning a bare `nostr://npub/identifier` URL with no relay hints (f3a6ae8)
- repository identifiers containing reserved characters (e.g. spaces, emoji) are now percent-encoded in `nostr://` clone URLs and GRASP HTTP paths, per [NIP-34]https://github.com/nostr-protocol/nips/pull/2312
- gracefully handle errors identifying potential PR merges on push (3daf61e)

## [2.3.0] - 2026-03-05

### Added

- **Issue management**: new `ngit issue` subcommand group (`list`, `view`, `create`, `close`, `resolved`, `reopen`, `comment`, `label`) for creating and viewing NIP-34 issues and posting NIP-22 comments
- **PR comments and viewing**: `ngit pr view` shows full PR details with all comments in chronological order; `ngit pr comment` posts a NIP-22 comment
- **NIP-32 labels**: apply hashtag labels to issues and PRs via `ngit issue label` / `ngit pr label`; labels from kind-1985 events are merged with inline `t` tags (author and maintainer only)
- **Set subject**: `ngit pr set-subject` / `ngit issue set-subject` — update the displayed title of a PR or issue after the fact via a NIP-32 kind-1985 `#subject` label event (author or maintainer only)
- **Cover notes** (kind 1624, experimental): attach a summary or context note to a PR or issue via `ngit pr set-cover-note` / `ngit issue set-cover-note`; displayed in place of the description in `view` output; designed to be pinned to the top of long threads
- **Repo-only relays**: new `nostr.repo-relay-only` git config key; when `true`, nostr events are sent only to the repository's own relays, skipping personal write and default relays; enable with `git config nostr.repo-relay-only true` or `ngit init --repo-relay-only`
- **`ngit account whoami`**: show the currently logged-in account(s); improved detection of credentials set at the system git config level (`/etc/gitconfig`)
- **SKILL.md**: AI agent skill file for working with ngit repositories

### Fixed

- `ngit pr checkout` now requires `--force` when the local branch has diverged from the proposal branch
- `ngit issue list` missing `--comments` flag added
- NIP-22 comment compliance fixes; `--reply-to` flag added for threaded replies on issues and PRs
- Login local config takes precedence correctly when posting comments

## [2.2.3] - 2026-02-27

### Fixed

- Regression introduced in 28ad5440: `ngit sync` crashed with "invalid refspec refs/remotes/origin/v1.4.4^{}:refs/tags/v1.4.4^{}" on repos with annotated tags; `RepoState::try_from` now retains `^{}` peeled-tag entries in state, but the sync refspec builder did not skip them; fixed by guarding all three iteration sites in sync.rs and `identify_remote_sync_issues` in list.rs; also corrected the always-false logic bug in `invalid_nostr_state_ref`

## [2.2.2] - 2026-02-27 [YANKED]

### Added

- `ngit sync --force` now republishes the state event with a fresh timestamp even when no refs have changed, allowing users to repair repos with a corrupt or incomplete state event (e.g. missing `^{}` peeled refs for annotated tags) without needing to push a new ref
- git server push option passthrough, enabling `-o secret-scanning.skip` for grasp servers
- `ngit sync` now publishes the current state event to grasp server relays that are missing it or have a stale version before attempting git pushes, preventing rejections; per-relay state visibility is captured during the nostr fetch and surfaced via `FetchReport::state_per_relay`
- Fetch filters now request kind-5 deletion events for cached state and repo announcement events by `#e` tag (NIP-09), in addition to the existing `#a`-tagged filter; ensures deletions of these events are received even from clients that do not embed a repo coordinate in their deletion event
- `KIND_PULL_REQUEST` (kind 1618) event IDs are now included in `proposal_ids` when building fetch filters, so kind-5 deletion events that only `#e`-tag a PR Kind event (without an `#a` repo coordinate tag) are fetched and applied; previously deleted PR Kind events remained in the local cache and continued to appear as remote refs
- `FetchReport` now tracks and displays a count of kind-5 deletion events received (e.g. `"1 deletion"` in the fetch summary)
- `ngit account login` nostrconnect flow now shows current signer relays and allows changing them
- `ngit account login --bunker-url` - specify bunker URL for non-interactive nostrconnect login

### Fixed

- Annotated tags missing from `git-remote-nostr` list output; peeled `^{}` refs were stripped when parsing the nostr state event, so git could not resolve the tag to a commit and `git fetch --prune` deleted it; existing repos with affected state events are self-healed on the next push
- Fallback signer relays updated: replaced `nsec.app` with `bucket.coracle.social` and `nos.lol` for nostrconnect resilience
- `merge-base` tag in PR events generated by `git push` of a `pr/` branch was set to the parent of the PR tip instead of the actual base commit; multi-commit PRs showed only 1 commit when applied via `ngit apply`
- `git-remote-nostr` list now advertises the newest state event whose OIDs are all confirmed present on a git server or locally, rather than unconditionally using the latest nostr state event; this prevents catastrophic fetch/clone failures when a state event was published before the corresponding git push completed
- Tag tracking refs written with wrong path (`refs/remotes/origin/refs/tags/v1.0.0` instead of `refs/remotes/origin/v1.0.0`) after a push via `git-remote-nostr`, causing `ngit sync` to fail with "src refspec does not match any existing object" when syncing tags
- Annotated tag tracking refs stored with the peeled commit OID instead of the tag object OID after a push via `git-remote-nostr`; this caused `ngit sync` to push the wrong object to grasp servers, which rejected it because the nostr state event referenced the tag object OID
- `ngit sync --verbose` detailed per-relay view not shown; `--verbose` flag was ignored due to a logic error in `send_events`
- `ngit sync` using wrong refspec source (`refs/remotes/origin/refs/heads/master` instead of `refs/remotes/origin/master`), causing sync to fail with "src refspec does not match any existing object"
- State event publish failures silently swallowed during push; summary now shows `"Published to X/N relays (failed: relay1 relay2)"` instead of unconditional success message
- Grasp servers whose internal relay did not receive the state event are now skipped during push, with a clear warning; push fails with an error message when no servers remain
- New state event is now removed from the local cache and the previous state restored when a push fails entirely, so retries start from a clean baseline

## [2.2.1] - 2026-02-25

### Fixed

- IPv6 connection failures with Happy Eyeballs (RFC 8305)

## [2.2.0] - 2026-02-20

### Changed

- **AI-friendly commands** all non-interactive by default
  - Add `--defaults/-d` flag for sensible defaults
  - Add `--force/-f` flag to bypass safety guards
  - Add `--interactive/-i` flag to enable prompts
- **Simplify CLI output**
  - Add `--verbose/-v` flag for detailed output
  - show fetch/publish report if taking longer than 5s
- **Default relay updates**: replace `nos.lol` with `relay.ditto.pub` (nos.lol requires NIP-42 auth even for reads); add `relay.ditto.pub` as second default signer relay for nostrconnect resilience
- **Grasp server readiness**: poll grasp servers for readiness instead of a fixed 5-second wait

### Added

- **`ngit repo` subcommand group**: new command group for repository management operations
- **Auto-accept co-maintainership on push**: when pushing to a repo where you are listed as a maintainer but have not yet published an announcement, ngit now automatically publishes your announcement (using your grasp servers or the trusted maintainer's as fallback) and provisions your grasp server instead of failing
- `ngit account login --signer-relay` - specify custom relays for nostrconnect (auto-prefixes with `wss://` if no scheme)
- `ngit checkout <id>` - checkout a proposal branch by event-id or nevent
- `ngit apply <id>` - apply proposal patches to current branch; supports both patch and PR-format proposals
- `ngit account create` - create a new nostr account
- `ngit list --json` - output proposals as JSON
- `ngit list --status` - filter by status (open,draft,closed,applied)
- `ngit list --offline` / `ngit checkout --offline` / `ngit apply --offline` - skip relay fetching and use local cache
- `ngit init --hashtag` - specify repository hashtag
- Push options for PR title/description: `git push --push-option=title="..." --push-option=description="..."`
  - Multiline support: use `\n` for newlines in values (e.g. `--push-option=description='line1\n\nline2'`). Use single quotes to prevent shell interpretation. Use `\\n` for a literal backslash-n.
- `ngit list` output improvements: show active filter, 'To view' hint, and yellow hint lines

### Removed

- `--blossoms` flag from `ngit init` (removed from GRASP spec)
- `relay.nostr.band` from default relays (relay is now offline)

### Fixed

- Compatibility with clients that omit optional patch tags
- Branch tracking setup when checking out proposals (c85ca81)
- Handle existing local branch that is behind when checking out PR (1be46b4)
- Preserve progress bars on relay errors during clone (b8716ed)
- Show help menu when `ngit` is run without arguments (972e220)
- Various output formatting and wording improvements

## [2.1.0] - 2025-11-18

### Added

- **Adaptive relay timeouts**: Relay timeout is now 45 seconds initially, then 7 seconds based on successful connections for faster operations
- **Async git list refs operation**: Made git ref list async and include sync report inline for better visibility
- **Improved fetch reporting**: Fetch report now shows even when successful in git remote helper for better transparency

### Fixed

- **CLI output improvements**:
  - Fixed line deletion during fetch operations
  - Fixed dim coloring in CLI output
  - Fixed out of sync grasp server CLI output
- **Tag handling**: Don't attempt to fetch annotated tags that are already available locally
- **Fetch reporting**: Fixed cached profile events being incorrectly shown as new

### Changed

- Updated to rust-nostr v0.44

## [2.0.1] - Fix Account Creation on NixOS

### Fixed

- **NIP-46 bunker url privacy** tag bunker pubkey rather than user pubkey to communicate with bunker
- **Create account** show nsec for manually setting nostr.nsec git config when not able to set global git config

## [2.0.0] - Pull Request support

### Breaking Changes

- **SSH Key Authentication in nostr:// URLs**: The user field in nostr git URLs (e.g., `nym1@ssh/npub123/identifier`) is now treated as an SSH key file location rather than an SSH user. SSH key can be specified as a file within `~/.ssh` (e.g., `~/.ssh/nym1`) or as a full/relative path. Most git servers expect the SSH user to be 'git', so specifying a different SSH key is the idiomatic way to use different credentials.

### Added

- **Pull Requests Support**: Introduced complete PR functionality for large contributions that would be too big for relays as patches:
  - Generate PR events for oversized patches automatically
  - Support PR updates and PR as patch revision
  - List open/draft proposals on repo relays/servers as `pr/*` branches and all proposals as `refs/pr/*` and `refs/pr/pr-by-id/head`
  - Push PRs to custom clone URLs with auto-fork creation fallback
  - Add `--force-pr` and `--force-patch` flags for manual control
  - Full NIP-34 compliance with `merge-base` tags

- **NIP-22 Status Events Support**: Read and process NIP-22 style status events for proposals and PRs

- **ngit sync command**: New command to synchronize git servers with nostr state
  - Optional `--force` flag for forced synchronization eg deleting refs on non-GRASP servers
  - `--ref-name` parameter to limit sync to a single reference

- **ngit init improvements** (simple model for non-grasp servers):
  - Use user's grasp list for defaults instead of hardcoded options
  - List and allow selection/deselection of non-grasp servers
  - Check and fetch origin refs when missing locally
  - Publish state event and sync when existing origin matches tip

- Allow specifying non-default SSH key in `nostr://` address

### Fixed

- **Git server timeouts**: More robust timeout enforcement in both ngit binary and remote helper
- **Annotated and lightweight tags**: Proper handling and pushing of all tag types
- **nostr:// URLs with NIP-05**:
  - Fixed URLs with NIP-05 addresses without local part
  - Allow NIP-05 domain without `_@` prefix
- **Sync and fetch improvements**:
  - Don't fetch tags already available locally
  - Fetch refs missing locally before sync, fail gracefully
  - Include all valid nostr state (was incorrectly filtering)
- **Repository state**: Only use state and announcements from authorized maintainers
- **Status events**: Only use status events from author and maintainers
- **Grasp server detection**: Fix to ensure no SSH fallback when not needed
- **NIP compliance updates**:
  - Fix `t` tag: `revision-root``root-revision` (NIP-34)
  - Fix mention marker → `q` tag (NIP-10 update)
- **Error handling**: Capture more errors when updating refs
- Suppress warnings for poorly formatted proposals (only show to maintainers/author)

### Changed

- Updated to latest rust-nostr v0.43
- Updated gitworkshop.dev URL format (now uses nevent)
- Removed blossom from grasp server detection (removed from grasp spec)
- Print event description before publishing for clearer terminal UI

## [1.7.4] - 2025-07-16

### Fixed

- Apply nip46 breaking changes as remote signers remove nip04 support
- Apply relay connection timeout once, instead of per request batch
- Add git server timeouts
- Bump all dependencies

## [1.7.3] - 2025-06-20

### Changed

- Rename ngit-relay to grasp

### Fixed

- Always include HEAD in state event

## [1.7.2] - 2025-06-18

### Fixed

- Fix clone when HEAD isn't in nostr state event

## [1.7.1] - 2025-06-17

### Fixed

- Add support for `git://` clone urls

## [1.7.0] - 2025-06-03

### Added

- Quality-of-life features for ngit-relay users
  - Detect ngit-relays and only attempt using unauthenticated http protocols
  - Better sync and less errors as nostr is the only way to push
- Overhaul `ngit init`
  - Add simple / advanced mode
  - Add support for ngit-relays
  - Specify blossom servers
  - Sensible defaults
- Add resiliency - push to all maintainer's relays and git servers
- Require additional maintainers to publish announcements before pushing
- Allow users to specify fallback relays see `ngit --customize`
- Add show npub command

### Fixed

- Use newest state event found, rather than oldest
- More resilient builds for platforms and distros

## [1.6.3] - 2025-05-12

### Fixed

- Fallback to http protocol if ssh is unavailable

## [1.6.2] - 2025-05-06

### Added

- Add event description for remote signing process

### Fixed

- Fix custom ports use for git servers

### Changed

- Bump all dependencies to latest major versions

## [1.6.1] - 2025-04-02

### Changed

- Build binaries for more OSes

## [1.6.0] - 2024-12-20

### Added

- Overhaul and simplify login experience
- Add `account` api with `login`, `logout` and `export-keys` commands
- Add sign up feature targeted at users new to nostr
- Support nip05 addresses in nostr git urls (e.g., `nostr://dan@gitworkshop.dev/ngit`)
- Rework `ngit init` to make on-boarding more intuitive with simpler questions and more guidance
- Expand merge types that automatically update PR status when pushed

### Changed

- Don't create `maintainers.yaml` for new repos but continue to support it for existing projects
- Remove ngit `pull`, `push` and `fetch` api to nudge users to use native git commands with git plugin
- Bump dependencies (e.g., rust-nostr to v0.37)

### Fixed

- Fix `ngit account login` from outside of a git repository
- Add QR code border
- Make `ngit list` prompts more intuitive

## [1.5.3] - 2024-11-12

### Fixed

- Fix remote signing as nip46 update has breaking changes
- Auth to relays on requests
- Fix `pr/` branch name prefix issue
- Fix `ngit init` error when remote added before initiation
- Don't blast initiation events as munity blaster is no more
- When git-remote-nostr called directly show help instead of error

### Changed

- Bump rust-nostr to v0.36
- Replace sqlite with lmdb due to rust-nostr deprecation

## [1.5.2] - 2024-09-24

### Added

- Login via nip46 QR code
- Enable login directly in git plugin
- Add resilience to git plugin so that a poorly formatted PR will gracefully fail

## [1.5.1] - 2024-09-20

### Changed

- Git plugin reports on event broadcasting

## [1.5.0] - 2024-09-18

### Added

- New nostr url format that works better for MacOS users: `nostr://<*protocol>/<npub123>/<*relay-hint>/<identifier>` (\*optional)
- Status updates during clone, push and fetch
- Intelligent protocol selection and fallback
  - Unless unusual protocol specified in clone url it will try in this order:
    - fetch: https unauth, ssh, https
    - push: ssh, https auth
  - Save successful protocol in git config so it is tried first next time
  - Enable override from nostr url (will only use this protocol)
- Enable building binaries via nix

### Changed

- Refactor into lib and bin structure
- Bump dependencies

## [1.4.6] - 2024-09-13

### Fixed

- Fix `ngit push` and `ngit pull` when on a pr branch not in the format `pr/<branch-name>(<8-chars-from-id>)`

## [1.4.5] - 2024-08-30

### Added

- When clone url is ssh use auth for `list` and `fetch` as they are required
- When clone url is ssh, fallback to https so read events don't always require auth

### Fixed

- Stop asking for git server credentials when pushing `pr/` branch
- Fix `no repo events at specified coordinates` error via rust-nostr v0.34.1 upgrade

## [1.4.4] - 2024-08-27

### Added

- Include git plugin in release zip

## [1.4.3] - 2024-08-27

### Fixed

- Fix clone using nostr url

## [1.4.2] - 2024-08-20

### Fixed

- Only maintainers can push normal branches / tags

## [1.4.1] - 2024-08-20

### Fixed

- Fix pushing tags in git-remote-nostr

## [1.4.0] - 2024-08-20

### Added

- Add git-remote-nostr binary

## [1.3.1] - 2024-07-25

### Fixed

- Fix(init): update maintainers.yaml if identifier or relays have changed

## [1.3.0] - 2024-07-24

### Added

- NIP-46 remote signing (from Amber, etc)
- `list` breaks down proposals by status
- Local cache in `.git` to enable viewing proposals offline and reuse by other git clients
- Introduced `fetch` to download recent proposals
- Improved repo selection and handling of multiple maintainers
- Unique branch names for proposals to prevent name conflicts
- Login to different npubs for different repositories
- Store login details in git config so they can be reused by other git clients ran locally
- Add NIP-31 alt tags to events
- Add euc marker per NIP-34 tweak

### Fixed

- Ensure repo events of all maintainers are tagged in proposals
- Stop filtering out very large patches

## [1.3-beta1] - 2024-07-05

### Added

- Beta release for testing

## [1.2.1] - 2024-05-14

### Fixed

- Fix ngit init support for multiple maintainers

## [1.2.0] - 2024-05-14

### Added

- `ngit send --in-reply-to` tag any nostr notes and npubs in proposals
- `ngit send` link to proposal on gitworkshop

### Changed

- Remove unreliable relay.f7z.io from default relay set

## [1.1.2] - 2024-04-16

### Added

- Improve relay timeout behaviour
- Improve reliability via dependency upgrade
- Build via nix in ci

### Fixed

- Various reliability improvements

## [1.1.1] - 2024-03-08

### Fixed

- Fix stack overflow bug when origin remote doesn't exist

## [1.1.0] - 2024-03-08

### Added

- ngit send - improve proposal commit

## [1.0.0] - 2024-02-29

### Changed

- Major version to indicate breaking changes, not stability

## [0.1.2] - 2024-01-31

### Added

- Early release improvements

## [0.1.1] - 2024-01-26

### Added

- Early release improvements

## [0.1.0] - 2024-01-23

### Added

- Initial minor release

## [0.0.2] - 2023-05-23

### Added

- Early development release

## [0.0.1] - 2023-05-21

### Added

- Initial release