1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.scm.provider.git.jgit.command.info;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.LinkedList;
24 import java.util.List;
25
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.maven.scm.CommandParameters;
28 import org.apache.maven.scm.ScmException;
29 import org.apache.maven.scm.ScmFileSet;
30 import org.apache.maven.scm.ScmResult;
31 import org.apache.maven.scm.command.AbstractCommand;
32 import org.apache.maven.scm.command.info.InfoItem;
33 import org.apache.maven.scm.command.info.InfoScmResult;
34 import org.apache.maven.scm.provider.ScmProviderRepository;
35 import org.apache.maven.scm.provider.git.command.GitCommand;
36 import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
37 import org.eclipse.jgit.api.Git;
38 import org.eclipse.jgit.lib.Constants;
39 import org.eclipse.jgit.lib.ObjectId;
40 import org.eclipse.jgit.lib.PersonIdent;
41 import org.eclipse.jgit.lib.Repository;
42 import org.eclipse.jgit.revwalk.RevCommit;
43 import org.eclipse.jgit.revwalk.RevSort;
44 import org.eclipse.jgit.revwalk.RevWalk;
45 import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
46 import org.eclipse.jgit.treewalk.filter.PathFilter;
47 import org.eclipse.jgit.treewalk.filter.TreeFilter;
48
49
50
51
52 public class JGitInfoCommand extends AbstractCommand implements GitCommand {
53 @Override
54 protected ScmResult executeCommand(
55 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
56 File basedir = fileSet.getBasedir();
57 Git git = null;
58 try {
59 git = JGitUtils.openRepo(basedir);
60 ObjectId objectId = git.getRepository().resolve(Constants.HEAD);
61 if (objectId == null) {
62 throw new ScmException("Cannot resolve HEAD in git repository at " + basedir);
63 }
64
65 List<InfoItem> infoItems = new LinkedList<>();
66 if (fileSet.getFileList().isEmpty()) {
67 RevCommit headCommit = git.getRepository().parseCommit(objectId);
68 infoItems.add(getInfoItem(headCommit, fileSet.getBasedir()));
69 } else {
70
71 for (File file : JGitUtils.getWorkingCopyRelativePaths(
72 git.getRepository().getWorkTree(), fileSet)) {
73 infoItems.add(getInfoItem(git.getRepository(), objectId, file));
74 }
75 }
76 return new InfoScmResult(infoItems, new ScmResult("JGit.resolve(HEAD)", "", objectId.toString(), true));
77 } catch (Exception e) {
78 throw new ScmException("JGit resolve failure!", e);
79 } finally {
80 JGitUtils.closeRepo(git);
81 }
82 }
83
84 protected InfoItem getInfoItem(Repository repository, ObjectId headObjectId, File file) throws IOException {
85 RevCommit commit = getMostRecentCommitForPath(repository, headObjectId, JGitUtils.toNormalizedFilePath(file));
86 return getInfoItem(commit, file);
87 }
88
89 protected InfoItem getInfoItem(RevCommit fileCommit, File file) {
90 InfoItem infoItem = new InfoItem();
91 infoItem.setPath(file.getPath());
92 infoItem.setRevision(StringUtils.trim(fileCommit.name()));
93 infoItem.setURL(file.toPath().toUri().toASCIIString());
94 PersonIdent authorIdent = fileCommit.getAuthorIdent();
95 infoItem.setLastChangedDateTime(authorIdent
96 .getWhen()
97 .toInstant()
98 .atZone(authorIdent.getTimeZone().toZoneId()));
99 infoItem.setLastChangedAuthor(authorIdent.getName() + " <" + authorIdent.getEmailAddress() + ">");
100 return infoItem;
101 }
102
103 private RevCommit getMostRecentCommitForPath(Repository repository, ObjectId headObjectId, String path)
104 throws IOException {
105 RevCommit latestCommit = null;
106 try (RevWalk revWalk = new RevWalk(repository)) {
107 RevCommit headCommit = revWalk.parseCommit(headObjectId);
108 revWalk.markStart(headCommit);
109 revWalk.sort(RevSort.COMMIT_TIME_DESC);
110 revWalk.setTreeFilter(AndTreeFilter.create(PathFilter.create(path), TreeFilter.ANY_DIFF));
111 latestCommit = revWalk.next();
112 }
113 return latestCommit;
114 }
115 }