Skip to content

Commit ad52a59

Browse files
committed
git-remote-entire: relay helper-status before send-pack exit check
send-pack exits non-zero on per-ref rejections (D/F conflict, protected branch, server hook decline). The buffered `error refs/X <reason>` lines are what git's transport-helper.c reads to render the user-visible `! [remote rejected]` output. Forwarding helper-status only on the happy path meant Wait/feed errors swallowed those lines, leaving users with only `send-pack exited with error: exit status 1`. Relay helper-status before checking exit codes so the real reason reaches the user. Examples now surfaced: Branch protection violation ! [remote rejected] branch-test -> branch-test (upstream: push declined due to repository rule violations) error: failed to push some refs to 'X' Invalid ref: ! [remote rejected] test-prefix -> test-prefix (ref name conflicts with an existing ref namespace) error: failed to push some refs to 'X' Permissions: ! [remote rejected] new-test/repo -> new-test/repo (pushing to GitHub: tracing transport: handshake: http transport: authorization failed: unexpected requesting "https://github.com/x/x/info/refs?service=git-receive-pack" status code: 403: Permission to x/x.git denied to <user>.) error: failed to push some refs to 'X' Assisted-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Paulo Gomes <paulo@entire.io> Entire-Checkpoint: 25d3ab26f571
1 parent 9ac4c6c commit ad52a59

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

  • internal/remotehelper/githelper

internal/remotehelper/githelper/push.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,20 @@ func handlePush(ctx context.Context, t Transport, firstLine string, opts *Option
151151
return fmt.Errorf("reading helper-status: %w", err)
152152
}
153153

154+
// Relay helper-status before checking exit codes. send-pack exits
155+
// non-zero on per-ref rejections (D/F conflict, protected branch,
156+
// hook decline); the buffered `error refs/X <reason>` lines are
157+
// what git's transport-helper.c reads to print `! [remote rejected]
158+
// refs/X (<reason>)`. Returning early on Wait/feed errors swallowed
159+
// them, leaving users with only `send-pack exited with error: exit
160+
// status 1`.
161+
if _, err := stdout.Write(helperStatus); err != nil {
162+
return fmt.Errorf("writing helper-status: %w", err)
163+
}
164+
if _, err := fmt.Fprintln(stdout); err != nil {
165+
return fmt.Errorf("writing push terminator: %w", err)
166+
}
167+
154168
if err := <-feedErr; err != nil {
155169
if waitErr := sp.Wait(); waitErr != nil {
156170
return errors.Join(err, fmt.Errorf("send-pack exited after feeder error: %w", waitErr))
@@ -160,13 +174,6 @@ func handlePush(ctx context.Context, t Transport, firstLine string, opts *Option
160174
if err := sp.Wait(); err != nil {
161175
return fmt.Errorf("send-pack exited with error: %w", err)
162176
}
163-
164-
if _, err := stdout.Write(helperStatus); err != nil {
165-
return fmt.Errorf("writing helper-status: %w", err)
166-
}
167-
if _, err := fmt.Fprintln(stdout); err != nil {
168-
return fmt.Errorf("writing push terminator: %w", err)
169-
}
170177
return nil
171178
}
172179

0 commit comments

Comments
 (0)