diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryConfigTest.java
index 203b7c82514a3045da23cabcd98ecb9fef213734..41c4971a04e08181ed9fee6106f7d8cc94a69e1f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryConfigTest.java
@@ -271,6 +271,47 @@ public void testEmptyString() throws ConfigInvalidException {
 		assertEquals("[my]\n\tempty =\n", c.toText());
 	}
 
+	public void testUnsetBranchSection() 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"
+				+ "[core-section-not-to-remove-in-test]\n"
+				+ "  packedGitLimit = 14\n");
+		c.unsetSection("branch", "does.not.exist");
+		c.unsetSection("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", c.toText());
+	}
+
+	public void testUnsetSingleSection() throws ConfigInvalidException {
+		Config c = parse("" //
+				+ "[branch \"keep\"]\n"
+				+ "  merge = master.branch.to.keep.in.the.file\n"
+				+ "\n"
+				+ "[single]\n"
+				+ "  merge = this.will.get.deleted\n"
+				+ "  remote = origin-for-some-long-gone-place\n"
+				+ "\n"
+				+ "[core-section-not-to-remove-in-test]\n"
+				+ "  packedGitLimit = 14\n");
+		c.unsetSection("single", null);
+		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", c.toText());
+	}
+
 	private void assertReadLong(long exp) throws ConfigInvalidException {
 		assertReadLong(exp, String.valueOf(exp));
 	}
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 d66aa74c8e67188f6104edaf2119b28e446211b4..0d0c377f8fcc05504e41c7aa4b5a2edf3d446557 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -576,6 +576,43 @@ public void unset(final String section, final String subsection,
 				.<String> emptyList());
 	}
 
+	/**
+	 * Remove all configuration values under a single section.
+	 *
+	 * @param section
+	 *            section name, e.g "branch"
+	 * @param subsection
+	 *            optional subsection value, e.g. a branch name
+	 */
+	public void unsetSection(String section, String subsection) {
+		State src, res;
+		do {
+			src = state.get();
+			res = unsetSection(src, section, subsection);
+		} while (!state.compareAndSet(src, res));
+	}
+
+	private State unsetSection(final State srcState, final String section,
+			final String subsection) {
+		final int max = srcState.entryList.size();
+		final ArrayList<Entry> r = new ArrayList<Entry>(max);
+
+		boolean lastWasMatch = false;
+		for (Entry e : srcState.entryList) {
+			if (e.match(section, subsection)) {
+				// Skip this record, it's for the section we are removing.
+				lastWasMatch = true;
+				continue;
+			}
+
+			if (lastWasMatch && e.section == null && e.subsection == null)
+				continue; // skip this padding line in the section.
+			r.add(e);
+		}
+
+		return newState(r);
+	}
+
 	/**
 	 * Set a configuration value.
 	 *
@@ -1104,6 +1141,11 @@ && eqSameCase(subsection, aSubsection)
 					&& eqIgnoreCase(name, aKey);
 		}
 
+		boolean match(final String aSection, final String aSubsection) {
+			return eqIgnoreCase(section, aSection)
+					&& eqSameCase(subsection, aSubsection);
+		}
+
 		private static boolean eqIgnoreCase(final String a, final String b) {
 			if (a == null && b == null)
 				return true;