diff --git a/cmd/root.go b/cmd/root.go index 194218c..ce1f569 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -30,6 +30,7 @@ var allowDirty bool var currentTag string var latestTag bool var dryRun bool +var onlyAncestors bool var rootCmd = &cobra.Command{ Use: "bump", @@ -52,6 +53,7 @@ func init() { rootCmd.PersistentFlags().BoolVar(&allowDirty, "allow-dirty", false, "allow usage of bump on dirty git") rootCmd.PersistentFlags().BoolVar(&latestTag, "latest-tag", true, "use latest tag, prompt tags if false") rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "Don't touch git repository") + rootCmd.PersistentFlags().BoolVar(&onlyAncestors, "only-ancestors", true, "Ignore tags which are not ancestors of HEAD") } @@ -68,7 +70,7 @@ func preRun(cmd *cobra.Command, args []string) { } if !latestTag { - tags, err := g.Tags() + tags, err := g.Tags(onlyAncestors) if err != nil { log.Fatalf("error tags: %s", err) } @@ -85,7 +87,7 @@ func preRun(cmd *cobra.Command, args []string) { } fmt.Printf("You choose %q\n", currentTag) } else { - currentTag, err = g.LatestTag() + currentTag, err = g.LatestTag(onlyAncestors) if err != nil { log.Fatalf("Can't get latest tag: %s", err) } diff --git a/pkg/git/git.go b/pkg/git/git.go index d99e210..f8c8bb0 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -102,17 +102,34 @@ func (g *Git) CurrentCommit() (string, error) { return headSha, nil } -func (g *Git) Tags() ([]string, error) { - tags, _, err := g.tags() +func (g *Git) currentCommitObject() (*object.Commit, error) { + var headCommit *object.Commit + + headRef, err := g.repository.Head() + if err != nil { + return headCommit, err + } + headHash := headRef.Hash() + headCommit, err = g.repository.CommitObject(headHash) + + if err != nil { + return headCommit, err + } + + return headCommit, nil +} + +func (g *Git) Tags(onlyAncestors bool) ([]string, error) { + tags, _, err := g.tags(onlyAncestors) return tags, err } -func (g *Git) LatestTag() (string, error) { - _, tag, err := g.tags() +func (g *Git) LatestTag(onlyAncestors bool) (string, error) { + _, tag, err := g.tags(onlyAncestors) return tag, err } -func (g *Git) tags() ([]string, string, error) { +func (g *Git) tags(onlyAncestors bool) ([]string, string, error) { var latestTagName string var tags []string var latestTagCommit *object.Commit @@ -122,6 +139,11 @@ func (g *Git) tags() ([]string, string, error) { return tags, latestTagName, err } + headCommit, err := g.currentCommitObject() + if err != nil { + return tags, latestTagName, err + } + err = tagRefs.ForEach(func(tagRef *plumbing.Reference) error { revision := plumbing.Revision(tagRef.Name().String()) tagCommitHash, err := g.repository.ResolveRevision(revision) @@ -133,16 +155,30 @@ func (g *Git) tags() ([]string, string, error) { if err != nil { return err } - tags = append(tags, tagRef.Name().Short()) - if latestTagCommit == nil { - latestTagCommit = commit - latestTagName = tagRef.Name().Short() - } + useTag := true - if commit.Committer.When.After(latestTagCommit.Committer.When) { - latestTagCommit = commit - latestTagName = tagRef.Name().Short() + if onlyAncestors { + isAncestor, err := commit.IsAncestor(headCommit) + if err != nil { + return err + } + if !isAncestor { + useTag = false + } + } + if useTag { + tags = append(tags, tagRef.Name().Short()) + + if latestTagCommit == nil { + latestTagCommit = commit + latestTagName = tagRef.Name().Short() + } + + if commit.Committer.When.After(latestTagCommit.Committer.When) { + latestTagCommit = commit + latestTagName = tagRef.Name().Short() + } } return nil