1 /*******************************************************************************
2 * Copyright (C) 2015, Obeo.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org
.eclipse
.egit
.core
.internal
.merge
;
11 import java
.io
.IOException
;
12 import java
.util
.LinkedHashSet
;
15 import org
.eclipse
.core
.resources
.IResource
;
16 import org
.eclipse
.core
.runtime
.IPath
;
17 import org
.eclipse
.core
.runtime
.Path
;
18 import org
.eclipse
.egit
.core
.internal
.storage
.TreeParserResourceVariant
;
19 import org
.eclipse
.egit
.core
.internal
.util
.ResourceUtil
;
20 import org
.eclipse
.jgit
.lib
.Repository
;
21 import org
.eclipse
.jgit
.treewalk
.AbstractTreeIterator
;
22 import org
.eclipse
.jgit
.treewalk
.CanonicalTreeParser
;
23 import org
.eclipse
.jgit
.treewalk
.TreeWalk
;
24 import org
.eclipse
.team
.core
.variants
.IResourceVariantTree
;
27 * This will populate its three {@link IResourceVariantTree} by walking over a
28 * tree walk and caching the IResources it spans.
30 * Files that are not located within the workspace will be ignored and thus will
31 * not be accessible through the trees created by this provider.
34 public class TreeWalkResourceVariantTreeProvider
implements
35 GitResourceVariantTreeProvider
{
36 private final IResourceVariantTree baseTree
;
38 private final IResourceVariantTree oursTree
;
40 private final IResourceVariantTree theirsTree
;
42 private final Set
<IResource
> roots
;
44 private final Set
<IResource
> knownResources
;
47 * Constructs the resource variant trees by iterating over the given tree
48 * walk. This TreeWalk must contain at least three trees corresponding to
49 * the three "sides" we need.
51 * The tree walk will be reset to its initial state when we are done with
56 * The repository this tree walk has been created for.
58 * The tree walk to iterate over.
60 * Index of the ancestor tree in the given TreeWalk (value
61 * returned by {@link TreeWalk#addTree(AbstractTreeIterator)})
63 * Index of our tree in the given TreeWalk (value returned by
64 * {@link TreeWalk#addTree(AbstractTreeIterator)})
66 * Index of their tree in the given TreeWalk (value returned by
67 * {@link TreeWalk#addTree(AbstractTreeIterator)})
69 * if we somehow cannot iterate over the treewalk.
71 public TreeWalkResourceVariantTreeProvider(Repository repository
,
72 TreeWalk treeWalk
, int baseIndex
, int ourIndex
, int theirIndex
)
74 // Record the initial state of this tree walk before iterating
75 final AbstractTreeIterator
[] initialTrees
= new AbstractTreeIterator
[treeWalk
77 for (int i
= 0; i
< treeWalk
.getTreeCount(); i
++) {
78 initialTrees
[i
] = treeWalk
.getTree(i
, AbstractTreeIterator
.class);
81 final GitResourceVariantCache baseCache
= new GitResourceVariantCache();
82 final GitResourceVariantCache theirsCache
= new GitResourceVariantCache();
83 final GitResourceVariantCache oursCache
= new GitResourceVariantCache();
85 while (treeWalk
.next()) {
86 final int modeBase
= treeWalk
.getRawMode(baseIndex
);
87 final int modeOurs
= treeWalk
.getRawMode(ourIndex
);
88 final int modeTheirs
= treeWalk
.getRawMode(theirIndex
);
89 if (modeBase
== 0 && modeOurs
== 0 && modeTheirs
== 0) {
94 final CanonicalTreeParser base
= treeWalk
.getTree(baseIndex
,
95 CanonicalTreeParser
.class);
96 final CanonicalTreeParser ours
= treeWalk
.getTree(ourIndex
,
97 CanonicalTreeParser
.class);
98 final CanonicalTreeParser theirs
= treeWalk
.getTree(theirIndex
,
99 CanonicalTreeParser
.class);
101 final IPath path
= new Path(treeWalk
.getPathString());
102 final IResource resource
= ResourceUtil
103 .getResourceHandleForLocation(path
);
104 // Resource variants only make sense for IResources. Do not consider
105 // files outside of the workspace or otherwise non accessible.
106 if (resource
.getProject() != null
107 && resource
.getProject().isAccessible()) {
109 baseCache
.setVariant(resource
,
110 TreeParserResourceVariant
.create(repository
, base
));
113 oursCache
.setVariant(resource
,
114 TreeParserResourceVariant
.create(repository
, ours
));
116 if (modeTheirs
!= 0) {
117 theirsCache
.setVariant(resource
,
118 TreeParserResourceVariant
.create(repository
, theirs
));
122 if (treeWalk
.isSubtree()) {
123 treeWalk
.enterSubtree();
127 // TODO any better way to reset the tree walk after an iteration?
129 for (int i
= 0; i
< initialTrees
.length
; i
++) {
130 initialTrees
[i
].reset();
131 treeWalk
.addTree(initialTrees
[i
]);
134 baseTree
= new GitCachedResourceVariantTree(baseCache
);
135 theirsTree
= new GitCachedResourceVariantTree(theirsCache
);
136 oursTree
= new GitCachedResourceVariantTree(oursCache
);
138 roots
= new LinkedHashSet
<IResource
>();
139 roots
.addAll(baseCache
.getRoots());
140 roots
.addAll(oursCache
.getRoots());
141 roots
.addAll(theirsCache
.getRoots());
143 knownResources
= new LinkedHashSet
<IResource
>();
144 knownResources
.addAll(baseCache
.getKnownResources());
145 knownResources
.addAll(oursCache
.getKnownResources());
146 knownResources
.addAll(theirsCache
.getKnownResources());
150 public IResourceVariantTree
getBaseTree() {
155 public IResourceVariantTree
getRemoteTree() {
160 public IResourceVariantTree
getSourceTree() {
165 public Set
<IResource
> getKnownResources() {
166 return knownResources
;
170 public Set
<IResource
> getRoots() {