Repository: jesseduffield/lazygit
File: pkg/commands/git_commands/commit_loader.go (Go)

Code before:
		}
		if passedAncestor {
			commits[i].Status = models.StatusMerged
		}
	}
	return commits
}

func (self *CommitLoader) getMergeBase(refName string) string {
	quotedBaseBranches := strings.Join(
		lo.FilterMap(self.UserConfig.Git.BaseBranches, func(branch string, _ int) (string, bool) {
			// We need to filter out base branches that don't exist, as they
			// would make the git merge-base call fail with an error
			if !self.branchExists(branch) {
				return "", false
			}

			return self.cmd.Quote(branch), true
		}), " ")

	if quotedBaseBranches == "" {
		return ""
	}

	// swallowing error because it's not a big deal; probably because there are no commits yet
	output, _ := self.cmd.New(fmt.Sprintf("git merge-base %s %s", self.cmd.Quote(refName), quotedBaseBranches)).DontLog().RunWithOutput()
	return ignoringWarnings(output)
}

func (self *CommitLoader) branchExists(branchName string) bool {
	branchExists, cacheEntryExists := self.doBranchesExist[branchName]
	if cacheEntryExists {
		return branchExists
	}

	err := self.cmd.New(fmt.Sprintf("git rev-parse --verify --quiet refs/heads/%s", self.cmd.Quote(branchName))).DontLog().Run()
	branchExists = err == nil
	self.doBranchesExist[branchName] = branchExists
	return branchExists
}

func ignoringWarnings(commandOutput string) string {
	trimmedOutput := strings.TrimSpace(commandOutput)
	split := strings.Split(trimmedOutput, "\n")
	// need to get last line in case the first line is a warning about how the error is ambiguous.
	// At some point we should find a way to make it unambiguous
	lastLine := split[len(split)-1]

	return lastLine
}


Review comment (performance):
If we need to make N+1 calls to git, I think we should go through the list and find the first branch that exists and then use that alone in the merge-base. I prefer that because:
* it spares unnecessary calls to git due to the ability to early-exit
* it's logic that's easy to explain to a user

Code after:
		}
		if commit.Status != models.StatusPushed && commit.Status != models.StatusUnpushed {
			continue
		}
		if passedAncestor {
			commits[i].Status = models.StatusMerged
		}
	}
	return commits
}

func (self *CommitLoader) getMergeBase(refName string) string {
	if self.quotedMainBranches == nil {
		self.quotedMainBranches = lo.ToPtr(self.getExistingMainBranches())
	}

	if *self.quotedMainBranches == "" {
		return ""
	}

	// We pass all configured main branches to the merge-base call; git will
	// return the base commit for the closest one.
	output, err := self.cmd.New(fmt.Sprintf("git merge-base %s %s",
		self.cmd.Quote(refName), *self.quotedMainBranches)).DontLog().RunWithOutput()
	if err != nil {
		// If there's an error, it must be because one of the main branches that
		// used to exist when we called getExistingMainBranches() was deleted
		// meanwhile. To fix this for next time, throw away our cache.
		self.quotedMainBranches = nil
	}
	return ignoringWarnings(output)
}

func (self *CommitLoader) getExistingMainBranches() string {
	return strings.Join(
		lo.FilterMap(self.UserConfig.Git.MainBranches,
			func(branchName string, _ int) (string, bool) {
				quotedRef := self.cmd.Quote("refs/heads/" + branchName)
				if err := self.cmd.New(fmt.Sprintf("git rev-parse --verify --quiet %s", quotedRef)).DontLog().Run(); err != nil {
					return "", false
				}
				return quotedRef, true
			}), " ")
}

func ignoringWarnings(commandOutput string) string {
	trimmedOutput := strings.TrimSpace(commandOutput)
	split := strings.Split(trimmedOutput, "\n")
	// need to get last line in case the first line is a warning about how the error is ambiguous.
	// At some point we should find a way to make it unambiguous
	lastLine := split[len(split)-1]