in commands/stack/sync/stack_sync.go [92:195]
func stackSync(f *cmdutils.Factory, iostream *iostreams.IOStreams, opts *Options, gr git.GitRunner) error {
client, err := auth.GetAuthenticatedClient(f)
if err != nil {
return fmt.Errorf("error authorizing with GitLab: %v", err)
}
opts.LabClient = client
iostream.StopSpinner("")
repo, err := f.BaseRepo()
if err != nil {
return fmt.Errorf("error determining base repo: %v", err)
}
// This prompts the user for the head repo if they're in a fork,
// allowing them to choose between their fork and the original repository
source, err := create.ResolvedHeadRepo(f)()
if err != nil {
return fmt.Errorf("error determining head repo: %v", err)
}
iostream.StartSpinner("Syncing")
stack, err := getStack()
if err != nil {
return fmt.Errorf("error getting current stack: %v", err)
}
user, _, err := client.Users.CurrentUser()
if err != nil {
return fmt.Errorf("error getting current user: %v", err)
}
opts.stack = stack
opts.target = repo
opts.source = source
opts.user = *user
err = fetchOrigin(gr)
if err != nil {
return err
}
pushAfterSync := false
for ref := range stack.Iter() {
status, err := branchStatus(&ref, gr)
if err != nil {
return fmt.Errorf("error getting branch status: %v", err)
}
switch {
case strings.Contains(status, BranchIsBehind):
err = branchBehind(&ref, gr)
if err != nil {
return err
}
case strings.Contains(status, BranchHasDiverged):
needsPush, err := branchDiverged(&ref, &stack, gr)
if err != nil {
return err
}
if needsPush {
pushAfterSync = true
}
case strings.Contains(status, NothingToCommit):
// this is fine. we can just move on.
default:
return fmt.Errorf("your Git branch is ahead, but it shouldn't be. You might need to squash your commits.")
}
if ref.MR == "" {
err := populateMR(&ref, opts, client, gr)
if err != nil {
return err
}
} else {
// we found an MR. let's get the status:
mr, _, err := mrutils.MRFromArgsWithOpts(f, []string{ref.Branch}, nil, "any")
if err != nil {
return fmt.Errorf("error getting merge request from branch: %v. Does it still exist?", err)
}
// remove the MR from the stack if it's merged
// do not remove the MR from the stack if it is closed,
// but alert the user
err = removeOldMrs(&ref, mr, &stack, gr)
if err != nil {
return fmt.Errorf("error removing merged merge request: %v", err)
}
}
}
if pushAfterSync {
err := forcePushAllWithLease(&stack, gr)
if err != nil {
return fmt.Errorf("error pushing branches to remote: %v", err)
}
}
fmt.Print(progressString("Sync finished!"))
return nil
}