Remove System.out.println from RevWalkFilterTest
[jgit.git] / org.spearce.egit.core / src / org / spearce / egit / core / project / RepositoryMapping.java
blob029c56ac62c5a131d94d90d80853db100e5d9cd7
1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
4 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5 * Copyright (C) 2008, Shunichi Fuji <palglowr@gmail.com>
6 * Copyright (C) 2008, Google Inc.
8 * All rights reserved. This program and the accompanying materials
9 * are made available under the terms of the Eclipse Public License v1.0
10 * See LICENSE for the full license text, also available.
11 *******************************************************************************/
12 package org.spearce.egit.core.project;
14 import java.io.File;
15 import java.io.IOException;
16 import java.io.UnsupportedEncodingException;
17 import java.util.Properties;
19 import org.eclipse.core.resources.IContainer;
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.Path;
25 import org.eclipse.team.core.RepositoryProvider;
26 import org.spearce.egit.core.GitProvider;
27 import org.spearce.jgit.lib.Constants;
28 import org.spearce.jgit.lib.GitIndex;
29 import org.spearce.jgit.lib.Repository;
30 import org.spearce.jgit.lib.Tree;
31 import org.spearce.jgit.lib.TreeEntry;
32 import org.spearce.jgit.lib.GitIndex.Entry;
34 /**
35 * This class keeps track
37 public class RepositoryMapping {
38 static boolean isInitialKey(final String key) {
39 return key.endsWith(".gitdir");
42 private final String containerPath;
44 private final String gitdirPath;
46 private Repository db;
48 private String workdirPrefix;
50 private IContainer container;
52 /**
53 * Construct a {@link RepositoryMapping} for a previously connected project.
55 * @param p TODO
56 * @param initialKey TODO
58 public RepositoryMapping(final Properties p, final String initialKey) {
59 final int dot = initialKey.lastIndexOf('.');
61 containerPath = initialKey.substring(0, dot);
62 gitdirPath = p.getProperty(initialKey);
65 /**
66 * Construct a {@link RepositoryMapping} for previously
67 * unknown project.
69 * @param mappedContainer
70 * @param gitDir
72 public RepositoryMapping(final IContainer mappedContainer, final File gitDir) {
73 final IPath cLoc = mappedContainer.getLocation()
74 .removeTrailingSeparator();
75 final IPath gLoc = Path.fromOSString(gitDir.getAbsolutePath())
76 .removeTrailingSeparator();
77 final IPath gLocParent = gLoc.removeLastSegments(1);
78 String p;
79 int cnt;
81 container = mappedContainer;
82 containerPath = container.getProjectRelativePath().toPortableString();
84 if (cLoc.isPrefixOf(gLoc)) {
85 gitdirPath = gLoc.removeFirstSegments(
86 gLoc.matchingFirstSegments(cLoc)).toPortableString();
87 } else if (gLocParent.isPrefixOf(cLoc)) {
88 cnt = cLoc.segmentCount() - cLoc.matchingFirstSegments(gLocParent);
89 p = "";
90 while (cnt-- > 0) {
91 p += "../";
93 p += gLoc.segment(gLoc.segmentCount() - 1);
94 gitdirPath = p;
95 } else {
96 gitdirPath = gLoc.toPortableString();
100 IPath getContainerPath() {
101 return Path.fromPortableString(containerPath);
104 IPath getGitDirPath() {
105 return Path.fromPortableString(gitdirPath);
109 * @return the workdir file, i.e. where the files are checked out
111 public File getWorkDir() {
112 return getRepository().getWorkDir();
115 synchronized void clear() {
116 db = null;
117 workdirPrefix = null;
118 container = null;
122 * @return a reference to the repository object handled by this mapping
124 public synchronized Repository getRepository() {
125 return db;
128 synchronized void setRepository(final Repository r) {
129 db = r;
131 try {
132 workdirPrefix = getWorkDir().getCanonicalPath();
133 } catch (IOException err) {
134 workdirPrefix = getWorkDir().getAbsolutePath();
136 workdirPrefix = workdirPrefix.replace('\\', '/');
137 if (!workdirPrefix.endsWith("/"))
138 workdirPrefix += "/";
142 * @return the mapped container (currently project)
144 public synchronized IContainer getContainer() {
145 return container;
148 synchronized void setContainer(final IContainer c) {
149 container = c;
153 * Notify registered {@link RepositoryChangeListener}s of a change.
155 * @see GitProjectData#addRepositoryChangeListener(RepositoryChangeListener)
157 public void fireRepositoryChanged() {
158 GitProjectData.fireRepositoryChanged(this);
161 synchronized void store(final Properties p) {
162 p.setProperty(containerPath + ".gitdir", gitdirPath);
165 public String toString() {
166 return "RepositoryMapping[" + containerPath + " -> " + gitdirPath + "]";
170 * Check whether a resource has been changed relative to the checked out
171 * version. Content is assumed changed by this routine if the resource's
172 * modification time differs from what is recorded in the index, but the
173 * real content hasn't changed. The reason is performance.
175 * @param rsrc
176 * @return true if a resource differs in the workdir or index relative to
177 * HEAD
179 * @throws IOException
180 * @throws UnsupportedEncodingException
182 public boolean isResourceChanged(IResource rsrc) throws IOException, UnsupportedEncodingException {
183 Repository repository = getRepository();
184 GitIndex index = repository.getIndex();
185 String repoRelativePath = getRepoRelativePath(rsrc);
186 Tree headTree = repository.mapTree(Constants.HEAD);
187 TreeEntry blob = headTree!=null ? headTree.findBlobMember(repoRelativePath) : null;
188 Entry entry = index.getEntry(repoRelativePath);
189 if (rsrc instanceof IFile && entry == null && blob == null)
190 return false;
191 if (entry == null)
192 return true; // flags new resources as changes
193 if (blob == null)
194 return true; // added in index
195 boolean hashesDiffer = !entry.getObjectId().equals(blob.getId());
196 return hashesDiffer || entry.isModified(getWorkDir());
200 * @param rsrc
201 * @return the path relative to the Git repository, including base name.
203 public String getRepoRelativePath(final IResource rsrc) {
204 // We should only be called for resources that are actually
205 // in this repository, so we can safely assume that their
206 // path prefix matches workdirPrefix. Testing that here is
207 // rather expensive so we don't bother.
209 final int pfxLen = workdirPrefix.length();
210 final String p = rsrc.getLocation().toString();
211 final int pLen = p.length();
212 if (pLen > pfxLen)
213 return p.substring(pfxLen);
214 else if (p.length() == pfxLen - 1)
215 return "";
216 return null;
220 * Get the repository mapping for a resource
222 * @param resource
223 * @return the RepositoryMapping for this resource,
224 * or null for non GitProvider.
226 public static RepositoryMapping getMapping(final IResource resource) {
227 final IProject project = resource.getProject();
228 if (project == null)
229 return null;
231 final RepositoryProvider rp = RepositoryProvider.getProvider(project);
232 if (!(rp instanceof GitProvider))
233 return null;
235 if (((GitProvider)rp).getData() == null)
236 return null;
238 return ((GitProvider)rp).getData().getRepositoryMapping(resource);
242 * @return the name of the .git directory
244 public String getGitDir() {
245 return gitdirPath;