Remove trailing whitespace across EGit
[egit.git] / org.eclipse.egit.core / src / org / eclipse / egit / core / project / RepositoryFinder.java
blob4b4956ef9052fc92831058d66fddabd4f0bcbcc3
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 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *******************************************************************************/
11 package org.eclipse.egit.core.project;
13 import java.io.File;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Collection;
18 import org.eclipse.core.resources.IContainer;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.NullProgressMonitor;
25 import org.eclipse.core.runtime.SubProgressMonitor;
26 import org.eclipse.egit.core.CoreText;
28 /**
29 * Searches for existing Git repositories associated with a project's files.
30 * <p>
31 * This finder algorithm searches a project's contained files to see if any of
32 * them are located within the working directory of an existing Git repository.
33 * The finder searches through linked resources, as the EGit core is capable of
34 * dealing with linked directories spanning multiple repositories in the same
35 * project.
36 * </p>
37 * <p>
38 * The search algorithm is exhaustive, it will find all matching repositories.
39 * For the project itself as well as for each linked container within the
40 * project it scans down the local filesystem trees to locate any Git
41 * repositories which may be found there. It also scans up the local filesystem
42 * tree to locate any Git repository which may be outside of Eclipse's
43 * workspace-view of the world, but which contains the project or a linked
44 * resource within the project. In short, if there is a Git repository
45 * associated, it finds it.
46 * </p>
48 public class RepositoryFinder {
49 private final IProject proj;
51 private final Collection<RepositoryMapping> results = new ArrayList<RepositoryMapping>();
53 /**
54 * Create a new finder to locate Git repositories for a project.
56 * @param p
57 * the project this new finder should locate the existing Git
58 * repositories of.
60 public RepositoryFinder(final IProject p) {
61 proj = p;
64 /**
65 * Run the search algorithm.
67 * @param m
68 * a progress monitor to report feedback to; may be null.
69 * @return all found {@link RepositoryMapping} instances associated with the
70 * project supplied to this instance's constructor.
71 * @throws CoreException
72 * Eclipse was unable to access its workspace, and threw up on
73 * us. We're throwing it back at the caller.
75 public Collection<RepositoryMapping> find(IProgressMonitor m) throws CoreException {
76 if (m == null) {
77 m = new NullProgressMonitor();
79 find(m, proj);
80 return results;
83 private void find(final IProgressMonitor m, final IContainer c)
84 throws CoreException {
85 final IPath loc = c.getLocation();
87 m.beginTask("", 101);
88 m.subTask(CoreText.RepositoryFinder_finding);
89 try {
90 if (loc != null) {
91 final File fsLoc = loc.toFile();
92 final File ownCfg = configFor(fsLoc);
93 final IResource[] children;
95 if (ownCfg.isFile()) {
96 register(c, ownCfg.getParentFile());
98 if (c.isLinked() || c instanceof IProject) {
99 File p = fsLoc.getParentFile();
100 while (p != null) {
101 final File pCfg = configFor(p);
102 if (pCfg.isFile()) {
103 register(c, pCfg.getParentFile());
105 p = p.getParentFile();
108 m.worked(1);
110 children = c.members();
111 if (children != null && children.length > 0) {
112 final int scale = 100 / children.length;
113 for (int k = 0; k < children.length; k++) {
114 final IResource o = children[k];
115 if (o instanceof IContainer
116 && !o.getName().equals(".git")) {
117 find(new SubProgressMonitor(m, scale),
118 (IContainer) o);
119 } else {
120 m.worked(scale);
125 } finally {
126 m.done();
130 private File configFor(final File fsLoc) {
131 return new File(new File(fsLoc, ".git"), "config");
134 private void register(final IContainer c, final File gitdir) {
135 File f;
136 try {
137 f = gitdir.getCanonicalFile();
138 } catch (IOException ioe) {
139 f = gitdir.getAbsoluteFile();
141 results.add(new RepositoryMapping(c, f));