0

for a project I need to checkout one file from a repository. But I need to go through all the commits. The idea is to track the changes inside this file. My idea was to create a inMemory repo and just copy the one file to disk. But I do not know how to iterate through the commits for this one file. It works fine, if I connect to a local git repo. But I won't have it on the server where this program will be running.

I followed this so far.

But when I try to do someting like

    LogCommand logCommand = git.log().addPath("componentModel.xml");
    List<ObjectId> commitIds = new ArrayList<>();
    for (RevCommit revCommit : logCommand.setMaxCount(20).call()) {
      commitIds.add(revCommit.getId());
      revCommit.disposeBody();
    }
    Collections.reverse(commitIds);

I get an error when reaching the logcommand.call()

org.eclipse.jgit.api.errors.NoHeadException: No HEAD exists and no explicit starting revision was specified

at org.eclipse.jgit.api.LogCommand.call(LogCommand.java:131)

This is my code so far

            DfsRepositoryDescription repoDesc = new DfsRepositoryDescription();
            InMemoryRepository repository = new InMemoryRepository(repoDesc);
            Git git = new Git(repository);
            git.fetch()
                    .setRemote(myRemoteGitRepo)
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider("myToken", ""))
                    .setRefSpecs(new RefSpec("+refs/heads/*:refs/heads/*"))
                    .call();
            repository.getObjectDatabase();
            
            LogCommand logCommand = git.log().addPath("componentModel.xml");
            List<ObjectId> commitIds = new ArrayList<>();
            for (RevCommit revCommit : logCommand.setMaxCount(20).call()) {
                commitIds.add(revCommit.getId());
                revCommit.disposeBody();
            }
            Collections.reverse(commitIds);

            for (ObjectId id : commitIds) {
               RevWalk revWalk = new RevWalk(repository)
               RevCommit commit = revWalk.parseCommit(id);
               RevTree tree = commit.getTree();
                    
               TreeWalk treeWalk = new TreeWalk(repository)
               treeWalk.addTree(tree);
               treeWalk.setRecursive(true);
               treeWalk.setFilter(PathFilter.create("componentModel.xml"));
               if (!treeWalk.next()) {
                 throw new IllegalStateException("Did not find expected file componentModel.xml");
               }
               ObjectId objectId = treeWalk.getObjectId(0);
               ObjectLoader loader = repository.open(objectId);
               FileOutputStream fileOutputStream = new FileOutputStream(path + "componentModel.xml", false);
               loader.copyTo(fileOutputStream);
               fileOutputStream.flush();
               fileOutputStream.close();
               transformXML(path, commit.getId().toString(), Date.from(Instant.ofEpochSecond(commit.getCommitTime())), extractJiraTicketNumber(commit.getFullMessage()));
            }

Thanks for any help on this!

Cliff Pereira
  • 403
  • 4
  • 14
  • What error do you get? Please edit your question to include the stacktrace. – Rüdiger Herrmann Jun 20 '20 at 08:20
  • Hi Rüdiger, thanks for your quick reply. I updated the question with the according error – Cliff Pereira Jun 22 '20 at 08:48
  • @RüdigerHerrmann any ideas? Hoped you could help me. Vielen Dank :-) – Cliff Pereira Jun 23 '20 at 12:51
  • 1
    To my understanding, in-memory repositories were meant for testing and experiments only. If you plan to use this in production, I'd rather drop the approach. Otherwise, did you debug-step through the relevant code to see why there is no HEAD? Perhaps you'd need to explicitly create a HEAD ref or specify the exact range in terms of commit IDs that you want to see. – Rüdiger Herrmann Jun 23 '20 at 15:16
  • 1
    You may also want to inspect the `FetchResult` returned by `git.fetch()` to see which refs were actually fetched. That may also allow you to work around the 'HEAD not found' if you find a suitable commit ID that you can set as the starting point for the log command. – Rüdiger Herrmann Jun 24 '20 at 08:54
  • thanks! I'll try that. But if I need to clone the repo anyway, I could also go with the usual approach. Seems to work with a "normal" repo. – Cliff Pereira Jun 24 '20 at 16:20

0 Answers0