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
;
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
;
29 * Searches for existing Git repositories associated with a project's files.
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
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.
48 public class RepositoryFinder
{
49 private final IProject proj
;
51 private final Collection
<RepositoryMapping
> results
= new ArrayList
<RepositoryMapping
>();
54 * Create a new finder to locate Git repositories for a project.
57 * the project this new finder should locate the existing Git
60 public RepositoryFinder(final IProject p
) {
65 * Run the search algorithm.
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
{
77 m
= new NullProgressMonitor();
83 private void find(final IProgressMonitor m
, final IContainer c
)
84 throws CoreException
{
85 final IPath loc
= c
.getLocation();
88 m
.subTask(CoreText
.RepositoryFinder_finding
);
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();
101 final File pCfg
= configFor(p
);
103 register(c
, pCfg
.getParentFile());
105 p
= p
.getParentFile();
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
),
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
) {
137 f
= gitdir
.getCanonicalFile();
138 } catch (IOException ioe
) {
139 f
= gitdir
.getAbsoluteFile();
141 results
.add(new RepositoryMapping(c
, f
));