Eclipseplugins
DiffOperation.java
1 package com.proalpha.pds.gitutils.common;
2 
3 import java.io.IOException;
4 import java.lang.reflect.InvocationTargetException;
5 import java.util.List;
6 
7 import org.eclipse.jgit.api.DiffCommand;
8 import org.eclipse.jgit.api.errors.GitAPIException;
9 import org.eclipse.jgit.diff.DiffEntry;
10 import org.eclipse.jgit.lib.ObjectId;
11 import org.eclipse.jgit.lib.ObjectReader;
12 import org.eclipse.jgit.lib.Repository;
13 import org.eclipse.jgit.revwalk.RevCommit;
14 import org.eclipse.jgit.revwalk.RevTree;
15 import org.eclipse.jgit.revwalk.RevWalk;
16 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
17 import org.eclipse.jgit.treewalk.CanonicalTreeParser;
18 import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21 
22 import com.proalpha.git.PaGit;
23 
24 public class DiffOperation extends CheckoutOperation {
25 
26  private DiffCommand cmd;
27  private String dbCommit;
28  private String artifactsCommit;
29  private String targetRefName;
30  private String newHead;
31  private List<DiffEntry> pdiDiffList;
32  private List<DiffEntry> stateInfoDiffList;
33  private boolean isAssembliesXmlChanged;
34 
35  public DiffOperation(Repository repository, String remote, String sourceRef, String targetRef,
36  boolean updateSourceRef, boolean updateTargetRef, String dbCommit, String artifactsCommit) {
37  super(repository, remote, sourceRef, targetRef, updateSourceRef, updateTargetRef);
38  this.dbCommit = dbCommit;
39  this.artifactsCommit = artifactsCommit;
40  this.isAssembliesXmlChanged = false;
41  }
42 
43  public DiffOperation(Repository repository, String remote, String sourceRef, String targetRef,
44  boolean updateSourceRef, boolean updateTargetRef, String dbCommit) {
45  super(repository, remote, sourceRef, targetRef, updateSourceRef, updateTargetRef);
46  this.dbCommit = dbCommit;
47  this.artifactsCommit = dbCommit;
48  this.isAssembliesXmlChanged = false;
49  }
50 
51  public DiffOperation(Repository repository, String targetRef) {
52  super(repository, targetRef);
53  }
54 
55  private final Logger logger = LoggerFactory.getLogger(DiffOperation.class);
56 
62  @Override
63  public void run() throws InvocationTargetException {
64 
65  if (logger.isInfoEnabled())
66  logger.info("Get diff between selected commits");
67 
68  try {
69 
70  if (isLocalBranch(this.targetRef)) {
71  targetRefName = this.targetRef;
72  if (this.updateTargetRef)
73  tryFetch(this.targetRef);
74  } else if (isServerBranch(this.targetRef)) {
75  targetRefName = "remotes/" + this.remote + "/" + this.targetRef;
76  if (this.updateTargetRef)
77  tryFetch(this.targetRef);
78  } else {
79  targetRefName = "remotes/" + this.remote + "/" + this.sourceRef;
80  if (this.updateSourceRef)
81  tryFetch(this.sourceRef);
82  }
83 
84  newHead = PaGit.getInstance().getGit().getRepository().findRef(targetRefName).getObjectId().getName();
85 
86  logger.info("New head is {}", newHead);
87 
88  this.pdiDiffList = executeCommand(this.dbCommit, targetRefName, ".pdi");
89  this.stateInfoDiffList = executeCommand(this.artifactsCommit, targetRefName, ".state_info");
90  this.isAssembliesXmlChanged = !executeCommand(this.artifactsCommit, targetRefName, "assemblies.xml").isEmpty();
91 
92  } catch (IOException e) {
93  // TODO Auto-generated catch block
94  logger.info(e.getMessage());
95  e.printStackTrace();
96  } catch (GitAPIException e) {
97  // TODO Auto-generated catch block
98  e.printStackTrace();
99  } finally {
100  PaGit.getInstance().close();
101  }
102 
103  }
104 
105  private List<DiffEntry> executeCommand(String commitId, String refName, String pathFilter)
106  throws GitAPIException, IOException {
107 
108  // A diff command needs two TreeIterators (old and new)
109  AbstractTreeIterator oldTreeParser = prepareTreeParserWithCommitId(repository, commitId);
110  AbstractTreeIterator newTreeParser = prepareTreeParserWithRef(repository, refName);
111 
112  // Prepare the command which gets called
113  cmd = PaGit.getInstance().getGit().diff().setOldTree(oldTreeParser).setNewTree(newTreeParser)
114  .setShowNameAndStatusOnly(true).setPathFilter(PathSuffixFilter.create(pathFilter));
115 
116  List<DiffEntry> diffList = cmd.call();
117 
118  // Debug output of results
119  if (logger.isDebugEnabled()) {
120  for (DiffEntry entry : diffList) {
121  logger.debug("Entry: {}", entry);
122  }
123  }
124  return diffList;
125  }
126 
127  private static AbstractTreeIterator prepareTreeParserWithRef(Repository repository, String ref) throws IOException {
128  ObjectId treeId = repository.resolve(ref + "^{tree}");
129  try (RevWalk walk = new RevWalk(repository)) {
130  RevTree tree = walk.parseTree(treeId);
131 
132  CanonicalTreeParser treeParser = new CanonicalTreeParser();
133  try (ObjectReader reader = repository.newObjectReader()) {
134  treeParser.reset(reader, tree.getId());
135  }
136 
137  walk.dispose();
138 
139  return treeParser;
140  }
141  }
142 
143  private static AbstractTreeIterator prepareTreeParserWithCommitId(Repository repository, String objectId)
144  throws IOException {
145  // from the commit we can build the tree which allows us to construct the
146  // TreeParser
147 
148  try (RevWalk walk = new RevWalk(repository)) {
149  RevCommit commit = walk.parseCommit(ObjectId.fromString(objectId));
150  RevTree tree = walk.parseTree(commit.getTree().getId());
151 
152  CanonicalTreeParser treeParser = new CanonicalTreeParser();
153  try (ObjectReader reader = repository.newObjectReader()) {
154  treeParser.reset(reader, tree.getId());
155  }
156 
157  walk.dispose();
158 
159  return treeParser;
160  }
161  }
162 
163  public String getDbCommit() {
164  return dbCommit;
165  }
166 
167  public String getArtifactsCommit() {
168  return artifactsCommit;
169  }
170 
171  public String getTargetRefName() {
172  return targetRefName;
173  }
174 
175  public String getNewHead() {
176  return newHead;
177  }
178 
179  public List<DiffEntry> getPdiDiffList() {
180  return pdiDiffList;
181  }
182 
183  public List<DiffEntry> getStateInfoDiffList() {
184  return stateInfoDiffList;
185  }
186 
187  public boolean isAssembliesXmlChanged() {
188  return isAssembliesXmlChanged;
189  }
190 
191 }