List commits associated with a given tag with JGit

时光总嘲笑我的痴心妄想 提交于 2019-12-01 18:12:39

问题


I need to create a history file that details all tags and for each tag, all its commits.

I've tried to call getTags() on the repository object and use those object id's, but they are not commit id's.

I also tried to use getAllRefsByPeeledObjectId() on the repository and that does bring back commits but I can't associate them to tags.

Any ideas?


回答1:


List all Tags:

List<Ref> call = new Git(repository).tagList().call();
for (Ref ref : call) {
    System.out.println("Tag: " + ref + " " + ref.getName() + " " + ref.getObjectId().getName());
}

List commits based on tag:

I'd use the log-command based on the tag-name with the peeled-magic as noted by Rüdiger:

        LogCommand log = new Git(repository).log();

        Ref peeledRef = repository.peel(ref);
        if(peeledRef.getPeeledObjectId() != null) {
            log.add(peeledRef.getPeeledObjectId());
        } else {
            log.add(ref.getObjectId());
        }

        Iterable<RevCommit> logs = log.call();
        for (RevCommit rev : logs) {
            System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */);
        }

See also my jgit-cookbook for some related examples.




回答2:


To get a list of tags you can either use Repository#getTags() or the ListTagCommand.

There are annotated and unannotated tags in Git. While unannotated tags directly point to the commit they were placed on, an annotated tag points to a git object that holds - among other meta data like a message - the commit-id.

The learning test below ilustrates this:

public class TagLearningTest {

  @Rule
  public final TemporaryFolder tempFolder = new TemporaryFolder();

  private Git git;

  @Test
  public void testUnannotatedTag() throws Exception {
    RevCommit commit = git.commit().setMessage( "Tag Me!" ).call();

    Ref tagRef = git.tag().setAnnotated( false ).setName( "Unannotated_Tag" ).call();

    assertEquals( commit.getId(), tagRef.getObjectId() );
    assertNull( git.getRepository().peel( tagRef ).getPeeledObjectId() );
  }

  @Test
  public void testAnnotatedTag() throws Exception {
    RevCommit commit = git.commit().setMessage( "Tag Me!" ).call();

    Ref tagRef = git.tag().setAnnotated( true ).setName( "Annotated_Tag" ).call();

    assertEquals( commit, git.getRepository().peel( tagRef ).getPeeledObjectId() );
    ObjectReader objectReader = git.getRepository().newObjectReader();
    ObjectLoader objectLoader = objectReader.open( tagRef.getObjectId() );
    RevTag tag = RevTag.parse( objectLoader.getBytes() );
    objectReader.release();
    assertEquals( commit.getId(), tag.getObject() );
  }

  @Before
  public void setUp() throws GitAPIException {
    git = Git.init().setDirectory( tempFolder.getRoot() ).call();
  }
}

In JGit, an annotated tag is represented by a RevTag that is stored under the id to which the tag ref points to.

To tell one form the other, you can peel the ref and then test if its getPeeledObjectId() returns non-null.

Ref peeledRef = git.getRepository().peel( tagRef );
boolean annotatedTag = peeledRef.getPeeledObjectId() != null;

The peeled object id is the one that points to the commit on which the annotated tag was created.



来源:https://stackoverflow.com/questions/27149949/list-commits-associated-with-a-given-tag-with-jgit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!