refJoin creates a temporary git repository, adds the given refs as remotes, fetches them, and returns a GitCLI instance.
(ctx context.Context, refs []*GitRef)
| 583 | // refJoin creates a temporary git repository, adds the given refs as remotes, |
| 584 | // fetches them, and returns a GitCLI instance. |
| 585 | func refJoin(ctx context.Context, refs []*GitRef) (_ *gitutil.GitCLI, _ []string, _ func() error, rerr error) { |
| 586 | tmpDir, err := os.MkdirTemp("", "dagger-mergebase") |
| 587 | if err != nil { |
| 588 | return nil, nil, nil, fmt.Errorf("failed to create temp dir: %w", err) |
| 589 | } |
| 590 | cleanup := func() error { |
| 591 | return os.RemoveAll(tmpDir) |
| 592 | } |
| 593 | defer func() { |
| 594 | if rerr != nil { |
| 595 | cleanup() |
| 596 | } |
| 597 | }() |
| 598 | git := gitutil.NewGitCLI( |
| 599 | gitutil.WithDir(tmpDir), |
| 600 | gitutil.WithGitDir(filepath.Join(tmpDir, ".git")), |
| 601 | ) |
| 602 | if _, err := git.Run(ctx, "-c", "init.defaultBranch=main", "init"); err != nil { |
| 603 | return nil, nil, nil, fmt.Errorf("failed to init temp repo: %w", err) |
| 604 | } |
| 605 | |
| 606 | eg, egCtx := errgroup.WithContext(ctx) |
| 607 | mu := sync.Mutex{} // cannot simultaneously add+fetch remotes |
| 608 | commits := make([]string, len(refs)) |
| 609 | |
| 610 | for i, ref := range refs { |
| 611 | eg.Go(func() error { |
| 612 | commits[i] = ref.Ref.SHA |
| 613 | return ref.Backend.mount(egCtx, 0, false, func(gitN *gitutil.GitCLI) error { |
| 614 | remoteURL, err := gitN.URL(egCtx) |
| 615 | if err != nil { |
| 616 | return err |
| 617 | } |
| 618 | remoteName := fmt.Sprintf("origin%d", i+1) |
| 619 | mu.Lock() |
| 620 | defer mu.Unlock() |
| 621 | if _, err := git.Run(egCtx, "remote", "add", remoteName, remoteURL); err != nil { |
| 622 | return fmt.Errorf("failed to add remote %s: %w", remoteName, err) |
| 623 | } |
| 624 | if _, err := git.Run(egCtx, "fetch", "--no-tags", remoteName, ref.Ref.SHA); err != nil { |
| 625 | return fmt.Errorf("failed to fetch ref %d: %w", i+1, err) |
| 626 | } |
| 627 | return nil |
| 628 | }) |
| 629 | }) |
| 630 | } |
| 631 | |
| 632 | if err := eg.Wait(); err != nil { |
| 633 | return nil, nil, nil, err |
| 634 | } |
| 635 | return git, commits, cleanup, nil |
| 636 | } |