Remove System.out.println from RevWalkFilterTest
[jgit.git] / org.spearce.egit.core / src / org / spearce / egit / core / project / RepositoryFinder.java
blob2b4b16fa80634006f50cc0680dd1c57e7e12fb27
1 /*******************************************************************************
2 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Google Inc.
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * See LICENSE for the full license text, also available.
9 *******************************************************************************/
10 package org.spearce.egit.core.project;
12 import java.io.File;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Collection;
17 import org.eclipse.core.resources.IContainer;
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.NullProgressMonitor;
24 import org.eclipse.core.runtime.SubProgressMonitor;
25 import org.spearce.egit.core.CoreText;
27 /**
28 * Searches for existing Git repositories associated with a project's files.
29 * <p>
30 * This finder algorithm searches a project's contained files to see if any of
31 * them are located within the working directory of an existing Git repository.
32 * The finder searches through linked resources, as the EGit core is capable of
33 * dealing with linked directories spanning multiple repositories in the same
34 * project.
35 * </p>
36 * <p>
37 * The search algorithm is exhaustive, it will find all matching repositories.
38 * For the project itself as well as for each linked container within the
39 * project it scans down the local filesystem trees to locate any Git
40 * repositories which may be found there. It also scans up the local filesystem
41 * tree to locate any Git repository which may be outside of Eclipse's
42 * workspace-view of the world, but which contains the project or a linked
43 * resource within the project. In short, if there is a Git repository
44 * associated, it finds it.
45 * </p>
47 public class RepositoryFinder {
48 private final IProject proj;
50 private final Collection<RepositoryMapping> results = new ArrayList<RepositoryMapping>();
52 /**
53 * Create a new finder to locate Git repositories for a project.
55 * @param p
56 * the project this new finder should locate the existing Git
57 * repositories of.
59 public RepositoryFinder(final IProject p) {
60 proj = p;
63 /**
64 * Run the search algorithm.
66 * @param m
67 * a progress monitor to report feedback to; may be null.
68 * @return all found {@link RepositoryMapping} instances associated with the
69 * project supplied to this instance's constructor.
70 * @throws CoreException
71 * Eclipse was unable to access its workspace, and threw up on
72 * us. We're throwing it back at the caller.
74 public Collection<RepositoryMapping> find(IProgressMonitor m) throws CoreException {
75 if (m == null) {
76 m = new NullProgressMonitor();
78 find(m, proj);
79 return results;
82 private void find(final IProgressMonitor m, final IContainer c)
83 throws CoreException {
84 final IPath loc = c.getLocation();
86 m.beginTask("", 101);
87 m.subTask(CoreText.RepositoryFinder_finding);
88 try {
89 if (loc != null) {
90 final File fsLoc = loc.toFile();
91 final File ownCfg = configFor(fsLoc);
92 final IResource[] children;
94 if (ownCfg.isFile()) {
95 register(c, ownCfg.getParentFile());
96 } else if (c.isLinked() || c instanceof IProject) {
97 File p = fsLoc.getParentFile();
98 while (p != null) {
99 final File pCfg = configFor(p);
100 if (pCfg.isFile()) {
101 register(c, pCfg.getParentFile());
102 break;
104 p = p.getParentFile();
107 m.worked(1);
109 children = c.members();
110 if (children != null && children.length > 0) {
111 final int scale = 100 / children.length;
112 for (int k = 0; k < children.length; k++) {
113 final IResource o = children[k];
114 if (o instanceof IContainer
115 && !o.getName().equals(".git")) {
116 find(new SubProgressMonitor(m, scale),
117 (IContainer) o);
118 } else {
119 m.worked(scale);
124 } finally {
125 m.done();
129 private File configFor(final File fsLoc) {
130 return new File(new File(fsLoc, ".git"), "config");
133 private void register(final IContainer c, final File gitdir) {
134 File f;
135 try {
136 f = gitdir.getCanonicalFile();
137 } catch (IOException ioe) {
138 f = gitdir.getAbsoluteFile();
140 results.add(new RepositoryMapping(c, f));