in commands/stack/save/stack_save.go [24:149]
func NewCmdSaveStack(f *cmdutils.Factory, gr git.GitRunner, getText cmdutils.GetTextUsingEditor) *cobra.Command {
stackSaveCmd := &cobra.Command{
Use: "save",
Short: `Save your progress within a stacked diff. (EXPERIMENTAL.)`,
Long: `Save your current progress with a diff on the stack.
` + text.ExperimentalString,
Example: heredoc.Doc(`
$ glab stack save added_file
$ glab stack save . -m "added a function"
$ glab stack save -m "added a function"`),
RunE: func(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("message") && cmd.Flags().Changed("description") {
return &cmdutils.FlagError{Err: errors.New("specify either of --message or --description.")}
}
// check if there are even any changes before we start
err := checkForChanges()
if err != nil {
return fmt.Errorf("could not save: %v", err)
}
// a description is required, so ask if one is not provided
if description == "" {
description, err = promptForCommit(f, getText, "")
if err != nil {
return fmt.Errorf("error getting commit message: %v", err)
}
}
s := spinner.New(spinner.CharSets[11], 100*time.Millisecond)
// git add files
_, err = addFiles(args[0:])
if err != nil {
return fmt.Errorf("error adding files: %v", err)
}
// get stack title
title, err := git.GetCurrentStackTitle()
if err != nil {
return fmt.Errorf("error running Git command: %v", err)
}
author, err := git.GitUserName()
if err != nil {
return fmt.Errorf("error getting Git author: %v", err)
}
// generate a SHA based on: commit message, stack title, Git author name
sha, err := generateStackSha(description, title, string(author), time.Now())
if err != nil {
return fmt.Errorf("error generating hash for stack branch name: %v", err)
}
// create branch name from SHA
branch, err := createShaBranch(f, sha, title)
if err != nil {
return fmt.Errorf("error creating branch name: %v", err)
}
// create the branch prefix-stack_title-SHA
err = git.CheckoutNewBranch(branch)
if err != nil {
return fmt.Errorf("error running branch checkout: %v", err)
}
// commit files to branch
_, err = commitFiles(description)
if err != nil {
return fmt.Errorf("error committing files: %v", err)
}
stack, err := git.GatherStackRefs(title)
if err != nil {
return fmt.Errorf("error getting refs from file system: %v", err)
}
var stackRef git.StackRef
if !stack.Empty() {
lastRef := stack.Last()
// update the ref before it (the current last ref)
err = git.UpdateStackRefFile(title, git.StackRef{
Prev: lastRef.Prev,
MR: lastRef.MR,
Description: lastRef.Description,
SHA: lastRef.SHA,
Branch: lastRef.Branch,
Next: sha,
})
if err != nil {
return fmt.Errorf("error updating old ref: %v", err)
}
stackRef = git.StackRef{Prev: lastRef.SHA, SHA: sha, Branch: branch, Description: description}
} else {
stackRef = git.StackRef{SHA: sha, Branch: branch, Description: description}
}
err = git.AddStackRefFile(title, stackRef)
if err != nil {
return fmt.Errorf("error creating stack file: %v", err)
}
if f.IO.IsOutputTTY() {
color := f.IO.Color()
fmt.Fprintf(
f.IO.StdOut,
"%s %s: Saved with message: \"%s\".\n",
color.ProgressIcon(),
color.Blue(title),
description,
)
}
s.Stop()
return nil
},
}
stackSaveCmd.Flags().StringVarP(&description, "description", "d", "", "Description of the change.")
stackSaveCmd.Flags().StringVarP(&description, "message", "m", "", "Alias for the description flag.")
return stackSaveCmd
}