【发布时间】:2015-01-24 19:52:28
【问题描述】:
我需要创建一个历史文件,详细说明所有标签以及每个标签的所有提交。
我尝试在存储库对象上调用 getTags() 并使用这些对象 ID,但它们不是提交 ID。
我还尝试在存储库上使用getAllRefsByPeeledObjectId(),这确实会带回提交,但我无法将它们与标签相关联。
有什么想法吗?
【问题讨论】:
我需要创建一个历史文件,详细说明所有标签以及每个标签的所有提交。
我尝试在存储库对象上调用 getTags() 并使用这些对象 ID,但它们不是提交 ID。
我还尝试在存储库上使用getAllRefsByPeeledObjectId(),这确实会带回提交,但我无法将它们与标签相关联。
有什么想法吗?
【问题讨论】:
要获取标签列表,您可以使用Repository#getTags() 或ListTagCommand。
Git 中有带注释的标签和未注释的标签。虽然未注释的标签直接指向它们所在的提交,但带注释的标签指向一个 git 对象,该对象包含 - 以及其他元数据(如消息) - 提交 ID。
下面的学习测试说明了这一点:
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();
}
}
在 JGit 中,带注释的标签由 RevTag 表示,该标签存储在标签 ref 指向的 id 下。
要区分另一种形式,您可以剥离 ref,然后测试其getPeeledObjectId() 是否返回非空值。
Ref peeledRef = git.getRepository().peel( tagRef );
boolean annotatedTag = peeledRef.getPeeledObjectId() != null;
剥离的对象 id 是指向创建注释标记的提交的对象。
【讨论】:
列出所有标签:
List<Ref> call = new Git(repository).tagList().call();
for (Ref ref : call) {
System.out.println("Tag: " + ref + " " + ref.getName() + " " + ref.getObjectId().getName());
}
根据标签列出提交:
如 Rüdiger 所述,我将使用基于标签名称的 log-command 和剥离魔法:
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() */);
}
有关一些相关示例,另请参阅我的jgit-cookbook。
【讨论】: