1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.internal.ccvs.core.client;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener;
import org.eclipse.team.internal.ccvs.core.client.listeners.UpdateListener;
public class Update extends Command {
/*** Local options: specific to update ***/
public static final LocalOption CLEAR_STICKY = new LocalOption("-A"); //$NON-NLS-1$
public static final LocalOption IGNORE_LOCAL_CHANGES = new LocalOption("-C"); //$NON-NLS-1$
public static final LocalOption RETRIEVE_ABSENT_DIRECTORIES = new LocalOption("-d"); //$NON-NLS-1$
public static final LocalOption JOIN = new LocalOption("-j"); //$NON-NLS-1$
/*** Default command output listener ***/
private static final ICommandOutputListener DEFAULT_OUTPUT_LISTENER = new UpdateListener(null);
/*** File information status returned from update ***/
public static final int STATE_NONE = 0; // no state information available
public static final int STATE_ADDED_LOCAL = 1; // new file locally that was added but not comitted to server yet
public static final int STATE_UNKOWN = 2; // new file locally but not added to server
public static final int STATE_REMOTE_CHANGES = 3; // remote changes to an unmodified local file
public static final int STATE_DELETED = 4; // removed locally but still exists on the server
public static final int STATE_MODIFIED = 5; // modified locally
public static final int STATE_CONFLICT = 6; // modified locally and on the server but cannot be auto-merged
public static final int STATE_MERGEABLE_CONFLICT = 7; // modified locally and on the server but can be auto-merged
/**
* Makes a -r or -D or -A option for a tag.
* Valid for: checkout export history rdiff update
*/
public static LocalOption makeTagOption(CVSTag tag) {
int type = tag.getType();
switch (type) {
case CVSTag.HEAD:
return CLEAR_STICKY;
default:
return Command.makeTagOption(tag);
}
}
protected Update() { }
protected String getRequestId() {
return "update"; //$NON-NLS-1$
}
protected ICommandOutputListener getDefaultCommandOutputListener() {
return DEFAULT_OUTPUT_LISTENER;
}
protected ICVSResource[] sendLocalResourceState(Session session, GlobalOption[] globalOptions,
LocalOption[] localOptions, ICVSResource[] resources, IProgressMonitor monitor)
throws CVSException {
// Send all folders that are already managed to the server
// even folders that are empty
sendFileStructure(session, resources, localOptions, true, monitor);
return resources;
}
/**
* On successful finish, prune empty directories if the -P or -D option was specified.
*/
protected IStatus commandFinished(Session session, GlobalOption[] globalOptions,
LocalOption[] localOptions, ICVSResource[] resources, IProgressMonitor monitor,
IStatus status) throws CVSException {
// If we didn't succeed, don't do any post processing
if (status.getCode() == CVSStatus.SERVER_ERROR) {
return status;
}
// If we are pruning (-P), then prune empty directories
// Note, the CVS spec says that Date (-D) and version (-r) updates
// should automatically prune but this is a problem for remote CVS handles
// which fetch a level at a time
if (PRUNE_EMPTY_DIRECTORIES.isElementOf(localOptions)) {
// Delete empty directories
new PruneFolderVisitor().visit(session, resources);
}
return status;
}
protected LocalOption[] filterLocalOptions(Session session, GlobalOption[] globalOptions, LocalOption[] localOptions) {
List<LocalOption> newOptions = new ArrayList<>(Arrays.asList(localOptions));
if (shouldRetrieveAbsentDirectories(session) && ! RETRIEVE_ABSENT_DIRECTORIES.isElementOf(localOptions)) {
newOptions.add(Update.RETRIEVE_ABSENT_DIRECTORIES);
}
// Prune empty directories if pruning is enabled and the command in not being run in non-update mode
if (CVSProviderPlugin.getPlugin().getPruneEmptyDirectories() && ! PRUNE_EMPTY_DIRECTORIES.isElementOf(localOptions)) {
if (! DO_NOT_CHANGE.isElementOf(globalOptions)) {
newOptions.add(Command.PRUNE_EMPTY_DIRECTORIES);
}
}
localOptions = newOptions.toArray(new LocalOption[newOptions.size()]);
return super.filterLocalOptions(session, globalOptions, localOptions);
}
/**
* Return whether the update command should retrieve absent directories.
* @param session the session
* @return whether the update command should retrieve absent directories
*/
protected boolean shouldRetrieveAbsentDirectories(Session session) {
// Look for absent directories if enabled and the option is not already included
IResource resource = null;
RepositoryProvider provider = null;
// If there is a provider, use the providers setting
try {
resource = session.getLocalRoot().getIResource();
if (resource != null) {
provider = RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId());
if (provider != null) {
if (((CVSTeamProvider)provider).getFetchAbsentDirectories()) {
return true;
}
}
}
} catch (CVSException e) {
CVSProviderPlugin.log(e);
}
// If there is no provider, use the global setting
if (provider == null) {
if (CVSProviderPlugin.getPlugin().getFetchAbsentDirectories()) {
return true;
}
}
return false;
}
/**
* We allow unmanaged resources as long as there parents are managed.
*
* @see Command#checkResourcesManaged(Session, ICVSResource[])
*/
protected void checkResourcesManaged(Session session, ICVSResource[] resources) throws CVSException {
for (int i = 0; i < resources.length; ++i) {
ICVSFolder folder;
if (resources[i].isFolder()) {
if (((ICVSFolder)resources[i]).isCVSFolder()) {
folder = (ICVSFolder)resources[i];
} else {
folder = resources[i].getParent();
}
}
else {
folder = resources[i].getParent();
}
if (folder==null || (!folder.isCVSFolder() && folder.exists())) {
if (folder == null)
folder = (ICVSFolder)resources[i];
IStatus status = new CVSStatus(IStatus.ERROR,CVSStatus.ERROR,NLS.bind(CVSMessages.Command_argumentNotManaged, new String[] { folder.getName() }),session.getLocalRoot());
throw new CVSException(status);
}
}
}
@Override
protected IStatus doExecute(
Session session,
GlobalOption[] globalOptions,
LocalOption[] localOptions,
String[] arguments,
ICommandOutputListener listener,
IProgressMonitor monitor)
throws CVSException {
session.setIgnoringLocalChanges(IGNORE_LOCAL_CHANGES.isElementOf(localOptions));
try {
return super.doExecute(
session,
globalOptions,
localOptions,
arguments,
listener,
monitor);
} finally {
session.setIgnoringLocalChanges(false);
}
}
}
|