enforce lifecycle contracts and scratch transport

This commit is contained in:
kami
2026-07-26 20:45:22 +04:00
parent 952c061c9d
commit f748be194a
5 changed files with 88 additions and 10 deletions
+27
View File
@@ -194,6 +194,16 @@ func ScratchCommit(root, branch, message string) error {
if strings.TrimSpace(message) == "" {
return errors.New("scratch commit message required")
}
status, err := exec.Command("git", "-C", root, "status", "--porcelain", "--", "TASK.md").Output()
if err != nil {
return err
}
if len(status) != 0 {
return errors.New("TASK.md is immutable")
}
if strings.TrimSpace(message) == "" {
return errors.New("scratch commit message required")
}
for _, args := range [][]string{{"switch", "-c", branch}, {"add", "-A"}, {"commit", "-m", message}} {
if err := exec.Command("git", append([]string{"-C", root}, args...)...).Run(); err != nil {
return err
@@ -202,6 +212,23 @@ func ScratchCommit(root, branch, message string) error {
return nil
}
func ScratchPush(root, branch, remote string) error {
if branch == "" || remote == "" {
return errors.New("scratch branch and remote required")
}
return exec.Command("git", "-C", root, "push", remote, branch).Run()
}
func ScratchPull(root, branch, remote string) error {
if branch == "" || remote == "" {
return errors.New("scratch branch and remote required")
}
if err := exec.Command("git", "-C", root, "fetch", remote, branch).Run(); err != nil {
return err
}
return exec.Command("git", "-C", root, "merge", "--ff-only", "FETCH_HEAD").Run()
}
// ScratchSync pushes/pulls a scratch branch. Pull uses fast-forward-only to
// avoid silently merging independent WIP histories.
func ScratchSync(root, branch, remote string, push bool) error {