1package git
2
3import (
4 "fmt"
5 "os/exec"
6
7 "github.com/go-git/go-git/v5"
8 "github.com/go-git/go-git/v5/config"
9)
10
11func Fork(repoPath, source string) error {
12 _, err := git.PlainClone(repoPath, true, &git.CloneOptions{
13 URL: source,
14 SingleBranch: false,
15 })
16
17 if err != nil {
18 return fmt.Errorf("failed to bare clone repository: %w", err)
19 }
20
21 err = exec.Command("git", "-C", repoPath, "config", "receive.hideRefs", "refs/hidden").Run()
22 if err != nil {
23 return fmt.Errorf("failed to configure hidden refs: %w", err)
24 }
25
26 return nil
27}
28
29// TrackHiddenRemoteRef tracks a hidden remote in the repository. For example,
30// if the feature branch on the fork (forkRef) is feature-1, and the remoteRef,
31// i.e. the branch we want to merge into, is main, this will result in a refspec:
32//
33// +refs/heads/main:refs/hidden/feature-1/main
34func (g *GitRepo) TrackHiddenRemoteRef(forkRef, remoteRef string) error {
35 fetchOpts := &git.FetchOptions{
36 RefSpecs: []config.RefSpec{
37 config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/hidden/%s/%s", forkRef, forkRef, remoteRef)),
38 },
39 RemoteName: "origin",
40 }
41
42 err := g.r.Fetch(fetchOpts)
43 if err != nil {
44 return fmt.Errorf("failed to fetch hidden remote: %s: %w", forkRef, err)
45 }
46 return nil
47}