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 }