diff options
| -rw-r--r-- | main.go | 4 | ||||
| -rw-r--r-- | showtags.go | 99 | 
2 files changed, 103 insertions, 0 deletions
@@ -35,6 +35,10 @@ func main() {  		return  	}  	walkTree(t) + +	showtags(repo) +	// v0.0.8 +	printCommitsForTag(repo, "v0.22.2")  }  // lists the files in the git repo diff --git a/showtags.go b/showtags.go new file mode 100644 index 0000000..880e6d7 --- /dev/null +++ b/showtags.go @@ -0,0 +1,99 @@ +package main + +import ( +	"fmt" +	"sort" + +	git "go.wit.com/lib/libgit2" +	"go.wit.com/log" +) + +func showtags(repo *git.Repository) { +	// Map: commit OID -> list of tags pointing to it +	tagMap := make(map[string][]string) + +	// Walk through all tag names +	tags, err := repo.NewReferenceIteratorGlob("refs/tags/*") +	if err != nil { +		log.Fatalf("Failed to iterate tags: %v", err) +	} + +	for { +		ref, err := tags.Next() +		if err != nil { +			break // Done iterating +		} + +		name := ref.Shorthand() +		target, err := repo.RevparseSingle(ref.Name()) +		if err != nil { +			log.Printf("Skipping unresolved tag: %s", name) +			continue +		} + +		commitOID := target.Id().String() +		tagMap[commitOID] = append(tagMap[commitOID], name) +		log.Info("tag:", commitOID, name, target) +	} + +	// Identify and delete duplicate tags +	for commit, tagList := range tagMap { +		if len(tagList) > 1 { +			sort.Strings(tagList) +			fmt.Printf("Commit %s has duplicates: %v\n", commit, tagList) + +			// Keep the first tag, delete the rest +			for _, tag := range tagList[1:] { +				refname := "refs/tags/" + tag +				log.Info(refname) +				/* +					if err := repo.References.Remove(refname); err != nil { +						log.Printf("Failed to delete tag %s: %v", tag, err) +					} else { +						fmt.Printf("Deleted tag: %s\n", tag) +					} +				*/ +			} +		} +	} +} + +func printCommitsForTag(repo *git.Repository, tagName string) error { +	// Resolve tag reference +	ref, err := repo.References.Lookup("refs/tags/" + tagName) +	if err != nil { +		return fmt.Errorf("failed to find tag %s: %w", tagName, err) +	} + +	// Resolve to commit object (may be annotated tag or direct commit) +	obj, err := ref.Peel(git.ObjectCommit) +	if err != nil { +		return fmt.Errorf("failed to peel tag %s to commit: %w", tagName, err) +	} + +	start, err := obj.AsCommit() +	if err != nil { +		return fmt.Errorf("peeled object is not a commit: %w", err) +	} + +	// Walk the history +	walker, err := repo.Walk() +	if err != nil { +		return fmt.Errorf("failed to create walker: %w", err) +	} + +	if err := walker.Push(start.Id()); err != nil { +		return fmt.Errorf("failed to push start commit: %w", err) +	} + +	fmt.Printf("Commits for tag %s:\n", tagName) +	err = walker.Iterate(func(c *git.Commit) bool { +		fmt.Printf("%s %s\n", c.Id().String(), c.Summary()) +		return true +	}) +	if err != nil { +		return fmt.Errorf("error during walk: %w", err) +	} + +	return nil +}  | 
