假设git存储库中有两个文件,path/to/file1.txt和path/to/file2.txt。首先提交file1.txt,然后提交file2.txt,因此它们属于具有不同sha1的提交。我想使用jgit检索与每个文件对应的sha1。这是我目前掌握的代码:
String localPath = "/path/to/repo";
Repository localRepo = new FileRepository(localPath + "/.git");
Ref headRef = localRepo.getRef("refs/heads/master");
RevWalk revWalk = new RevWalk(localRepo);
RevCommit headCommit = revWalk.parseCommit(headRef.getObjectId());
TreeWalk tw = new TreeWalk(localRepo);
tw.addTree(headCommit.getTree());
tw.setRecursive(true);
HashMap<String, String> fileShas = new HashMap<String, String>();
RevWalk commitFinder = new RevWalk(localRepo);
while (tw.next()) {
ArrayList<PathFilter> filters = new ArrayList<PathFilter>();
filters.add(PathFilter.create(tw.getPathString()));
commitFinder.reset();
RevCommit iterHead = commitFinder.lookupCommit(headRef.getObjectId());
commitFinder.markStart(iterHead);
commitFinder.setTreeFilter(AndTreeFilter.create(PathFilterGroup.create(filters), TreeFilter.ANY_DIFF));
commitFinder.setRevFilter(MaxCountRevFilter.create(1));
RevCommit commit = commitFinder.next();
fileShas.put(tw.getPathString(), commit.getId().getName());
}
不幸的是这不起作用。我得到了第一个文件的正确sha1,但没有得到第二个文件。看来
commitFinder.reset();
没有做好它的工作。如果我在每次迭代中创建一个新的RevWalk
,它可以工作,但速度非常慢。你知道为什么reset()
不起作用吗? 最佳答案
虽然这不能回答我的问题,但我把我的发现放在这里是为了更好的可读性。下面所示测试的getLatestModification
方法返回上次修改给定文件的提交的id。
尽管代码比原始代码片段短,但问题仍然是reset
显然不起作用。
public class RevWalkResetLearningTest {
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
private Repository repository;
@Test
public void testReset() throws Exception {
RevWalk revWalk = new RevWalk( repository );
RevCommit beerCommit = getLastModification( revWalk, "plugins/emoji/public/images/beer.png" );
// RevCommit discourseCommit = getLastModification( new RevWalk( repository ), "images/discourse.png" );
RevCommit discourseCommit = getLastModification( revWalk, "images/discourse.png" );
assertEquals( "8278fdb9ddbc61eea9f6e6045b705106678ce532", beerCommit.name() );
assertEquals( "50cd44df2dec27c0834be4a2975fe175c3fac64f", discourseCommit.name() );
}
private RevCommit getLastModification( RevWalk revWalk, String path ) throws IOException {
revWalk.reset();
revWalk.markStart( revWalk.parseCommit( repository.resolve( "refs/heads/master" ) ) );
revWalk.setTreeFilter( AndTreeFilter.create( PathFilter.create( path ), TreeFilter.ANY_DIFF ) );
return revWalk.next();
}
@Before
public void setUp() throws Exception {
// Git git = Git.cloneRepository().setURI( "https://github.com/discourse/discourse.git" ).setDirectory( tempFolder.getRoot() ).call();
// repository = git.getRepository();
repository = new FileRepositoryBuilder().setMustExist( true ).setGitDir( new File( "/path/to/discourse/.git" ) ).build();
}
@After
public void tearDown() {
repository.close();
}
}
测试失败,因为
discourseCommit
的提交id与beerCommit
相同。如果我更改代码,使对getLastModification
的每个调用都获得RevWalk
的新实例(请参阅注释行),则测试成功。我建议打开abug report或向jgitmailing list寻求帮助。
关于java - 为什么jGit的RevWalk.reset()方法行为异常?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24795001/