forked from tangled.org/core
this repo has no description

knotserver: git: track a hidden ref

anirudh.fi 1287e6b7 19ee94f4

verified
Changed files
+67 -1
appview
state
knotserver
+14
appview/state/signer.go
···
return s.client.Do(req)
}
+
func (s *SignedClient) NewHiddenRef(ownerDid, targetRepo, forkBranch, remoteBranch string) (*http.Response, error) {
+
const (
+
Method = "POST"
+
)
+
endpoint := fmt.Sprintf("/%s/%s/hidden-ref/%s/%s", ownerDid, targetRepo, forkBranch, remoteBranch)
+
+
req, err := s.newRequest(Method, endpoint, nil)
+
if err != nil {
+
return nil, err
+
}
+
+
return s.client.Do(req)
+
}
+
type UnsignedClient struct {
Url *url.URL
client *http.Client
+28 -1
knotserver/git/fork.go
···
import (
"fmt"
+
"os/exec"
"github.com/go-git/go-git/v5"
+
"github.com/go-git/go-git/v5/config"
)
func Fork(repoPath, source string) error {
_, err := git.PlainClone(repoPath, true, &git.CloneOptions{
URL: source,
-
Depth: 1,
SingleBranch: false,
})
if err != nil {
return fmt.Errorf("failed to bare clone repository: %w", err)
+
}
+
+
err = exec.Command("git", "-C", repoPath, "config", "receive.hideRefs", "refs/hidden").Run()
+
if err != nil {
+
return fmt.Errorf("failed to configure hidden refs: %w", err)
+
}
+
+
return nil
+
}
+
+
// TrackHiddenRemoteRef tracks a hidden remote in the repository. For example,
+
// if the feature branch on the fork (forkRef) is feature-1, and the remoteRef,
+
// i.e. the branch we want to merge into, is main, this will result in a refspec:
+
//
+
// +refs/heads/main:refs/hidden/feature-1/main
+
func (g *GitRepo) TrackHiddenRemoteRef(forkRef, remoteRef string) error {
+
fetchOpts := &git.FetchOptions{
+
RefSpecs: []config.RefSpec{
+
config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/hidden/%s/%s", forkRef, forkRef, remoteRef)),
+
},
+
RemoteName: "origin",
+
}
+
+
err := g.r.Fetch(fetchOpts)
+
if err != nil {
+
return fmt.Errorf("failed to fetch hidden remote: %s: %w", forkRef, err)
}
return nil
}
+2
knotserver/handler.go
···
r.Post("/git-upload-pack", h.UploadPack)
r.Get("/compare/{rev1}/{rev2}", h.Compare) // git diff-tree compare of two objects
+
r.With(h.VerifySignature).Post("/hidden-ref/{forkRef}/{remoteRef}", h.NewHiddenRef)
+
r.Route("/merge", func(r chi.Router) {
r.With(h.VerifySignature)
r.Post("/", h.Merge)
+23
knotserver/routes.go
···
return
}
+
func (h *Handle) NewHiddenRef(w http.ResponseWriter, r *http.Request) {
+
l := h.l.With("handler", "NewHiddenRef")
+
+
forkRef := chi.URLParam(r, "forkRef")
+
remoteRef := chi.URLParam(r, "remoteRef")
+
path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r))
+
gr, err := git.PlainOpen(path)
+
if err != nil {
+
notFound(w)
+
return
+
}
+
+
err = gr.TrackHiddenRemoteRef(forkRef, remoteRef)
+
if err != nil {
+
l.Error("error tracking hidden remote ref", "msg", err.Error())
+
writeError(w, "error tracking hidden remote ref", http.StatusBadRequest)
+
return
+
}
+
+
w.WriteHeader(http.StatusNoContent)
+
return
+
}
+
func (h *Handle) AddMember(w http.ResponseWriter, r *http.Request) {
l := h.l.With("handler", "AddMember")