aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Conley2013-08-29 14:14:07 (EDT)
committerBogdan Gheorghe2013-08-29 16:54:08 (EDT)
commit84867ac5f1535fe0a3ee859eef7ee50cbb29c782 (patch)
tree07d0cdb07de08080a60a59f6b71c06c989a4940b
parent7481e2461528efdbe509baea497fe25c3cdd1de4 (diff)
downloadorg.eclipse.orion.server-84867ac5f1535fe0a3ee859eef7ee50cbb29c782.zip
org.eclipse.orion.server-84867ac5f1535fe0a3ee859eef7ee50cbb29c782.tar.gz
org.eclipse.orion.server-84867ac5f1535fe0a3ee859eef7ee50cbb29c782.tar.bz2
Bug 414094 - Improve Git Blame implementationv20130829-2054
Signed-off-by: Chris Conley <chrisconley15@gmail.com>
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/objects/Blame.java133
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitBlameHandlerV1.java90
2 files changed, 144 insertions, 79 deletions
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/objects/Blame.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/objects/Blame.java
index 2bb3563..70f780e 100644
--- a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/objects/Blame.java
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/objects/Blame.java
@@ -15,12 +15,13 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.*;
+import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.orion.internal.server.servlets.ProtocolConstants;
import org.eclipse.orion.server.core.resources.*;
import org.eclipse.orion.server.core.resources.annotations.PropertyDescription;
import org.eclipse.orion.server.core.resources.annotations.ResourceDescription;
+import org.eclipse.orion.server.core.users.UserUtilities;
import org.eclipse.orion.server.git.BaseToCommitConverter;
import org.eclipse.orion.server.git.GitConstants;
import org.json.*;
@@ -34,11 +35,13 @@ public class Blame extends GitObject {
private List<String> lines = new ArrayList<String>();
+ private List<RevCommit> commits = new ArrayList<RevCommit>();
+
private String filePath = null;
private ObjectId startCommit = null;
- protected Serializer<JSONObject> jsonSerializer = new JSONSerializer();
+ protected JSONSerializer jsonSerializer = new JSONSerializer();
private URI blameLocation = null;
@@ -78,6 +81,24 @@ public class Blame extends GitObject {
}
/**
+ * Add RevCommit to needed commits
+ * @param commit
+ */
+ public void addCommit(RevCommit commit) {
+ this.commits.add(commit);
+ }
+
+ /**
+ * Check is commit is in the list
+ *
+ * @param commit
+ * @return boolean if exists
+ */
+ public boolean commitExists(RevCommit commit) {
+ return this.commits.contains(commit);
+ }
+
+ /**
* Get the file path for the blame object
*
* @return file path of blame object
@@ -133,28 +154,67 @@ public class Blame extends GitObject {
@PropertyDescription(name = ProtocolConstants.KEY_CHILDREN)
private JSONArray getBlameJSON() throws URISyntaxException, JSONException, IOException {
- JSONArray LinesJSON = new JSONArray();
- if (lines.size() > 0) {
-
+ if (lines.size() > 0 && commits.size() > 0) {
+ ArrayList<JSONArray> commitRanges = new ArrayList<JSONArray>();
JSONObject tempObj = null;
- String tempPath = null;
- for (int i = 0; i < lines.size(); i++) {
- String line = lines.get(i);
- if (!line.equalsIgnoreCase(tempPath)) {
- tempPath = line;
- if (i > 0) {
- tempObj.put(GitConstants.KEY_END_RANGE, i);
- LinesJSON.put(tempObj);
+ String lineId = null;
+ String currentCommitId = null;
+ for (int i = 0; i < commits.size(); i++) {
+ commitRanges.add(new JSONArray());
+ }
+ try {
+ for (int i = 0; i < lines.size(); i++) {
+ lineId = lines.get(i);
+ if (!lineId.equals(currentCommitId)) {
+ if (i > 0) {
+ tempObj.put(GitConstants.KEY_END_RANGE, i);
+ for (int j = 0; j < commits.size(); j++) {
+ if (commits.get(j).getId().getName().equals(currentCommitId)) {
+ commitRanges.get(j).put(tempObj);
+ break;
+ }
+ }
+
+ }
+ tempObj = new JSONObject();
+ tempObj.put(GitConstants.KEY_START_RANGE, i + 1);
+ currentCommitId = lineId;
}
- tempObj = new JSONObject();
- tempObj.put(GitConstants.KEY_START_RANGE, i + 1);
- URI commit = BaseToCommitConverter.getCommitLocation(cloneLocation, line, BaseToCommitConverter.REMOVE_FIRST_2);
- tempObj.put(GitConstants.KEY_COMMIT, commit);
}
+ tempObj.put(GitConstants.KEY_END_RANGE, lines.size());
+ for (int j = 0; j < commits.size(); j++) {
+ if (commits.get(j).getId().getName().equals(lineId)) {
+ commitRanges.get(j).put(tempObj);
+ break;
+ }
+ }
+ } catch (NullPointerException e) {
+
}
- tempObj.put(GitConstants.KEY_END_RANGE, lines.size());
- LinesJSON.put(tempObj);
- return LinesJSON;
+ JSONArray returnJSON = new JSONArray();
+ RevCommit tempCommit;
+ PersonIdent person;
+ for (int i = 0; i < commitRanges.size(); i++) {
+ tempObj = new JSONObject();
+ tempCommit = commits.get(i);
+ person = tempCommit.getAuthorIdent();
+ URI commitURI = BaseToCommitConverter.getCommitLocation(cloneLocation, tempCommit.getId().getName(), BaseToCommitConverter.REMOVE_FIRST_2);
+ tempObj = new JSONObject();
+ tempObj.put(GitConstants.KEY_COMMIT_TIME, (long) tempCommit.getCommitTime() * 1000);
+ tempObj.put(GitConstants.KEY_AUTHOR_EMAIL, person.getEmailAddress());
+ tempObj.put(GitConstants.KEY_AUTHOR_NAME, person.getName());
+ tempObj.put(GitConstants.KEY_AUTHOR_IMAGE, UserUtilities.getImageLink(person.getEmailAddress()));
+ person = tempCommit.getCommitterIdent();
+ tempObj.put(GitConstants.KEY_COMMITTER_EMAIL, person.getEmailAddress());
+ tempObj.put(GitConstants.KEY_COMMITTER_NAME, person.getName());
+ tempObj.put(GitConstants.KEY_COMMIT, commitURI);
+ tempObj.put(ProtocolConstants.KEY_CHILDREN, commitRanges.get(i));
+ tempObj.put(GitConstants.KEY_COMMIT_MESSAGE, tempCommit.getFullMessage());
+ tempObj.put(ProtocolConstants.KEY_NAME, tempCommit.getId().getName());
+ returnJSON.put(tempObj);
+ }
+ return returnJSON;
+
}
return null;
}
@@ -170,15 +230,28 @@ public class Blame extends GitObject {
* {
* {
* "CommitLocation":"/gitapi/commit/2b3a36c1b2f0064216a871740bd6906b6af7434a/file/C/",
- * "Start": 0,
- * "End": 7
- * },
- * {
- * "CommitLocation":"/gitapi/commit/fb774ffe5b1bbfbe80ac9afb5263901afdc12874/file/C/",
- * "Start": 8,
- * "End": 13
- * {
- * }
+ * "Name":"2b3a36c1b2f0064216a871740bd6906b6af7434a",
+ * "Time":1234567890,
+ * "AuthorName": Author Name,
+ * "AuthorEmail": Author Email,
+ * "AuthorImage": Gravatar URL,
+ * "Message": Commit Message,
+ * "Children":{
+ * {
+ * "Start":0,
+ * "End":5
+ * },
+ * {
+ * "Start":6,
+ * "End":8
+ * },
+ * ...
+ * ...
+ * }
+ * },
+ * ...
+ * ...
+ * }
*
*/
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitBlameHandlerV1.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitBlameHandlerV1.java
index 199ff2d..3a04011 100644
--- a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitBlameHandlerV1.java
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitBlameHandlerV1.java
@@ -16,6 +16,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
import org.eclipse.jgit.api.BlameCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.blame.BlameResult;
@@ -24,11 +25,11 @@ import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.orion.internal.server.servlets.ServletResourceHandler;
+import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.orion.server.git.BaseToCloneConverter;
-import org.eclipse.orion.server.git.GitConstants;
import org.eclipse.orion.server.git.objects.Blame;
import org.eclipse.orion.server.servlets.OrionServlet;
-import org.json.JSONObject;
+import org.eclipse.osgi.util.NLS;
public class GitBlameHandlerV1 extends AbstractGitHandler {
@@ -38,68 +39,40 @@ public class GitBlameHandlerV1 extends AbstractGitHandler {
@Override
protected boolean handleGet(RequestInfo requestInfo) throws ServletException {
- try {
+ HttpServletRequest request = requestInfo.request;
+ HttpServletResponse response = requestInfo.response;
- HttpServletRequest request = requestInfo.request;
- HttpServletResponse response = requestInfo.response;
+ try {
URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.BLAME);
- String path = requestInfo.relativePath;
- Blame blame = new Blame(cloneLocation, requestInfo.db);
-
- if (path.length() != 0) {
- // check that path isnt for a folder
- String file = path.substring(path.length() - 1);
- if (!file.endsWith("/") && !file.endsWith("\"")) {
- blame.setFilePath(path);
- blame.setBlameLocation(getURI(request));
- }
+ Path Filepath = new Path(requestInfo.filePath.toString());
+ if (Filepath.hasTrailingSeparator()) {
+ String msg = NLS.bind("Cannot get blame Information on a folder: {0}", requestInfo.filePath.toString());
+ return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
}
- doBlame(blame, requestInfo.db);
- OrionServlet.writeJSONResponse(request, response, blame.toJSON());
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- @Override
- protected boolean handlePost(RequestInfo requestInfo) throws ServletException {
- try {
-
- HttpServletRequest request = requestInfo.request;
- HttpServletResponse response = requestInfo.response;
-
- JSONObject obj = requestInfo.getJSONRequest();
- String commitString = obj.getString(GitConstants.KEY_COMMIT);
- ObjectId id = ObjectId.fromString(commitString);
-
- URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.BLAME);
-
- String path = requestInfo.relativePath;
Blame blame = new Blame(cloneLocation, requestInfo.db);
- if (path.length() != 0) {
- // check that path isnt for a folder
- String file = path.substring(path.length() - 1);
- if (!file.endsWith("/") && !file.endsWith("\"")) {
- blame.setFilePath(path);
- blame.setBlameLocation(getURI(request));
- }
+ String gitSegment = requestInfo.gitSegment;
+ if (!gitSegment.equalsIgnoreCase("HEAD") && !gitSegment.equalsIgnoreCase("master")) {
+ ObjectId id = ObjectId.fromString(requestInfo.gitSegment);
+ blame.setStartCommit(id);
}
- blame.setStartCommit(id);
+ String path = requestInfo.relativePath;
+ blame.setFilePath(path);
+ blame.setBlameLocation(getURI(request));
doBlame(blame, requestInfo.db);
OrionServlet.writeJSONResponse(request, response, blame.toJSON());
return true;
} catch (Exception e) {
- return false;
+ return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error generating blame response", e));
}
}
public void doBlame(Blame blame, Repository db) throws GitAPIException, IOException {
+
String filePath = blame.getFilePath();
if (db != null && filePath != null) {
@@ -121,11 +94,30 @@ public class GitBlameHandlerV1 extends AbstractGitHandler {
}
if (result != null) {
blame.clearLines();
- RevCommit commitPath;
+ RevCommit commit;
+ RevCommit prevCommit = null;
String path;
+ String prevPath = null;
for (int i = 0; i < result.getResultContents().size(); i++) {
- commitPath = result.getSourceCommit(i);
- path = commitPath.getId().getName();
+ try {
+ commit = result.getSourceCommit(i);
+ prevCommit = commit;
+ } catch (NullPointerException e) {
+ commit = prevCommit;
+ }
+
+ if (!blame.commitExists(commit)) {
+ if (commit != null) {
+ blame.addCommit(commit);
+ }
+ }
+
+ try {
+ path = commit.getId().getName();
+ prevPath = path;
+ } catch (NullPointerException e) {
+ path = prevPath;
+ }
blame.addLine(path);
}
}