Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
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)
}