Skip to content

fix(setup-sync): fetch issue notes without forcing, and name diverged issues - #4

Open
mparrett wants to merge 2 commits into
nnunley:mainfrom
mparrett:fix/notes-refspec-non-forcing
Open

mparrett wants to merge 2 commits into
nnunley:mainfrom
mparrett:fix/notes-refspec-non-forcing

Conversation

@mparrett

Copy link
Copy Markdown

Fixes the data loss tracked as #e2dfdaa (your reproduction of 2026-10-10 in two scratch clones; the new test is the same shape).

What went wrong. setup-sync enable added +refs/notes/*:refs/notes/* to the fetch refspec. Every issue is one linear history on its own ref, so once someone else pushed an edit to an issue you had edited locally, your next git fetch or git pull replaced your ref with theirs and your edit was gone, except from git reflog show refs/notes/issue-<id>. The post-merge hook sent the fetch output to /dev/null, so nothing said so.

What this does.

  • setup-sync enable writes refs/notes/*:refs/notes/* without the +, and rewrites a forcing entry left by an earlier release. A diverged issue is now rejected as non-fast-forward and the local edit stays; everything else still fetches.
  • The post-merge hook lists the rejected issue refs with a line on what to do (push first, or reconcile from the reflog), instead of staying silent. A remote with no notes still exits 0 as before.
  • The user guide's "Syncing between machines" section says the same.
  • tests/test_hooks_sync.sh gains three cases: the refspec after enable with a forcing one pre-existing, a two-clone divergence where bob's local ref must survive the fetch, and the hook naming the issue. With the fix reverted the second and third fail.

What it does not do. Two people editing one issue between pushes still diverge, and there is no merge for that. This turns a silent loss into a visible refusal, which seemed like the right floor until you decide on a merge story (the "divergent edits" item from the earlier audit).

One thing about the suite. tests/test_hooks_sync.sh computes bin/ from realpath "$0" after it has already cd'd into its temp dir, so run by relative path it silently tests the installed git-issue instead of the tree. Running it by absolute path works. Left as is here; happy to fix it in a separate PR.

🤖 Generated with Claude Code

mparrett and others added 2 commits October 10, 2026 19:15
… issues

setup-sync enable wrote the fetch refspec as +refs/notes/*:refs/notes/*.
Each issue is one linear history on its own ref, so a fetch after someone
else pushed an edit to an issue you had edited locally replaced your ref
and dropped the edit; the only copy left was in the reflog (#e2dfdaa).

The refspec is now refs/notes/*:refs/notes/*, so that fetch is rejected as
non-fast-forward and the local edit stays, and enable rewrites a forcing
entry left by earlier releases. The post-merge hook used to hide the fetch
output, which would have turned the rejection into a silent no-op; it now
lists the diverged issues and says what to do. The user guide's sync
section says the same.

tests/test_hooks_sync.sh gains three cases: the refspec after enable with
a forcing one pre-existing, a two-clone divergence where the local ref
must survive the fetch, and the hook naming the issue. The suite resolves
bin/ from a relative $0 after its cd, so it has to be run by absolute path
to test the tree rather than the installed binary.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ssues

With the fetch no longer forcing, an issue edited on two clones stays
diverged until someone settles it, and its push is rejected as a
non-fast-forward. Under --atomic that one rejection held back every other
changed issue in the push, behind a warning that called it normal for new
remotes. Push each ref on its own and list the rejected ones.

The post-merge hook and user guide said to push your edit first, which
the same rejection rules out; they now give the two commands that settle
a diverged issue, keeping one side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mparrett

Copy link
Copy Markdown
Author

Added e3fefeb, which follows from the fetch change here. With the fetch no longer forcing, an issue edited on two clones stays diverged until someone picks a side, and its push is rejected as a non-fast-forward. hooks/pre-push pushed with --atomic, so that one rejection also held back every other changed issue, and the only sign was the "may be normal for new remotes" warning. It now pushes without --atomic and lists the rejected issues.

The first commit's post-merge hook and user-guide text said to push your edit first, which the same rejection rules out. Both now give the two commands that settle it: force-push to keep yours, or force-fetch to take theirs.

New test 20 in tests/test_hooks_sync.sh: a clone with one diverged issue and one new one runs the hook; the new one reaches the remote and the diverged one is named. It fails against the old hook.

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.

1 participant