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
.op
;
19 import java
.io
.IOException
;
20 import java
.util
.Collection
;
21 import java
.util
.IdentityHashMap
;
22 import java
.util
.Iterator
;
25 import org
.eclipse
.core
.resources
.IContainer
;
26 import org
.eclipse
.core
.resources
.IFile
;
27 import org
.eclipse
.core
.resources
.IResource
;
28 import org
.eclipse
.core
.resources
.IWorkspaceRunnable
;
29 import org
.eclipse
.core
.runtime
.CoreException
;
30 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
31 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
32 import org
.spearce
.egit
.core
.Activator
;
33 import org
.spearce
.egit
.core
.CoreText
;
34 import org
.spearce
.egit
.core
.project
.GitProjectData
;
35 import org
.spearce
.egit
.core
.project
.RepositoryMapping
;
36 import org
.spearce
.jgit
.lib
.Tree
;
37 import org
.spearce
.jgit
.lib
.TreeEntry
;
40 * Add one or more new files/folders to the Git repository.
42 * Accepts a collection of resources (files and/or directories) which should be
43 * added to the their corresponding Git repositories. Resources in the
44 * collection can be associated with multiple repositories. The operation will
45 * automatically associate each resource with the nearest containing Git
49 * Resources are only scheduled for addition in the cache-tree. Their backing
50 * object in the object database is not built yet (as that can be a time
51 * consuming operation, depending on file size) and the cache-tree will be dirty
52 * in memory, needing a checkpoint.
55 public class TrackOperation
implements IWorkspaceRunnable
{
56 private final Collection rsrcList
;
59 * Create a new operation to track additional files/folders.
62 * collection of {@link IResource}s which should be added to the
63 * relevant Git repositories.
65 public TrackOperation(final Collection rsrcs
) {
69 public void run(IProgressMonitor m
) throws CoreException
{
71 m
= new NullProgressMonitor();
74 final IdentityHashMap tomerge
= new IdentityHashMap();
75 m
.beginTask(CoreText
.AddOperation_adding
, rsrcList
.size() * 200);
77 final Iterator i
= rsrcList
.iterator();
79 final Object obj
= i
.next();
80 if (obj
instanceof IResource
) {
81 add(tomerge
, (IResource
) obj
);
87 final Iterator i
= tomerge
.keySet().iterator();
89 final RepositoryMapping r
= (RepositoryMapping
) i
.next();
92 } catch (IOException ioe
) {
93 throw Activator
.error(CoreText
.AddOperation_failed
, ioe
);
100 private void add(final Map tomerge
, final IResource toAdd
)
101 throws CoreException
{
102 final GitProjectData pd
= GitProjectData
.get(toAdd
.getProject());
105 RepositoryMapping m
= null;
108 m
= pd
.getRepositoryMapping(r
);
114 s
= r
.getName() + "/" + s
;
122 if (s
== null || m
== null || m
.getCacheTree() == null) {
128 add(m
.getCacheTree(), s
, toAdd
);
129 } catch (IOException ioe
) {
130 throw Activator
.error(CoreText
.AddOperation_failed
, ioe
);
134 private void add(final Tree t
, final String path
, final IResource toAdd
)
135 throws IOException
, CoreException
{
136 if (!toAdd
.exists()) {
137 // Uh, what? Why are we adding a phantom resource? Just say no!
139 } else if (toAdd
instanceof IFile
) {
140 if (!t
.existsTree(path
)) {
141 if (!t
.existsBlob(path
)) {
145 } else if (toAdd
instanceof IContainer
) {
146 final IResource
[] m
= ((IContainer
) toAdd
).members();
147 final TreeEntry e
= t
.findTreeMember(path
);
149 c
= e
instanceof Tree ?
(Tree
) e
: e
== null ? t
.addTree(path
)
152 for (int k
= 0; k
< m
.length
; k
++) {
153 add(c
, m
[k
].getName(), m
[k
]);
156 // GIT does not take kindly to empty trees. If we just created
157 // such a thing remove it. We do the detection after-the-fact
158 // as its hard to know if all of our children were also empty
161 if (c
.memberCount() == 0) {