Skip to content

Commit ee7d2e9

Browse files
committed
Add preference for disabling history on specific files
This change adds a new preference to org.eclipse.core.resources: disable_history_property The preference can be set to a session property name, e.g.: disable_history If the preference is set and a file has the respective session property, setting the contents of the file will result in no new history entry for the edit. Example preference for product customization: org.eclipse.core.resources/disble_history_property=disable_history The session property can be set with: file.setSessionProperty(new QualifiedName(null, "disable_history"), "true"); Fixes: #2588
1 parent 86c0357 commit ee7d2e9

3 files changed

Lines changed: 143 additions & 5 deletions

File tree

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import org.eclipse.core.runtime.MultiStatus;
7474
import org.eclipse.core.runtime.OperationCanceledException;
7575
import org.eclipse.core.runtime.Platform;
76+
import org.eclipse.core.runtime.QualifiedName;
7677
import org.eclipse.core.runtime.SubMonitor;
7778
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
7879
import org.eclipse.core.runtime.preferences.InstanceScope;
@@ -84,18 +85,26 @@
8485
*/
8586
public class FileSystemResourceManager implements ICoreConstants, IManager {
8687

88+
private static final String DISABLE_HISTORY_PREFERENCE_NAME = "disable_history_property"; //$NON-NLS-1$
89+
8790
/**
8891
* The history store is initialized lazily - always use the accessor method
8992
*/
9093
protected IHistoryStore _historyStore;
9194
protected Workspace workspace;
9295

9396
private volatile boolean lightweightAutoRefreshEnabled;
97+
private volatile QualifiedName disableHistoryProperty;
9498

95-
private final IPreferenceChangeListener lightweightAutoRefreshPrefListener = event -> {
96-
if (ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH.equals(event.getKey())) {
99+
private final IPreferenceChangeListener prefListener = event -> {
100+
String preferenceName = event.getKey();
101+
if (ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH.equals(preferenceName)) {
97102
lightweightAutoRefreshEnabled = Platform.getPreferencesService().getBoolean(ResourcesPlugin.PI_RESOURCES,
98103
ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, false, null);
104+
} else if (DISABLE_HISTORY_PREFERENCE_NAME.equals(preferenceName)) {
105+
String propertyName = Platform.getPreferencesService().getString(ResourcesPlugin.PI_RESOURCES,
106+
DISABLE_HISTORY_PREFERENCE_NAME, "", null); //$NON-NLS-1$
107+
disableHistoryProperty = propertyName.isEmpty() ? null : new QualifiedName(null, propertyName);
99108
}
100109
};
101110

@@ -1203,13 +1212,13 @@ public void shutdown(IProgressMonitor monitor) throws CoreException {
12031212
_historyStore.shutdown(monitor);
12041213
}
12051214
InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES)
1206-
.removePreferenceChangeListener(lightweightAutoRefreshPrefListener);
1215+
.removePreferenceChangeListener(prefListener);
12071216
}
12081217

12091218
@Override
12101219
public void startup(IProgressMonitor monitor) {
12111220
InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES)
1212-
.addPreferenceChangeListener(lightweightAutoRefreshPrefListener);
1221+
.addPreferenceChangeListener(prefListener);
12131222
lightweightAutoRefreshEnabled = Platform.getPreferencesService().getBoolean(ResourcesPlugin.PI_RESOURCES,
12141223
ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, false, null);
12151224
}
@@ -1497,7 +1506,22 @@ public void writeSilently(IProject target) throws CoreException {
14971506

14981507
public static boolean storeHistory(IResource file) {
14991508
WorkspaceDescription description = ((Workspace) file.getWorkspace()).internalGetDescription();
1500-
return description.isKeepDerivedState() || !file.isDerived();
1509+
return (description.isKeepDerivedState() || !file.isDerived()) && !disableHistory(file);
15011510
}
15021511

1512+
private static boolean disableHistory(IResource resource) {
1513+
if (resource.getType() == IResource.FILE && resource.getWorkspace() instanceof Workspace ws) {
1514+
FileSystemResourceManager manager = ws.getFileSystemManager();
1515+
QualifiedName property = manager.disableHistoryProperty;
1516+
if (property != null) {
1517+
try {
1518+
return resource.getSessionProperty(property) != null;
1519+
} catch (CoreException e) {
1520+
Policy.log(e);
1521+
return true;
1522+
}
1523+
}
1524+
}
1525+
return false;
1526+
}
15031527
}

resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/AllLocalStoreTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
SafeFileInputOutputStreamTest.class, //
3636
SymlinkResourceTest.class, //
3737
UnifiedTreeTest.class, //
38+
DisableHistoryTests.class, //
3839
})
3940
public class AllLocalStoreTests {
4041

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Simeon Andreev and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Simeon Andreev - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.core.tests.internal.localstore;
15+
16+
import static org.eclipse.core.resources.ResourcesPlugin.getWorkspace;
17+
import static org.eclipse.core.tests.resources.ResourceTestUtil.createInWorkspace;
18+
import static org.junit.jupiter.api.Assertions.assertEquals;
19+
20+
import java.util.Arrays;
21+
import org.eclipse.core.resources.IFile;
22+
import org.eclipse.core.resources.IFileState;
23+
import org.eclipse.core.resources.IProject;
24+
import org.eclipse.core.resources.IResource;
25+
import org.eclipse.core.resources.ResourcesPlugin;
26+
import org.eclipse.core.runtime.CoreException;
27+
import org.eclipse.core.runtime.QualifiedName;
28+
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
29+
import org.eclipse.core.runtime.preferences.InstanceScope;
30+
import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
31+
import org.junit.jupiter.api.AfterEach;
32+
import org.junit.jupiter.api.BeforeEach;
33+
import org.junit.jupiter.api.Test;
34+
import org.junit.jupiter.api.extension.ExtendWith;
35+
import org.osgi.service.prefs.BackingStoreException;
36+
37+
/**
38+
* Test for disabling file history based on a preference. Sets the preference
39+
* {@code org.eclipse.core.resources/disable_history_property=disable_history},
40+
* adds the session property {@code disable_history} on some test file and
41+
* performs edits. After setting the preference and session property, no new
42+
* file history is expected.
43+
*/
44+
@ExtendWith(WorkspaceResetExtension.class)
45+
public class DisableHistoryTests {
46+
47+
private static final String DISABLE_PREFERENCE_NAME = "disable_history_property";
48+
49+
private static final QualifiedName SESSION_PROPERTY_QN = new QualifiedName(null, "disable_history");
50+
51+
private IProject project;
52+
53+
@BeforeEach
54+
public void createTestProject() throws Exception {
55+
project = getWorkspace().getRoot().getProject("Project");
56+
createInWorkspace(project);
57+
}
58+
59+
@AfterEach
60+
public void cleanUp() throws Exception {
61+
setHistoryDisablePreference(null);
62+
}
63+
64+
@Test
65+
public void testDisableHistoryBeforeEdit() throws Exception {
66+
IFile file = project.getFile("test.txt");
67+
file.create("initial".getBytes(), IResource.FORCE, null);
68+
setHistoryDisablePreference(SESSION_PROPERTY_QN.getLocalName());
69+
disableHistory(file);
70+
writeContents(file, "edit 1");
71+
writeContents(file, "edit 2");
72+
IFileState[] history = file.getHistory(null);
73+
assertEquals(0, history.length, "Unexpected history: " + toString(history));
74+
}
75+
76+
@Test
77+
public void testDisableHistoryAfterEdit() throws Exception {
78+
IFile file = project.getFile("test.txt");
79+
file.create("initial".getBytes(), IResource.FORCE, null);
80+
writeContents(file, "edit 1");
81+
writeContents(file, "edit 2");
82+
IFileState[] history = file.getHistory(null);
83+
assertEquals(2, history.length, "Unexpected history: " + toString(history));
84+
setHistoryDisablePreference(SESSION_PROPERTY_QN.getLocalName());
85+
disableHistory(file);
86+
writeContents(file, "edit 3");
87+
history = file.getHistory(null);
88+
assertEquals(2, history.length, "Unexpected history: " + toString(history));
89+
}
90+
91+
92+
private void writeContents(IFile file, String contents) throws CoreException {
93+
file.setContents(contents.getBytes(), IResource.KEEP_HISTORY, null);
94+
}
95+
96+
private static String toString(IFileState... states) {
97+
return Arrays.toString(states);
98+
}
99+
100+
private static void disableHistory(IFile file) throws CoreException {
101+
file.setSessionProperty(SESSION_PROPERTY_QN, "true");
102+
}
103+
104+
private static void setHistoryDisablePreference(String value) throws BackingStoreException {
105+
IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES);
106+
if (value != null) {
107+
node.put(DISABLE_PREFERENCE_NAME, value);
108+
} else {
109+
node.remove(DISABLE_PREFERENCE_NAME);
110+
}
111+
node.flush();
112+
}
113+
}

0 commit comments

Comments
 (0)