1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
4 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *******************************************************************************/
11 package org
.eclipse
.egit
.core
.op
;
14 import java
.io
.IOException
;
15 import java
.util
.Collection
;
16 import java
.util
.IdentityHashMap
;
17 import java
.util
.Iterator
;
19 import org
.eclipse
.core
.resources
.IContainer
;
20 import org
.eclipse
.core
.resources
.IFile
;
21 import org
.eclipse
.core
.resources
.IResource
;
22 import org
.eclipse
.core
.resources
.IResourceVisitor
;
23 import org
.eclipse
.core
.resources
.IWorkspaceRunnable
;
24 import org
.eclipse
.core
.runtime
.CoreException
;
25 import org
.eclipse
.core
.runtime
.IAdaptable
;
26 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
27 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
28 import org
.eclipse
.egit
.core
.Activator
;
29 import org
.eclipse
.egit
.core
.CoreText
;
30 import org
.eclipse
.egit
.core
.internal
.trace
.GitTraceLocation
;
31 import org
.eclipse
.egit
.core
.project
.RepositoryMapping
;
32 import org
.eclipse
.osgi
.util
.NLS
;
33 import org
.eclipse
.team
.core
.Team
;
34 import org
.eclipse
.jgit
.lib
.GitIndex
;
35 import org
.eclipse
.jgit
.lib
.GitIndex
.Entry
;
38 * Add one or more new files/folders to the Git repository.
40 * Accepts a collection of resources (files and/or directories) which should be
41 * added to the their corresponding Git repositories. Resources in the
42 * collection can be associated with multiple repositories. The operation will
43 * automatically associate each resource with the nearest containing Git
47 * Resources are only scheduled for addition in the index.
50 public class TrackOperation
implements IWorkspaceRunnable
{
51 private final Collection rsrcList
;
54 * Create a new operation to track additional files/folders.
57 * collection of {@link IResource}s which should be added to the
58 * relevant Git repositories.
60 public TrackOperation(final Collection rsrcs
) {
64 public void run(IProgressMonitor m
) throws CoreException
{
66 m
= new NullProgressMonitor();
69 final IdentityHashMap
<RepositoryMapping
, Boolean
> tomerge
= new IdentityHashMap
<RepositoryMapping
, Boolean
>();
70 m
.beginTask(CoreText
.AddOperation_adding
, rsrcList
.size() * 200);
72 for (Object obj
: rsrcList
) {
73 obj
= ((IAdaptable
)obj
).getAdapter(IResource
.class);
74 if (obj
instanceof IResource
) {
75 final IResource toAdd
= (IResource
)obj
;
76 final RepositoryMapping rm
= RepositoryMapping
.getMapping(toAdd
);
77 final GitIndex index
= rm
.getRepository().getIndex();
79 if (obj
instanceof IFile
) {
80 String repoPath
= rm
.getRepoRelativePath((IResource
) obj
);
81 Entry entry
= index
.getEntry(repoPath
);
83 if (!entry
.isAssumedValid()) {
84 // TODO is this the right location?
85 if (GitTraceLocation
.CORE
.isActive())
91 "Already tracked - skipping"); //$NON-NLS-1$
97 tomerge
.put(rm
, Boolean
.TRUE
);
98 if (toAdd
instanceof IContainer
) {
99 ((IContainer
)toAdd
).accept(new IResourceVisitor() {
100 public boolean visit(IResource resource
) throws CoreException
{
102 String repoPath
= rm
.getRepoRelativePath(resource
);
103 // We use add to reset the assume valid bit, so we check the bit
104 // first. If a resource within a ignored folder is marked
105 // we ignore it here, i.e. there is no way to unmark it expect
106 // by explicitly selecting and invoking track on it.
107 boolean isIgnored
= Team
.isIgnoredHint(resource
);
108 if (resource
.getType() == IResource
.FILE
) {
109 Entry entry
= index
.getEntry(repoPath
);
110 if (!isIgnored
|| entry
!= null && entry
.isAssumedValid()) {
111 entry
= index
.add(rm
.getWorkDir(), new File(rm
.getWorkDir(), repoPath
));
112 entry
.setAssumeValid(false);
118 } catch (IOException e
) {
119 if (GitTraceLocation
.CORE
.isActive())
120 GitTraceLocation
.getTrace().trace(GitTraceLocation
.CORE
.getLocation(), e
.getMessage(), e
);
121 throw new CoreException(Activator
.error(CoreText
.AddOperation_failed
, e
));
125 },IResource
.DEPTH_INFINITE
, IContainer
.EXCLUDE_DERIVED
);
127 Entry entry
= index
.add(rm
.getWorkDir(), new File(rm
.getWorkDir(),rm
.getRepoRelativePath(toAdd
)));
128 entry
.setAssumeValid(false);
134 for (RepositoryMapping rm
: tomerge
.keySet()) {
135 m
.setTaskName(NLS
.bind(CoreText
.TrackOperation_writingIndex
, rm
.getRepository().getDirectory()));
136 rm
.getRepository().getIndex().write();
138 } catch (RuntimeException e
) {
139 if (GitTraceLocation
.CORE
.isActive())
140 GitTraceLocation
.getTrace().trace(GitTraceLocation
.CORE
.getLocation(), e
.getMessage(), e
);
141 throw new CoreException(Activator
.error(CoreText
.AddOperation_failed
, e
));
142 } catch (IOException e
) {
143 if (GitTraceLocation
.CORE
.isActive())
144 GitTraceLocation
.getTrace().trace(GitTraceLocation
.CORE
.getLocation(), e
.getMessage(), e
);
145 throw new CoreException(Activator
.error(CoreText
.AddOperation_failed
, e
));
148 final Iterator i
= tomerge
.keySet().iterator();
149 while (i
.hasNext()) {
150 final RepositoryMapping r
= (RepositoryMapping
) i
.next();
151 r
.getRepository().getIndex().read();
152 r
.fireRepositoryChanged();
154 } catch (IOException e
) {
155 if (GitTraceLocation
.CORE
.isActive())
156 GitTraceLocation
.getTrace().trace(GitTraceLocation
.CORE
.getLocation(), e
.getMessage(), e
);