diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index 36cf77bb0..0c0257df9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java @@ -506,6 +506,35 @@ public void testBooleanWithNoValue() throws ConfigInvalidException { assertEquals("[my]\n\tempty\n", c.toText()); } + @Test + public void testRemoveBranchSection() throws ConfigInvalidException { + Config c = parse("" // + + "[branch \"keep\"]\n" + + " merge = master.branch.to.keep.in.the.file\n" + + "\n" + + "[branch \"remove\"]\n" + + " merge = this.will.get.deleted\n" + + " remote = origin-for-some-long-gone-place\n" + + "\n" + + "\n" + + "[core-section-not-to-remove-in-test]\n" + + " packedGitLimit = 14\n" + + "\n" + + "[other]\n" + + " foo = bar\n"); + assertFalse(c.removeSection("branch", "does.not.exist")); + assertTrue(c.removeSection("branch", "remove")); + assertEquals("" // + + "[branch \"keep\"]\n" + + " merge = master.branch.to.keep.in.the.file\n" + + "\n" + + "[core-section-not-to-remove-in-test]\n" + + " packedGitLimit = 14\n" + + "\n" + + "[other]\n" + + " foo = bar\n", c.toText()); + } + @Test public void testUnsetBranchSection() throws ConfigInvalidException { Config c = parse("" // @@ -516,8 +545,12 @@ public void testUnsetBranchSection() throws ConfigInvalidException { + " merge = this.will.get.deleted\n" + " remote = origin-for-some-long-gone-place\n" + "\n" + + "\n" + "[core-section-not-to-remove-in-test]\n" - + " packedGitLimit = 14\n"); + + " packedGitLimit = 14\n" + + "\n" + + "[other]\n" + + " foo = bar\n"); c.unsetSection("branch", "does.not.exist"); c.unsetSection("branch", "remove"); assertEquals("" // @@ -525,7 +558,10 @@ public void testUnsetBranchSection() throws ConfigInvalidException { + " merge = master.branch.to.keep.in.the.file\n" + "\n" + "[core-section-not-to-remove-in-test]\n" - + " packedGitLimit = 14\n", c.toText()); + + " packedGitLimit = 14\n" + + "\n" + + "[other]\n" + + " foo = bar\n", c.toText()); } @Test diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java index 7e2c5b5ad..07c5fa450 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java @@ -30,6 +30,7 @@ import java.util.Locale; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jgit.annotations.NonNull; @@ -921,29 +922,52 @@ public void unset(final String section, final String subsection, * optional subsection value, e.g. a branch name */ public void unsetSection(String section, String subsection) { - ConfigSnapshot src, res; - do { - src = state.get(); - res = unsetSection(src, section, subsection); - } while (!state.compareAndSet(src, res)); + removeSection(section, subsection); } - private ConfigSnapshot unsetSection(final ConfigSnapshot srcState, - final String section, - final String subsection) { + /** + * Removes all configuration values under a single section. + * + * @param section + * section name, e.g "branch" + * @param subsection + * optional subsection value, e.g. a branch name + * @return {@code true} if a section was present and was removed; + * {@code false} if the config was not changed (i.e., no such + * section was present) + * @since 6.8 + */ + public boolean removeSection(String section, String subsection) { + ConfigSnapshot src, res; + AtomicBoolean changed = new AtomicBoolean(); + do { + src = state.get(); + changed.set(false); + res = unsetSection(src, section, subsection, changed); + } while (!state.compareAndSet(src, res)); + return changed.get(); + } + + private ConfigSnapshot unsetSection(ConfigSnapshot srcState, String section, + String subsection, AtomicBoolean changed) { final int max = srcState.entryList.size(); final ArrayList r = new ArrayList<>(max); boolean lastWasMatch = false; for (ConfigLine e : srcState.entryList) { - if (e.includedFrom == null && e.match(section, subsection)) { - // Skip this record, it's for the section we are removing. - lastWasMatch = true; + if (e.includedFrom != null) { + r.add(e); continue; } - - if (lastWasMatch && e.section == null && e.subsection == null) + if (lastWasMatch && e.section == null && e.subsection == null) { continue; // skip this padding line in the section. + } + lastWasMatch = e.match(section, subsection); + if (lastWasMatch) { + // Skip this record, it's for the section we are removing. + changed.set(true); + continue; + } r.add(e); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index 7fdcc4d3e..cedc4d6cc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -5,7 +5,7 @@ * Copyright (C) 2009, JetBrains s.r.o. * Copyright (C) 2008-2009, Robin Rosenberg * Copyright (C) 2008, Shawn O. Pearce - * Copyright (C) 2008, Thad Hughes and others + * Copyright (C) 2008, 2023 Thad Hughes and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -22,7 +22,6 @@ import java.io.File; import java.io.IOException; import java.text.MessageFormat; -import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jgit.errors.ConfigInvalidException; @@ -107,17 +106,6 @@ boolean exists() { return exists.get(); } - @Override - public void setStringList(String section, String subsection, String name, - List values) { - super.setStringList(section, subsection, name, values); - } - - @Override - public void unsetSection(String section, String subsection) { - super.unsetSection(section, subsection); - } - /** * {@inheritDoc} *

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java index 2ad74c23c..c1eaac7b5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java @@ -82,6 +82,14 @@ public void unsetSection(String section, String subsection) { } } + @Override + public boolean removeSection(String section, String subsection) { + if (exists() || !parent.exists()) { + return super.removeSection(section, subsection); + } + return parent.removeSection(section, subsection); + } + @Override public boolean isOutdated() { return super.isOutdated() || parent.isOutdated();