package pijul import ( "bytes" "fmt" "os" "os/exec" ) // InitBare initializes a bare Pijul repository func InitBare(repoPath string) error { if err := os.MkdirAll(repoPath, 0755); err != nil { return fmt.Errorf("creating directory: %w", err) } cmd := exec.Command("pijul", "init") cmd.Dir = repoPath var stderr bytes.Buffer cmd.Stderr = &stderr if err := cmd.Run(); err != nil { return fmt.Errorf("pijul init: %w, stderr: %s", err, stderr.String()) } // remove .ignore auto-generated by pijul init os.Remove(fmt.Sprintf("%s/.ignore", repoPath)) return nil } // Fork clones a repository to a new location func Fork(srcPath, destPath string) error { // For local fork, we can use pijul clone cmd := exec.Command("pijul", "clone", srcPath, destPath) var stderr bytes.Buffer cmd.Stderr = &stderr if err := cmd.Run(); err != nil { return fmt.Errorf("pijul clone: %w, stderr: %s", err, stderr.String()) } return nil } // Push pushes changes to a remote func (p *PijulRepo) Push(remote string, channel string) error { args := []string{remote} if channel != "" { args = append(args, "--channel", channel) } _, err := p.runPijulCmd("push", args...) return err } // Pull pulls changes from a remote func (p *PijulRepo) Pull(remote string, channel string) error { args := []string{remote} if channel != "" { args = append(args, "--channel", channel) } _, err := p.runPijulCmd("pull", args...) return err } // Apply applies a change to the repository func (p *PijulRepo) Apply(changeHash string) error { _, err := p.runPijulCmd("apply", changeHash) return err } // Unrecord removes a change from the channel and resets the working copy // to match (like git reset --hard). func (p *PijulRepo) Unrecord(changeHash string) error { args := []string{changeHash} if p.channelName != "" { args = append(args, "--channel", p.channelName) } if _, err := p.runPijulCmd("unrecord", args...); err != nil { return err } // Reset working copy to match the channel state resetArgs := []string{} if p.channelName != "" { resetArgs = append(resetArgs, "--channel", p.channelName) } _, err := p.runPijulCmd("reset", resetArgs...) return err } // Record creates a new change (like git commit) func (p *PijulRepo) Record(message string, authors []Author) error { args := []string{"-m", message} for _, author := range authors { authorStr := author.Name if author.Email != "" { authorStr = fmt.Sprintf("%s <%s>", author.Name, author.Email) } args = append(args, "--author", authorStr) } if p.channelName != "" { args = append(args, "--channel", p.channelName) } _, err := p.runPijulCmd("record", args...) return err } // Add adds files to be tracked func (p *PijulRepo) Add(paths ...string) error { args := append([]string{}, paths...) _, err := p.runPijulCmd("add", args...) return err } // Remove removes files from tracking func (p *PijulRepo) Remove(paths ...string) error { args := append([]string{}, paths...) _, err := p.runPijulCmd("remove", args...) return err }