Skip to content

Commit 6327718

Browse files
Cherry pick
1 parent 7bee093 commit 6327718

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

pkg/cli/source.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Currently only supports git-checkout.
6060
Repository: step.With["repository"],
6161
Destination: destination,
6262
ExpectedCommit: step.With["expected-commit"],
63+
CherryPicks: step.With["cherry-picks"],
6364
}
6465

6566
if err := source.GitCheckout(ctx, opts); err != nil {

pkg/source/git.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"context"
1919
"fmt"
2020
"os"
21+
"os/exec"
22+
"strings"
2123

2224
"github.com/chainguard-dev/clog"
2325
"github.com/go-git/go-git/v5"
@@ -28,6 +30,7 @@ type GitCheckoutOptions struct {
2830
Repository string
2931
Destination string
3032
ExpectedCommit string
33+
CherryPicks string
3134
}
3235

3336
func GitCheckout(ctx context.Context, opts *GitCheckoutOptions) error {
@@ -77,5 +80,70 @@ func GitCheckout(ctx context.Context, opts *GitCheckoutOptions) error {
7780

7881
log.Infof("Checked out commit %s", head.Hash().String())
7982

83+
// Apply cherry-picks if specified
84+
if opts.CherryPicks != "" {
85+
log.Infof("Applying cherry-picks")
86+
picks, err := parseCherryPicks(opts.CherryPicks)
87+
if err != nil {
88+
return fmt.Errorf("failed to parse cherry-picks: %w", err)
89+
}
90+
91+
if err := applyCherryPicks(ctx, opts.Destination, picks); err != nil {
92+
return fmt.Errorf("failed to apply cherry-picks: %w", err)
93+
}
94+
}
95+
96+
return nil
97+
}
98+
99+
func parseCherryPicks(input string) ([]string, error) {
100+
var commits []string
101+
lines := strings.Split(input, "\n")
102+
103+
for _, line := range lines {
104+
// Trim whitespace
105+
line = strings.TrimSpace(line)
106+
107+
// Skip empty lines and comments
108+
if line == "" || strings.HasPrefix(line, "#") {
109+
continue
110+
}
111+
112+
// Parse format: [branch/]commit: comment
113+
// We only care about the commit hash
114+
parts := strings.SplitN(line, ":", 2)
115+
if len(parts) != 2 {
116+
return nil, fmt.Errorf("invalid cherry-pick format (expected '[branch/]commit: comment'): %s", line)
117+
}
118+
119+
pickSpec := strings.TrimSpace(parts[0])
120+
121+
// Strip optional branch prefix (we don't need it with full clone)
122+
commit := pickSpec
123+
if slashIdx := strings.Index(pickSpec, "/"); slashIdx != -1 {
124+
commit = pickSpec[slashIdx+1:]
125+
}
126+
127+
commits = append(commits, commit)
128+
}
129+
130+
return commits, nil
131+
}
132+
133+
func applyCherryPicks(ctx context.Context, repoPath string, commits []string) error {
134+
log := clog.FromContext(ctx)
135+
136+
for _, commit := range commits {
137+
log.Infof("Cherry-picking %s", commit)
138+
139+
cmd := exec.CommandContext(ctx, "git", "cherry-pick", "-x", commit)
140+
cmd.Dir = repoPath
141+
cmd.Stdout = os.Stdout
142+
cmd.Stderr = os.Stderr
143+
if err := cmd.Run(); err != nil {
144+
return fmt.Errorf("failed to cherry-pick %s: %w", commit, err)
145+
}
146+
}
147+
80148
return nil
81149
}

0 commit comments

Comments
 (0)