test server: emit HEAD symref-target under v2 ls-refs symrefs · Entire
test server: emit HEAD symref-target under v2 ls-refs symrefs
cc9e564→main·
Soph·2mo ago·1 file·+40 added/-0 removed
The v2 ls-refs handler ignored the "symrefs" argument and never emitted HEAD with a symref-target attribute, so source-side HEAD info captured via v2 was always empty in tests. Real git emits
when the client requests "symrefs" and a ref-prefix would include HEAD (or no prefixes are given). Add that to the test server with two small helpers: coversHead checks prefix coverage, lsRefsHeadLine formats the pkt-line by resolving HEAD's symref target through the repo.
Foundation for upcoming work on surfacing source HEAD.
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
Sessions
66bf19cf9e23View transcript
Changes
1
internal/syncer
Mintegration_test.go+40
3770 unmodified lines
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
4 unmodified lines
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
240 unmodified lines
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
3770 unmodified lines
func (s *smartHTTPRepoServer) handleUploadPackV2LSRefs(w http.ResponseWriter, req v2TestCommandRequest, body []byte) {
prefixes := make([]string, 0, len(req.Args))
wantSymrefs := false
for _, arg := range req.Args {
if strings.HasPrefix(arg, "ref-prefix ") {
prefixes = append(prefixes, strings.TrimPrefix(arg, "ref-prefix "))
} else if arg == "symrefs" {
wantSymrefs = true
}
}
4 unmodified lines
}
var buf bytes.Buffer
// Real git emits HEAD with symref-target attribute under "symrefs", as
// long as a ref-prefix covers HEAD (or no prefixes are given).
if wantSymrefs && coversHead(prefixes) {
if line, ok := s.lsRefsHeadLine(); ok {
if _, err := pktline.WriteString(&buf, line); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}
for _, ref := range refs {
if _, err := pktline.WriteString(&buf, ref.Hash().String()+" "+ref.Name().String()+"\n"); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
240 unmodified lines
strings.Contains(msg, "connection reset by peer")
}
// coversHead reports whether the ls-refs prefix list would include HEAD.
func coversHead(prefixes []string) bool {
if len(prefixes) == 0 {
return true
}
for _, p := range prefixes {
if p == "HEAD" {
return true
}
}
return false
}
// lsRefsHeadLine formats a v2 ls-refs HEAD line with the symref-target
// attribute, matching what real git advertises under "symrefs".
func (s *smartHTTPRepoServer) lsRefsHeadLine() (string, bool) {
head, err := s.repo.Storer.Reference(plumbing.HEAD)
if err != nil || head.Type() != plumbing.SymbolicReference {
return "", false
}
resolved, err := s.repo.Reference(head.Target(), true)
if err != nil {
return "", false
}
return fmt.Sprintf("%s HEAD symref-target:%s\n", resolved.Hash(), head.Target()), true
}
func (s *smartHTTPRepoServer) refsMatchingPrefixes(prefixes []string) ([]*plumbing.Reference, error) {
iter, err := s.repo.Storer.IterReferences()
if err != nil {