aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2022-01-22 17:00:32 +0100
committerThomas Wolf <thomas.wolf@paranor.ch>2022-03-26 19:53:37 +0100
commita187d12dd9d44d4af8ae5c7e9ec4923222c2f249 (patch)
treea700ee3a0e7a97b00380da7d3d12076738d58138
parenta171360292cedde6f05a40069e36946a8045a6a1 (diff)
downloadjgit-a187d12dd9d44d4af8ae5c7e9ec4923222c2f249.tar.gz
jgit-a187d12dd9d44d4af8ae5c7e9ec4923222c2f249.zip
CommitConfig: add support for core.commentChar
Provide access to the core.commentChar git config, and provide a utility method to determine an unused comment character if the setting is "auto". Bug: 579325 Change-Id: I1ec7e4deffea6ac5929a8538a624d73bb59e4ecc Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java79
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java104
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java9
3 files changed, 190 insertions, 2 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java
index d95d7814e4..7066f9d422 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java
@@ -11,7 +11,10 @@
package org.eclipse.jgit.lib;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitConfig.CleanupMode;
@@ -169,6 +172,82 @@ public class CommitConfigTest {
CommitConfig.cleanText(message, CleanupMode.SCISSORS, '#'));
}
+ @Test
+ public void testCommentCharDefault() throws Exception {
+ CommitConfig cfg = parse("");
+ assertEquals('#', cfg.getCommentChar());
+ assertFalse(cfg.isAutoCommentChar());
+ }
+
+ @Test
+ public void testCommentCharAuto() throws Exception {
+ CommitConfig cfg = parse("[core]\n\tcommentChar = auto\n");
+ assertEquals('#', cfg.getCommentChar());
+ assertTrue(cfg.isAutoCommentChar());
+ }
+
+ @Test
+ public void testCommentCharEmpty() throws Exception {
+ CommitConfig cfg = parse("[core]\n\tcommentChar =\n");
+ assertEquals('#', cfg.getCommentChar());
+ }
+
+ @Test
+ public void testCommentCharInvalid() throws Exception {
+ CommitConfig cfg = parse("[core]\n\tcommentChar = \" \"\n");
+ assertEquals('#', cfg.getCommentChar());
+ }
+
+ @Test
+ public void testCommentCharNonAscii() throws Exception {
+ CommitConfig cfg = parse("[core]\n\tcommentChar = รถ\n");
+ assertEquals('#', cfg.getCommentChar());
+ }
+
+ @Test
+ public void testCommentChar() throws Exception {
+ CommitConfig cfg = parse("[core]\n\tcommentChar = _\n");
+ assertEquals('_', cfg.getCommentChar());
+ }
+
+ @Test
+ public void testDetermineCommentChar() throws Exception {
+ String text = "A commit message\n\nBody\n";
+ assertEquals('#', CommitConfig.determineCommentChar(text));
+ }
+
+ @Test
+ public void testDetermineCommentChar2() throws Exception {
+ String text = "A commit message\n\nBody\n\n# Conflicts:\n#\tfoo.txt\n";
+ char ch = CommitConfig.determineCommentChar(text);
+ assertNotEquals('#', ch);
+ assertTrue(ch > ' ' && ch < 127);
+ }
+
+ @Test
+ public void testDetermineCommentChar3() throws Exception {
+ String text = "A commit message\n\n;Body\n\n# Conflicts:\n#\tfoo.txt\n";
+ char ch = CommitConfig.determineCommentChar(text);
+ assertNotEquals('#', ch);
+ assertNotEquals(';', ch);
+ assertTrue(ch > ' ' && ch < 127);
+ }
+
+ @Test
+ public void testDetermineCommentChar4() throws Exception {
+ String text = "A commit message\n\nBody\n\n # Conflicts:\n\t #\tfoo.txt\n";
+ char ch = CommitConfig.determineCommentChar(text);
+ assertNotEquals('#', ch);
+ assertTrue(ch > ' ' && ch < 127);
+ }
+
+ @Test
+ public void testDetermineCommentChar5() throws Exception {
+ String text = "A commit message\n\nBody\n\n#a\n;b\n@c\n!d\n$\n%\n^\n&\n|\n:";
+ char ch = CommitConfig.determineCommentChar(text);
+ assertEquals(0, ch);
+ }
+
private static CommitConfig parse(String content)
throws ConfigInvalidException {
Config c = new Config();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
index 55cc02683a..6a9b45b065 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Julian Ruppel <julian.ruppel@sap.com>
+ * Copyright (c) 2020, 2022 Julian Ruppel <julian.ruppel@sap.com> 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
@@ -29,6 +29,7 @@ import org.eclipse.jgit.lib.Config.SectionParser;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.jgit.util.StringUtils;
/**
* The standard "commit" configuration parameters.
@@ -44,6 +45,9 @@ public class CommitConfig {
private static final String CUT = " ------------------------ >8 ------------------------\n"; //$NON-NLS-1$
+ private static final char[] COMMENT_CHARS = { '#', ';', '@', '!', '$', '%',
+ '^', '&', '|', ':' };
+
/**
* How to clean up commit messages when committing.
*
@@ -99,6 +103,10 @@ public class CommitConfig {
private CleanupMode cleanupMode;
+ private char commentCharacter = '#';
+
+ private boolean autoCommentChar = false;
+
private CommitConfig(Config rc) {
commitTemplatePath = rc.getString(ConfigConstants.CONFIG_COMMIT_SECTION,
null, ConfigConstants.CONFIG_KEY_COMMIT_TEMPLATE);
@@ -106,6 +114,18 @@ public class CommitConfig {
null, ConfigConstants.CONFIG_KEY_COMMIT_ENCODING);
cleanupMode = rc.getEnum(ConfigConstants.CONFIG_COMMIT_SECTION, null,
ConfigConstants.CONFIG_KEY_CLEANUP, CleanupMode.DEFAULT);
+ String comment = rc.getString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_COMMENT_CHAR);
+ if (!StringUtils.isEmptyOrNull(comment)) {
+ if ("auto".equalsIgnoreCase(comment)) { //$NON-NLS-1$
+ autoCommentChar = true;
+ } else {
+ char first = comment.charAt(0);
+ if (first > ' ' && first < 127) {
+ commentCharacter = first;
+ }
+ }
+ }
}
/**
@@ -131,6 +151,51 @@ public class CommitConfig {
}
/**
+ * Retrieves the comment character set by git config
+ * {@code core.commentChar}.
+ *
+ * @return the character to use for comments in commit messages
+ * @since 6.2
+ */
+ public char getCommentChar() {
+ return commentCharacter;
+ }
+
+ /**
+ * Determines the comment character to use for a particular text. If
+ * {@code core.commentChar} is "auto", tries to determine an unused
+ * character; if none is found, falls back to '#'. Otherwise returns the
+ * character given by {@code core.commentChar}.
+ *
+ * @param text
+ * existing text
+ *
+ * @return the character to use
+ * @since 6.2
+ */
+ public char getCommentChar(String text) {
+ if (isAutoCommentChar()) {
+ char toUse = determineCommentChar(text);
+ if (toUse > 0) {
+ return toUse;
+ }
+ return '#';
+ }
+ return getCommentChar();
+ }
+
+ /**
+ * Tells whether the comment character should be determined by choosing a
+ * character not occurring in a commit message.
+ *
+ * @return {@code true} if git config {@code core.commentChar} is "auto"
+ * @since 6.2
+ */
+ public boolean isAutoCommentChar() {
+ return autoCommentChar;
+ }
+
+ /**
* Retrieves the {@link CleanupMode} as given by git config
* {@code commit.cleanup}.
*
@@ -315,4 +380,41 @@ public class CommitConfig {
}
return false;
}
+
+ /**
+ * Determines a comment character by choosing one from a limited set of
+ * 7-bit ASCII characters that do not occur in the given text at the
+ * beginning of any line. If none can be determined, {@code (char) 0} is
+ * returned.
+ *
+ * @param text
+ * to get a comment character for
+ * @return the comment character, or {@code (char) 0} if none could be
+ * determined
+ * @since 6.2
+ */
+ public static char determineCommentChar(String text) {
+ if (StringUtils.isEmptyOrNull(text)) {
+ return '#';
+ }
+ final boolean[] inUse = new boolean[127];
+ for (String line : text.split("\n")) { //$NON-NLS-1$
+ int len = line.length();
+ for (int i = 0; i < len; i++) {
+ char ch = line.charAt(i);
+ if (!Character.isWhitespace(ch)) {
+ if (ch >= 0 && ch < inUse.length) {
+ inUse[ch] = true;
+ }
+ break;
+ }
+ }
+ }
+ for (char candidate : COMMENT_CHARS) {
+ if (!inUse[candidate]) {
+ return candidate;
+ }
+ }
+ return (char) 0;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index 80d720ae41..8ad32d41c7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -2,7 +2,7 @@
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
* Copyright (C) 2012-2013, Robin Rosenberg
- * Copyright (C) 2018-2021, Andre Bossert <andre.bossert@siemens.com> and others
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com> 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
@@ -203,6 +203,13 @@ public final class ConfigConstants {
public static final String CONFIG_KEY_FORCE_SIGN_ANNOTATED = "forceSignAnnotated";
/**
+ * The "commentChar" key.
+ *
+ * @since 6.2
+ */
+ public static final String CONFIG_KEY_COMMENT_CHAR = "commentChar";
+
+ /**
* The "hooksPath" key.
*
* @since 5.6