// ListNewTrunkCommits returns the list of commits that are new since the last release. // By the last release we mean the last release being tested, staged or released. func ListNewTrunkCommits() ([]*git.Commit, error) { // Get git config. config, err := git.LoadConfig() if err != nil { return nil, err } var ( remoteName = config.RemoteName trunkBranch = config.TrunkBranchName releaseBranch = config.ReleaseBranchName stagingBranch = config.StagingBranchName ) // By default, use the staging branch as the --not part. // In other words, list commits that are on trunk, // but which are not reachable from the staging branch. // In case the staging branch doesn't exist, take the whole trunk. // That probably means that no release has ever been started, // so the staging branch has not been created yet. var revRange string for _, branch := range [...]string{releaseBranch, stagingBranch} { err := git.CheckOrCreateTrackingBranch(branch, remoteName) // In case the branch is ok, we use it. if err == nil { revRange = fmt.Sprintf("%v..%v", branch, trunkBranch) break } // In case the branch does not exist, it's ok and we continue. if _, ok := err.(*git.ErrRefNotFound); ok { continue } // Otherwise we return the error since something has just exploded. // This can mean that the branch is not up to date, but that is an error as well. return nil, err } if revRange == "" { revRange = trunkBranch } // Get the commits in range. commits, err := git.ShowCommitRange(revRange) if err != nil { return nil, err } // Limit the commits by date. repoConfig, err := repo.LoadConfig() if err != nil { return nil, err } enabledTimestamp := repoConfig.SalsaFlowEnabledTimestamp commits = git.FilterCommits(commits, func(commit *git.Commit) bool { return commit.AuthorDate.After(enabledTimestamp) }) return commits, nil }
func hook() error { // There are always 3 arguments passed to this hook. prevRef, newRef, flag := os.Args[1], os.Args[2], os.Args[3] // Return in case prevRef is the zero hash since that means // that this hook is being run right after 'git clone'. if prevRef == git.ZeroHash { return nil } // Return in case flag is '0'. That signals retrieving a file from the index. if flag == "0" { return nil } // Return unless the new HEAD is a core branch. isCore, err := isCoreBranchHash(newRef) if err != nil { return err } if !isCore { return nil } // Return also in case we are doing something with a temporary branch. isNewRefTemp, err := isTempBranchHash(newRef) if err != nil { return err } isPrevRefTemp, err := isTempBranchHash(prevRef) if err != nil { return err } if isNewRefTemp || isPrevRefTemp { return nil } // Get the relevant commits. // These are the commits specified by newRef..prevRef, e.g. trunk..story/foobar. commits, err := git.ShowCommitRange(fmt.Sprintf("%v..%v", newRef, prevRef)) if err != nil { return err } // Drop commits that happened before SalsaFlow bootstrap. repoConfig, err := repo.LoadConfig() if err != nil { return err } enabledTimestamp := repoConfig.SalsaFlowEnabledTimestamp() commits = git.FilterCommits(commits, func(commit *git.Commit) bool { return commit.AuthorDate.After(enabledTimestamp) }) // Collect the commits with missing Story-Id tag. missing := make([]*git.Commit, 0, len(commits)) for _, commit := range commits { // Skip merge commits. if commit.Merge != "" { continue } // Add the commit in case Story-Id tag is not set. if commit.StoryIdTag == "" { missing = append(missing, commit) } } if len(missing) == 0 { return nil } // Print the warning. return printWarning(missing) }