<feed xmlns='http://www.w3.org/2005/Atom'>
<title>npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/src, branch v2.4.1</title>
<subtitle>Personal mirror of DanConwayDev/ngit-cli on git.upleb.uk
</subtitle>
<id>https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/atom?h=v2.4.1</id>
<link rel='self' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/atom?h=v2.4.1'/>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/'/>
<updated>2026-04-22T13:00:17+00:00</updated>
<entry>
<title>fix: prevent fatal clone/fetch errors when PR git data unavailable</title>
<updated>2026-04-22T13:00:17+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-04-22T13:00:17+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=e98acf8c5da5033b20aee8510485a8b4a4f4a56e'/>
<id>urn:sha1:e98acf8c5da5033b20aee8510485a8b4a4f4a56e</id>
<content type='text'>
Only advertise `refs/heads/pr/*` branches once their tip OIDs are
confirmed present locally; prevents `fatal: bad object` / `remote did
not send all necessary objects` errors during clone/fetch when a PR tip
lives on a different git server than the one that won the bulk prefetch
race.

After the bulk prefetch, collect remaining missing PR tip OIDs and do
one batch fetch per repo git server using only the OIDs that server has
advertised; break early once all are satisfied and skip servers that
carry none. Avoids batch-poisoning (a server rejects the whole request
if any single OID is absent) and redundant connections.

Restrict mop-up fetches and run_fetch to the repo's declared git
servers; do not fetch from clone-tag URLs in PR events - they are
submitter-supplied and could let a malicious or slow server stall every
clone/fetch operation.

Also apply rustfmt and fix clippy warnings.
</content>
</entry>
<entry>
<title>fix: percent-encode identifier in nostr:// URLs and GRASP HTTP paths</title>
<updated>2026-04-10T16:30:02+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-04-10T16:25:26+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=47622eb762e802a9caa2f37d8162eaaf2f9aa9ca'/>
<id>urn:sha1:47622eb762e802a9caa2f37d8162eaaf2f9aa9ca</id>
<content type='text'>
Repository identifiers can contain any characters per NIP-01 d-tag rules.
Encode them in nostr:// clone URLs (display and parse) and in GRASP
/&lt;npub&gt;/&lt;identifier&gt;.git paths, aligning with NIP-34 and GRASP-01.
</content>
</entry>
<entry>
<title>feat: git worktree support</title>
<updated>2026-03-30T16:29:23+00:00</updated>
<author>
<name>m0wer</name>
<email>m0wer@sgn.space</email>
</author>
<published>2026-03-29T14:45:52+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=820fd706a24be7a58554a27e411e120cfa28d9a6'/>
<id>urn:sha1:820fd706a24be7a58554a27e411e120cfa28d9a6</id>
<content type='text'>
Git worktrees don't have a .git directory with a parent, so we need to
look for the git dir via git2's Repository::discover() and then look for
the cache database there. This allows the client to work correctly when
run from a worktree, and also allows the cache database to be shared
between the main repo and its worktrees (since they share the same git
dir and thus the same cache path).
</content>
</entry>
<entry>
<title>fix(patch): accept reconstructed OID when commit id mismatch occurs</title>
<updated>2026-03-30T16:29:22+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-03-30T11:43:55+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=e3276e74bc45cb4fb8f158b8249bee3d12a0805f'/>
<id>urn:sha1:e3276e74bc45cb4fb8f158b8249bee3d12a0805f</id>
<content type='text'>
When applying a patch, if the reconstructed commit OID doesn't match
the tagged commit id (after the existing amend attempt), accept the
reconstructed OID rather than erroring. The diff is applied correctly
regardless of the mismatch; apply_patch_chain already threads the
actual OID forward via next_parent_override so the chain remains
consistent.

Mismatches can occur for several reasons: GPG-signed commits where
libgit2's commit_create_buffer produces subtly different bytes than
the original git commit, patches produced with non-standard tooling,
or edge cases like the diff.noprefix issue fixed in 7a36aed.
</content>
</entry>
<entry>
<title>fix(patch): don't error on commit id mismatch for pgp-signed commits</title>
<updated>2026-03-30T16:29:20+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-03-30T10:54:31+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=33a72aa745ea6b6594bacfb71ea8ff2778f9b748'/>
<id>urn:sha1:33a72aa745ea6b6594bacfb71ea8ff2778f9b748</id>
<content type='text'>
When applying a patch with a pgp signature, commit_create_buffer +
commit_signed reconstructs the signed commit object. The resulting OID
matches the original only if commit_create_buffer produces the exact
same bytes that git originally signed — which isn't guaranteed across
different git implementations or versions.

