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
.util
.Properties
;
23 import org
.eclipse
.core
.resources
.IContainer
;
24 import org
.eclipse
.core
.runtime
.IPath
;
25 import org
.eclipse
.core
.runtime
.Path
;
26 import org
.eclipse
.core
.runtime
.jobs
.IJobChangeEvent
;
27 import org
.eclipse
.core
.runtime
.jobs
.JobChangeAdapter
;
28 import org
.spearce
.jgit
.errors
.MissingObjectException
;
29 import org
.spearce
.jgit
.lib
.Constants
;
30 import org
.spearce
.jgit
.lib
.MergedTree
;
31 import org
.spearce
.jgit
.lib
.RefLock
;
32 import org
.spearce
.jgit
.lib
.Repository
;
33 import org
.spearce
.jgit
.lib
.Tree
;
34 import org
.spearce
.jgit
.lib
.TreeEntry
;
36 public class RepositoryMapping
{
37 public static boolean isInitialKey(final String key
) {
38 return key
.endsWith(".gitdir");
41 private final String containerPath
;
43 private final String gitdirPath
;
45 private final String subset
;
47 private final String cacheref
;
49 private Repository db
;
51 private CheckpointJob currowj
;
53 private boolean runningowj
;
55 private IContainer container
;
57 private Tree cacheTree
;
59 private MergedTree activeDiff
;
61 public RepositoryMapping(final Properties p
, final String initialKey
) {
62 final int dot
= initialKey
.lastIndexOf('.');
65 containerPath
= initialKey
.substring(0, dot
);
66 gitdirPath
= p
.getProperty(initialKey
);
67 s
= p
.getProperty(containerPath
+ ".subset");
68 subset
= "".equals(s
) ?
null : s
;
69 cacheref
= p
.getProperty(containerPath
+ ".cacheref");
72 public RepositoryMapping(final IContainer mappedContainer
,
73 final File gitDir
, final String subsetRoot
) {
74 final IPath cLoc
= mappedContainer
.getLocation()
75 .removeTrailingSeparator();
76 final IPath gLoc
= Path
.fromOSString(gitDir
.getAbsolutePath())
77 .removeTrailingSeparator();
78 final IPath gLocParent
= gLoc
.removeLastSegments(1);
82 container
= mappedContainer
;
83 containerPath
= container
.getProjectRelativePath().toPortableString();
85 if (cLoc
.isPrefixOf(gLoc
)) {
86 gitdirPath
= gLoc
.removeFirstSegments(
87 gLoc
.matchingFirstSegments(cLoc
)).toPortableString();
88 } else if (gLocParent
.isPrefixOf(cLoc
)) {
89 cnt
= cLoc
.segmentCount() - cLoc
.matchingFirstSegments(gLocParent
);
94 p
+= gLoc
.segment(gLoc
.segmentCount() - 1);
97 gitdirPath
= gLoc
.toPortableString();
100 subset
= "".equals(subsetRoot
) ?
null : subsetRoot
;
103 + container
.getWorkspace().getRoot().getLocation()
104 .lastSegment() + "/";
105 IPath r
= container
.getFullPath();
106 for (int j
= 0; j
< r
.segmentCount(); j
++) {
114 public IPath
getContainerPath() {
115 return Path
.fromPortableString(containerPath
);
118 public IPath
getGitDirPath() {
119 return Path
.fromPortableString(gitdirPath
);
122 public String
getSubset() {
126 public synchronized void clear() {
134 public synchronized Repository
getRepository() {
138 public synchronized void setRepository(final Repository r
) {
147 public synchronized IContainer
getContainer() {
151 public synchronized void setContainer(final IContainer c
) {
155 public synchronized Tree
getCacheTree() {
159 public synchronized MergedTree
getActiveDiff() {
163 public synchronized void checkpointIfNecessary() {
165 currowj
.scheduleIfNecessary();
169 public synchronized void saveCache() throws IOException
{
170 final RefLock lock
= getRepository().lockRef(cacheref
);
172 lock
.write(cacheTree
.getId());
177 public synchronized void fullUpdate() throws IOException
{
178 cacheTree
= mapHEADTree();
180 if (container
.exists()) {
181 cacheTree
.accept(new UpdateTreeFromWorkspace(container
),
182 TreeEntry
.CONCURRENT_MODIFICATION
);
188 currowj
.scheduleIfNecessary();
191 public synchronized void recomputeMerge() throws IOException
{
192 Tree head
= mapHEADTree();
194 if (cacheTree
== null) {
195 cacheTree
= getRepository().mapTree(cacheref
);
197 if (cacheTree
== null) {
198 cacheTree
= new Tree(getRepository());
201 cacheTree
.accept(new EnqueueWriteTree(container
, currowj
),
202 TreeEntry
.MODIFIED_ONLY
);
204 activeDiff
= new MergedTree(new Tree
[] { head
, cacheTree
});
207 public synchronized Tree
mapHEADTree() throws IOException
,
208 MissingObjectException
{
209 Tree head
= getRepository().mapTree(Constants
.HEAD
);
211 if (getSubset() != null) {
212 final TreeEntry e
= head
.findMember(getSubset());
214 head
= e
instanceof Tree ?
(Tree
) e
: null;
218 head
= new Tree(getRepository());
223 public synchronized void store(final Properties p
) {
224 p
.setProperty(containerPath
+ ".gitdir", gitdirPath
);
225 p
.setProperty(containerPath
+ ".cacheref", cacheref
);
226 if (subset
!= null && !"".equals(subset
)) {
227 p
.setProperty(containerPath
+ ".subset", subset
);
231 public String
toString() {
232 return "RepositoryMapping[" + containerPath
+ " -> " + gitdirPath
233 + ", " + cacheref
+ "]";
236 private void initJob() {
237 currowj
= new CheckpointJob(this);
238 currowj
.addJobChangeListener(new JobChangeAdapter() {
239 public void running(final IJobChangeEvent event
) {
240 synchronized (RepositoryMapping
.this) {
246 public void done(final IJobChangeEvent event
) {
247 synchronized (RepositoryMapping
.this) {