gsquash/git/squash.go
2023-12-05 19:41:23 +00:00

85 lines
1.5 KiB
Go

package git
import (
"log"
"strconv"
"strings"
)
// SquashInput contains the input for Squash
type SquashInput struct {
Message *string
}
// Squash squashes everything every commit ahead of main into one commit
func (g *Git) Squash(input SquashInput) error {
// Get the current commit hash
hash, err := g.GetHash()
if err != nil {
log.Panic(err)
return err
}
// Get the commit hash on the remote
remote, err := g.GetCommitRemote()
if err != nil {
log.Panic(err)
return err
}
// If the hashes are the same, there's nothing to squash
if hash == remote {
log.Println("Already up to date")
return nil
}
// Get the number of commits ahead of main
commits, err := g.GetCommitsAhead()
if err != nil {
log.Panic(err)
return err
}
log.Println(commits, "commits ahead of main")
message := ""
if input.Message != nil {
message = *input.Message
} else {
// Get array of commit messages
out, err := g.Execute("log", "--pretty=format:%s", "-n", strconv.Itoa(commits))
if err != nil {
log.Println(out)
return err
}
messages := strings.Split(out, "\n")
// Add `-` to each message
for i, m := range messages {
messages[i] = "- " + m
}
// Join the messages
message = strings.Join(messages, "\n")
// Add header comment
message = "Squashed " + strconv.Itoa(commits) + " commits\n\n" + message
}
_, err = g.Execute("reset", "--soft", "HEAD~"+strconv.Itoa(commits))
if err != nil {
return err
}
_, err = g.Execute("commit", "-m", message)
if err != nil {
return err
}
return nil
}