aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Sawicki2011-04-28 14:05:35 (EDT)
committerChris Aniszczyk2011-04-28 15:06:09 (EDT)
commit2e4b940d2c6e0bbd7bb2b413aad8f7a82ec93126 (patch)
tree3c17d2d3198e69cae6525185f323b52f3322d463
parent849357793250c23b6562189f4ccdc13689d98a54 (diff)
downloadegit-2e4b940d2c6e0bbd7bb2b413aad8f7a82ec93126.zip
egit-2e4b940d2c6e0bbd7bb2b413aad8f7a82ec93126.tar.gz
egit-2e4b940d2c6e0bbd7bb2b413aad8f7a82ec93126.tar.bz2
Add commit search query class.refs/changes/84/3284/2
This class performs a rev walk for the repositories added to a search and matches rev commits against the selected fields in that commit search. Bug: 341652 Change-Id: I2a66e81424f1698b61a85cefe06f3e837c336fed Signed-off-by: Kevin Sawicki <kevin@github.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java6
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java237
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties2
3 files changed, 245 insertions, 0 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
index 37ebc68..688feb2 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
@@ -3446,6 +3446,12 @@ public class UIText extends NLS {
public static String CommitFileDiffViewer_OpenWorkingTreeVersionInEditorMenuLabel;
/** */
+ public static String CommitSearchQuery_Label;
+
+ /** */
+ public static String CommitSearchQuery_TaskSearchCommits;
+
+ /** */
public static String CommitSearchResult_LabelPlural;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java
new file mode 100644
index 0000000..90b6ff1
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.search;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.search.internal.core.text.PatternConstructor;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.ISearchResult;
+
+/**
+ * Commit search query class that runs a {@link RevWalk} for all
+ * {@link Repository} objects included in the {@link CommitSearchSettings} and
+ * matches all {@link RevCommit} objects against the search settings.
+ */
+public class CommitSearchQuery implements ISearchQuery {
+
+ private abstract class SearchMatcher {
+
+ abstract boolean matches(Pattern pattern, RevCommit commit);
+
+ protected boolean matches(Pattern pattern, String input) {
+ return input != null && input.length() > 0
+ && pattern.matcher(input).find();
+ }
+
+ }
+
+ private class AuthorMatcher extends SearchMatcher {
+
+ public boolean matches(Pattern pattern, RevCommit commit) {
+ PersonIdent author = commit.getAuthorIdent();
+ if (author != null)
+ return matches(pattern, author.getName())
+ || matches(pattern, author.getEmailAddress());
+ else
+ return false;
+ }
+ }
+
+ private class CommitterMatcher extends SearchMatcher {
+
+ public boolean matches(Pattern pattern, RevCommit commit) {
+ PersonIdent committer = commit.getCommitterIdent();
+ if (committer != null)
+ return matches(pattern, committer.getName())
+ || matches(pattern, committer.getEmailAddress());
+ else
+ return false;
+ }
+ }
+
+ private class MessageMatcher extends SearchMatcher {
+
+ public boolean matches(Pattern pattern, RevCommit commit) {
+ return matches(pattern, commit.getFullMessage());
+ }
+ }
+
+ private class CommitNameMatcher extends SearchMatcher {
+
+ public boolean matches(Pattern pattern, RevCommit commit) {
+ return matches(pattern, commit.name());
+ }
+
+ }
+
+ private class TreeMatcher extends SearchMatcher {
+
+ public boolean matches(Pattern pattern, RevCommit commit) {
+ RevTree tree = commit.getTree();
+ return tree != null ? matches(pattern, tree.name()) : false;
+ }
+ }
+
+ private class ParentMatcher extends SearchMatcher {
+
+ public boolean matches(Pattern pattern, RevCommit commit) {
+ for (RevCommit parent : commit.getParents())
+ if (matches(pattern, parent.name()))
+ return true;
+ return false;
+ }
+
+ }
+
+ private CommitSearchResult result = new CommitSearchResult(this);
+
+ private CommitSearchSettings settings;
+
+ private List<SearchMatcher> matchers = new LinkedList<SearchMatcher>();
+
+ /**
+ * Create git search query
+ *
+ * @param settings
+ */
+ public CommitSearchQuery(CommitSearchSettings settings) {
+ this.settings = settings;
+
+ if (this.settings.isMatchAuthor())
+ matchers.add(new AuthorMatcher());
+ if (this.settings.isMatchCommitter())
+ matchers.add(new CommitterMatcher());
+ if (this.settings.isMatchMessage())
+ matchers.add(new MessageMatcher());
+ if (this.settings.isMatchCommit())
+ matchers.add(new CommitNameMatcher());
+ if (this.settings.isMatchTree())
+ matchers.add(new TreeMatcher());
+ if (this.settings.isMatchParents())
+ matchers.add(new ParentMatcher());
+ }
+
+ private Repository getRepository(String name) throws IOException {
+ Repository repository = null;
+ File path = new File(name);
+ if (path.exists())
+ repository = Activator.getDefault().getRepositoryCache()
+ .lookupRepository(path);
+ return repository;
+ }
+
+ /**
+ * @see org.eclipse.search.ui.ISearchQuery#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStatus run(IProgressMonitor monitor)
+ throws OperationCanceledException {
+ this.result.removeAll();
+
+ Pattern pattern = PatternConstructor.createPattern(
+ this.settings.getTextPattern(),
+ this.settings.isCaseSensitive(), this.settings.isRegExSearch());
+ List<String> paths = settings.getRepositories();
+ try {
+ for (String path : paths) {
+ if (monitor.isCanceled())
+ throw new OperationCanceledException();
+
+ Repository repo = getRepository(path);
+ if (repo == null)
+ continue;
+
+ monitor.setTaskName(MessageFormat.format(
+ UIText.CommitSearchQuery_TaskSearchCommits, repo
+ .getDirectory().getParentFile().getName()));
+ walkRepository(repo, pattern, monitor);
+ }
+ } catch (IOException e) {
+ org.eclipse.egit.ui.Activator.handleError(
+ "Error searching commits", e, true); //$NON-NLS-1$
+ }
+ return Status.OK_STATUS;
+ }
+
+ private void walkRepository(Repository repository, Pattern pattern,
+ IProgressMonitor monitor) throws IOException {
+ RevWalk walk = new RevWalk(repository);
+ try {
+ walk.setRetainBody(true);
+ RevCommit commit = walk.parseCommit(repository
+ .resolve(Constants.HEAD));
+ if (commit != null) {
+ walk.markStart(commit);
+ commit = walk.next();
+ while (commit != null) {
+ if (monitor.isCanceled())
+ throw new OperationCanceledException();
+ for (SearchMatcher matcher : this.matchers)
+ if (matcher.matches(pattern, commit)) {
+ result.addResult(new RepositoryCommit(repository,
+ commit));
+ break;
+ }
+ commit = walk.next();
+ }
+ }
+ } finally {
+ walk.dispose();
+ }
+ }
+
+ /**
+ * @see org.eclipse.search.ui.ISearchQuery#getLabel()
+ */
+ public String getLabel() {
+ return UIText.CommitSearchQuery_Label;
+ }
+
+ /**
+ * @see org.eclipse.search.ui.ISearchQuery#canRerun()
+ */
+ public boolean canRerun() {
+ return true;
+ }
+
+ /**
+ * @see org.eclipse.search.ui.ISearchQuery#canRunInBackground()
+ */
+ public boolean canRunInBackground() {
+ return true;
+ }
+
+ /**
+ * @see org.eclipse.search.ui.ISearchQuery#getSearchResult()
+ */
+ public ISearchResult getSearchResult() {
+ return this.result;
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
index 77a8543..b6c4007 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
@@ -1027,6 +1027,8 @@ CommitFileDiffViewer_SelectOneCommitMessage=Please select exactly one commit
CommitGraphTable_CommitId=Id
CommitGraphTable_Committer=Committer
CommitGraphTable_CompareWithEachOtherInTreeMenuLabel=Compare with each other in &Tree
+CommitSearchQuery_Label=Git Commit Search
+CommitSearchQuery_TaskSearchCommits=Searching commits in {0}
CommitSearchResult_LabelPlural=Git Commit Search - {0} matches
CommitSearchResult_LabelSingle=Git Commit Search - 1 match
CommitSelectionDialog_BuildingCommitListMessage=Building commit list