did something
This commit is contained in:
@@ -253,6 +253,84 @@ func WriteFile(repoPath, branch, filePath, content, authorName, authorEmail, mes
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileUpload holds a file path and its content for a batch commit.
|
||||
type FileUpload struct {
|
||||
Path string // repo-relative path, e.g. "src/main.go"
|
||||
Content []byte
|
||||
}
|
||||
|
||||
// WriteManyFiles commits all files in a single commit to branch. Each file path
|
||||
// must be a clean relative path — no ".." or absolute paths allowed.
|
||||
func WriteManyFiles(repoPath, branch, message, authorName, authorEmail string, files []FileUpload) error {
|
||||
if len(files) == 0 {
|
||||
return errors.New("no files to commit")
|
||||
}
|
||||
|
||||
// Validate all paths before touching the filesystem.
|
||||
for _, f := range files {
|
||||
clean := filepath.Clean(filepath.FromSlash(f.Path))
|
||||
if strings.HasPrefix(clean, "..") || filepath.IsAbs(clean) {
|
||||
return fmt.Errorf("invalid file path: %s", f.Path)
|
||||
}
|
||||
}
|
||||
|
||||
tmpDir, err := os.MkdirTemp("", "fb-upload-*")
|
||||
if err != nil {
|
||||
return fmt.Errorf("mktemp: %w", err)
|
||||
}
|
||||
|
||||
baseEnv := []string{"GIT_TERMINAL_PROMPT=0", "HOME=/tmp"}
|
||||
authorEnv := append(baseEnv,
|
||||
"GIT_AUTHOR_NAME="+authorName,
|
||||
"GIT_AUTHOR_EMAIL="+authorEmail,
|
||||
"GIT_COMMITTER_NAME="+authorName,
|
||||
"GIT_COMMITTER_EMAIL="+authorEmail,
|
||||
)
|
||||
|
||||
addWt := exec.Command("git", "worktree", "add", "--force", tmpDir, branch)
|
||||
addWt.Dir = filepath.Clean(repoPath)
|
||||
addWt.Env = baseEnv
|
||||
if out, err := addWt.CombinedOutput(); err != nil {
|
||||
os.RemoveAll(tmpDir)
|
||||
return fmt.Errorf("worktree add: %w: %s", err, out)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
rmWt := exec.Command("git", "worktree", "remove", "--force", tmpDir)
|
||||
rmWt.Dir = filepath.Clean(repoPath)
|
||||
rmWt.Env = baseEnv
|
||||
rmWt.Run()
|
||||
os.RemoveAll(tmpDir)
|
||||
}()
|
||||
|
||||
for _, f := range files {
|
||||
clean := filepath.Clean(filepath.FromSlash(f.Path))
|
||||
fullPath := filepath.Join(tmpDir, clean)
|
||||
if err := os.MkdirAll(filepath.Dir(fullPath), 0755); err != nil {
|
||||
return fmt.Errorf("mkdirall %s: %w", clean, err)
|
||||
}
|
||||
if err := os.WriteFile(fullPath, f.Content, 0644); err != nil {
|
||||
return fmt.Errorf("writefile %s: %w", clean, err)
|
||||
}
|
||||
}
|
||||
|
||||
addC := exec.Command("git", "add", ".")
|
||||
addC.Dir = tmpDir
|
||||
addC.Env = authorEnv
|
||||
if out, err := addC.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("git add: %w: %s", err, out)
|
||||
}
|
||||
|
||||
commitC := exec.Command("git", "commit", "-m", message)
|
||||
commitC.Dir = tmpDir
|
||||
commitC.Env = authorEnv
|
||||
if out, err := commitC.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("git commit: %w: %s", err, out)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Branch struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user