2 * Copyright (C) 2006 Shawn Pearce <spearce@spearce.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License, version 2.1, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org
.spearce
.egit
.core
.project
;
20 import java
.io
.IOException
;
21 import java
.io
.UnsupportedEncodingException
;
22 import java
.util
.Properties
;
24 import org
.eclipse
.core
.resources
.IContainer
;
25 import org
.eclipse
.core
.resources
.IFile
;
26 import org
.eclipse
.core
.resources
.IResource
;
27 import org
.eclipse
.core
.runtime
.IPath
;
28 import org
.eclipse
.core
.runtime
.Path
;
29 import org
.eclipse
.core
.runtime
.jobs
.IJobChangeEvent
;
30 import org
.eclipse
.core
.runtime
.jobs
.JobChangeAdapter
;
31 import org
.spearce
.jgit
.errors
.MissingObjectException
;
32 import org
.spearce
.jgit
.lib
.Constants
;
33 import org
.spearce
.jgit
.lib
.GitIndex
;
34 import org
.spearce
.jgit
.lib
.Repository
;
35 import org
.spearce
.jgit
.lib
.Tree
;
36 import org
.spearce
.jgit
.lib
.TreeEntry
;
37 import org
.spearce
.jgit
.lib
.GitIndex
.Entry
;
39 public class RepositoryMapping
{
40 public static boolean isInitialKey(final String key
) {
41 return key
.endsWith(".gitdir");
44 private final String containerPath
;
46 private final String gitdirPath
;
48 private final String subset
;
50 private Repository db
;
52 private CheckpointJob currowj
;
54 private boolean runningowj
;
56 private IContainer container
;
58 public RepositoryMapping(final Properties p
, final String initialKey
) {
59 final int dot
= initialKey
.lastIndexOf('.');
62 containerPath
= initialKey
.substring(0, dot
);
63 gitdirPath
= p
.getProperty(initialKey
);
64 s
= p
.getProperty(containerPath
+ ".subset");
65 subset
= "".equals(s
) ?
null : s
;
68 public RepositoryMapping(final IContainer mappedContainer
,
69 final File gitDir
, final String subsetRoot
) {
70 final IPath cLoc
= mappedContainer
.getLocation()
71 .removeTrailingSeparator();
72 final IPath gLoc
= Path
.fromOSString(gitDir
.getAbsolutePath())
73 .removeTrailingSeparator();
74 final IPath gLocParent
= gLoc
.removeLastSegments(1);
78 container
= mappedContainer
;
79 containerPath
= container
.getProjectRelativePath().toPortableString();
81 if (cLoc
.isPrefixOf(gLoc
)) {
82 gitdirPath
= gLoc
.removeFirstSegments(
83 gLoc
.matchingFirstSegments(cLoc
)).toPortableString();
84 } else if (gLocParent
.isPrefixOf(cLoc
)) {
85 cnt
= cLoc
.segmentCount() - cLoc
.matchingFirstSegments(gLocParent
);
90 p
+= gLoc
.segment(gLoc
.segmentCount() - 1);
93 gitdirPath
= gLoc
.toPortableString();
96 subset
= "".equals(subsetRoot
) ?
null : subsetRoot
;
99 + container
.getWorkspace().getRoot().getLocation()
100 .lastSegment() + "/";
101 IPath r
= container
.getFullPath();
102 for (int j
= 0; j
< r
.segmentCount(); j
++) {
109 public IPath
getContainerPath() {
110 return Path
.fromPortableString(containerPath
);
113 public IPath
getGitDirPath() {
114 return Path
.fromPortableString(gitdirPath
);
117 public String
getSubset() {
121 public File
getWorkDir() {
122 // assert containerPath.endsWith("/" + subset);
123 // return Path.fromPortableString(
124 // containerPath.substring(containerPath.length() - 1
125 // - subset.length())).toFile();
126 return getRepository().getDirectory().getParentFile();
129 public synchronized void clear() {
135 public synchronized Repository
getRepository() {
139 public synchronized void setRepository(final Repository r
) {
146 public synchronized IContainer
getContainer() {
150 public synchronized void setContainer(final IContainer c
) {
154 public synchronized void checkpointIfNecessary() {
156 currowj
.scheduleIfNecessary();
160 public synchronized void fullUpdate() {
162 currowj
.scheduleIfNecessary();
165 public synchronized void recomputeMerge() {
166 GitProjectData
.fireRepositoryChanged(this);
169 public synchronized Tree
mapHEADTree() throws IOException
,
170 MissingObjectException
{
171 Tree head
= getRepository().mapTree(Constants
.HEAD
);
173 if (getSubset() != null) {
174 final TreeEntry e
= head
.findTreeMember(getSubset());
176 head
= e
instanceof Tree ?
(Tree
) e
: null;
180 head
= new Tree(getRepository());
185 public synchronized void store(final Properties p
) {
186 p
.setProperty(containerPath
+ ".gitdir", gitdirPath
);
187 if (subset
!= null && !"".equals(subset
)) {
188 p
.setProperty(containerPath
+ ".subset", subset
);
192 public String
toString() {
193 return "RepositoryMapping[" + containerPath
+ " -> " + gitdirPath
+ "]";
196 @SuppressWarnings("synthetic-access")
197 private void initJob() {
198 currowj
= new CheckpointJob(this);
199 currowj
.addJobChangeListener(new JobChangeAdapter() {
200 public void running(final IJobChangeEvent event
) {
201 synchronized (RepositoryMapping
.this) {
207 public void done(final IJobChangeEvent event
) {
208 synchronized (RepositoryMapping
.this) {
215 public boolean isResourceChanged(IResource rsrc
) throws IOException
, UnsupportedEncodingException
{
216 Repository repository
= getRepository();
217 GitIndex index
= repository
.getIndex();
218 String repoRelativePath
= getRepoRelativePath(rsrc
);
219 Tree headTree
= repository
.mapTree("HEAD");
220 TreeEntry blob
= headTree
.findBlobMember(repoRelativePath
);
221 Entry entry
= index
.getEntry(repoRelativePath
);
222 if (rsrc
instanceof IFile
&& entry
== null && blob
== null)
225 return true; // flags new resources as changes
227 return true; // added in index
228 boolean hashesDiffer
= !entry
.getObjectId().equals(blob
.getId());
229 // System.out.println("HashesDiffer: " + rsrc);
230 return hashesDiffer
|| entry
.isModified(getWorkDir());
233 public String
getRepoRelativePath(IResource rsrc
) {
234 String prefix
= getSubset();
235 String projectRelativePath
= rsrc
.getProjectRelativePath().toString();
236 String repoRelativePath
;
238 repoRelativePath
= prefix
+ "/" + projectRelativePath
;
240 repoRelativePath
= projectRelativePath
;
241 return repoRelativePath
;