The existing amend workaround (which re-applies author/committer to
recover the correct OID) is preserved for unsigned commits. For
pgp-signed commits the amend still runs but the mismatch bail is
skipped, since the tree, author, committer, message and signature are
all correct regardless of the OID difference.
</content>
</entry>
<entry>
<title>fix(patch): handle diff.noprefix and normalize non-standard diff paths</title>
<updated>2026-03-30T16:29:19+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-03-30T08:54:31+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=3a03cca6eb6597c19f5146c5f0d18f9230eb0fae'/>
<id>urn:sha1:3a03cca6eb6597c19f5146c5f0d18f9230eb0fae</id>
<content type='text'>
libgit2 respects the user's `diff.noprefix` git config when generating
patches via `git_email_create_from_commit`, producing diffs without the
standard `a/`/`b/` path prefixes. `git2::Diff::from_buffer` always
expects the standard prefix format and fails with "header filename does
not contain 1 path components" when it is absent.

Two fixes:
- In `make_patch_from_commit`: explicitly set `old_prefix("a/")` and
  `new_prefix("b/")` on the diff options so ngit always generates
  interoperable patches regardless of the submitter's git config.
- In `create_commit_from_patch`: normalize no-prefix diffs before
  passing to `git2::Diff::from_buffer`, as a defensive measure for
  patches already published by affected ngit versions or other tools.

Adds unit tests for the normalization function covering: no-op on
already-prefixed diffs, single and multi-file patches, new/deleted
files (/dev/null preservation), and end-to-end libgit2 parse
verification.
</content>
</entry>
<entry>
<title>fix(client): panic cloning bare npub nostr:// URL with no relay hints</title>
<updated>2026-03-20T09:25:02+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-03-20T09:25:02+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=f3a6ae82ccee44dc3b66a66caafe1bb39e7a46a6'/>
<id>urn:sha1:f3a6ae82ccee44dc3b66a66caafe1bb39e7a46a6</id>
<content type='text'>
When cloning a nostr:// URL containing only an npub and identifier (no
relay hints), and nothing is cached yet, the relay set was empty because
fallback relays were intentionally skipped when a coordinate was present.
This caused an unwrap() on a None from reduce() over an empty iterator.

Fall back to fallback relays when the coordinate-derived relay set is
still empty after processing all hints, and replace unwrap() with
map_or() as a defensive guard.
</content>
</entry>
<entry>
<title>fix(push): gracefully handle errors identifying potential PR merges</title>
<updated>2026-03-09T10:02:25+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-03-09T09:14:03+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=3daf61e74c8969c91333bc92c4914c8c6077592c'/>
<id>urn:sha1:3daf61e74c8969c91333bc92c4914c8c6077592c</id>
<content type='text'>
Errors from get_merged_status_events no longer abort the push; the
call site now uses if let Ok(...) so failures are silently skipped.
Also replace an .unwrap() in create_merge_events with a safe
.map().unwrap_or_default() to avoid any panic in that path.
</content>
</entry>
<entry>
<title>fix(pr-checkout): require --force on diverged proposal branch</title>
<updated>2026-03-05T22:12:07+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-03-05T21:25:50+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=f6d1e03dc99b3ea48cb6e4bd1d3371dd924a567a'/>
<id>urn:sha1:f6d1e03dc99b3ea48cb6e4bd1d3371dd924a567a</id>
<content type='text'>
checkout_patch() previously re-applied the patch chain whenever the local
branch tip didn't match the published tip, silently overwriting local
amendments and rebased revisions without warning.

Now detects the relationship between local and published tips:
- up to date: check out as-is
- behind (local is ancestor of published): fast-forward, no flag needed
- local commits on top (published is ancestor of local): check out as-is
- diverged (neither ancestor): bail with guidance, --force to overwrite
- published tip not found locally and branch exists: same as diverged

Also adds --force flag to `ngit pr checkout` to explicitly opt in to
overwriting a diverged branch, covering both local amendments and
author force-pushes.

Bug discovered during test implementation in tests/ngit_pr_checkout.rs.
</content>
</entry>
<entry>
<title>refactor(set-subject): remove alt tag from subject label event</title>
<updated>2026-03-05T19:11:43+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-03-05T19:11:43+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-cli-mirror/commit/?id=84a197700cac6b2ef72cf0723474ac3185c5d1de'/>
<id>urn:sha1:84a197700cac6b2ef72cf0723474ac3185c5d1de</id>
<content type='text'>
</content>
</entry>
</feed>
