summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2022-01-15 22:51:06 +0100
committerThomas Wolf <thomas.wolf@paranor.ch>2022-01-31 00:42:35 +0100
commit318a25f0e62553ee771962369462d54f0e8870c8 (patch)
tree00ebb1251ecf4d23e1b46147b09388ff9b1af38f /org.eclipse.jgit
parent2b01ac3389c11be88ec875048d6a2cc4ed6903f1 (diff)
downloadjgit-318a25f0e62553ee771962369462d54f0e8870c8.tar.gz
jgit-318a25f0e62553ee771962369462d54f0e8870c8.zip
Provide git config commit.cleanup
Add an enumeration for the possible values, and a method to resolve the "default" value. Give CommitConfig a static method to process a text according to a given clean-up mode and comment character. (The core.commentChar is not yet handled by JGit; it's hard-coded as #.) Bug: 553065 Change-Id: If6e384522275f73b713fbc29ffcaa1753c239dea Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java180
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java7
2 files changed, 187 insertions, 0 deletions
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 22e1f98181..55cc02683a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
@@ -18,11 +18,13 @@ import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.text.MessageFormat;
+import java.util.Locale;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.Config.ConfigEnum;
import org.eclipse.jgit.lib.Config.SectionParser;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
@@ -34,22 +36,76 @@ import org.eclipse.jgit.util.RawParseUtils;
* @since 5.13
*/
public class CommitConfig {
+
/**
* Key for {@link Config#get(SectionParser)}.
*/
public static final Config.SectionParser<CommitConfig> KEY = CommitConfig::new;
+ private static final String CUT = " ------------------------ >8 ------------------------\n"; //$NON-NLS-1$
+
+ /**
+ * How to clean up commit messages when committing.
+ *
+ * @since 6.1
+ */
+ public enum CleanupMode implements ConfigEnum {
+
+ /**
+ * {@link #WHITESPACE}, additionally remove comment lines.
+ */
+ STRIP,
+
+ /**
+ * Remove trailing whitespace and leading and trailing empty lines;
+ * collapse multiple empty lines to a single one.
+ */
+ WHITESPACE,
+
+ /**
+ * Make no changes.
+ */
+ VERBATIM,
+
+ /**
+ * Omit everything from the first "scissor" line on, then apply
+ * {@link #WHITESPACE}.
+ */
+ SCISSORS,
+
+ /**
+ * Use {@link #STRIP} for user-edited messages, otherwise
+ * {@link #WHITESPACE}, unless overridden by a git config setting other
+ * than DEFAULT.
+ */
+ DEFAULT;
+
+ @Override
+ public String toConfigValue() {
+ return name().toLowerCase(Locale.ROOT);
+ }
+
+ @Override
+ public boolean matchConfigValue(String in) {
+ return toConfigValue().equals(in);
+ }
+ }
+
private final static Charset DEFAULT_COMMIT_MESSAGE_ENCODING = StandardCharsets.UTF_8;
private String i18nCommitEncoding;
private String commitTemplatePath;
+ private CleanupMode cleanupMode;
+
private CommitConfig(Config rc) {
commitTemplatePath = rc.getString(ConfigConstants.CONFIG_COMMIT_SECTION,
null, ConfigConstants.CONFIG_KEY_COMMIT_TEMPLATE);
i18nCommitEncoding = rc.getString(ConfigConstants.CONFIG_SECTION_I18N,
null, ConfigConstants.CONFIG_KEY_COMMIT_ENCODING);
+ cleanupMode = rc.getEnum(ConfigConstants.CONFIG_COMMIT_SECTION, null,
+ ConfigConstants.CONFIG_KEY_CLEANUP, CleanupMode.DEFAULT);
}
/**
@@ -75,6 +131,48 @@ public class CommitConfig {
}
/**
+ * Retrieves the {@link CleanupMode} as given by git config
+ * {@code commit.cleanup}.
+ *
+ * @return the {@link CleanupMode}; {@link CleanupMode#DEFAULT} if the git
+ * config is not set
+ * @since 6.1
+ */
+ @NonNull
+ public CleanupMode getCleanupMode() {
+ return cleanupMode;
+ }
+
+ /**
+ * Computes a non-default {@link CleanupMode} from the given mode and the
+ * git config.
+ *
+ * @param mode
+ * {@link CleanupMode} to resolve
+ * @param defaultStrip
+ * if {@code true} return {@link CleanupMode#STRIP} if the git
+ * config is also "default", otherwise return
+ * {@link CleanupMode#WHITESPACE}
+ * @return the {@code mode}, if it is not {@link CleanupMode#DEFAULT},
+ * otherwise the resolved mode, which is never
+ * {@link CleanupMode#DEFAULT}
+ * @since 6.1
+ */
+ @NonNull
+ public CleanupMode resolve(@NonNull CleanupMode mode,
+ boolean defaultStrip) {
+ if (CleanupMode.DEFAULT == mode) {
+ CleanupMode defaultMode = getCleanupMode();
+ if (CleanupMode.DEFAULT == defaultMode) {
+ return defaultStrip ? CleanupMode.STRIP
+ : CleanupMode.WHITESPACE;
+ }
+ return defaultMode;
+ }
+ return mode;
+ }
+
+ /**
* Get the content to the commit template as defined in
* {@code commit.template}. If no {@code i18n.commitEncoding} is specified,
* UTF-8 fallback is used.
@@ -135,4 +233,86 @@ public class CommitConfig {
return commitMessageEncoding;
}
+
+ /**
+ * Processes a text according to the given {@link CleanupMode}.
+ *
+ * @param text
+ * text to process
+ * @param mode
+ * {@link CleanupMode} to use
+ * @param commentChar
+ * comment character (normally {@code #}) to use if {@code mode}
+ * is {@link CleanupMode#STRIP} or {@link CleanupMode#SCISSORS}
+ * @return the processed text
+ * @throws IllegalArgumentException
+ * if {@code mode} is {@link CleanupMode#DEFAULT} (use
+ * {@link #resolve(CleanupMode, boolean)} first)
+ * @since 6.1
+ */
+ public static String cleanText(@NonNull String text,
+ @NonNull CleanupMode mode, char commentChar) {
+ String toProcess = text;
+ boolean strip = false;
+ switch (mode) {
+ case VERBATIM:
+ return text;
+ case SCISSORS:
+ String cut = commentChar + CUT;
+ if (text.startsWith(cut)) {
+ return ""; //$NON-NLS-1$
+ }
+ int cutPos = text.indexOf('\n' + cut);
+ if (cutPos >= 0) {
+ toProcess = text.substring(0, cutPos + 1);
+ }
+ break;
+ case STRIP:
+ strip = true;
+ break;
+ case WHITESPACE:
+ break;
+ case DEFAULT:
+ default:
+ // Internal error; no translation
+ throw new IllegalArgumentException("Invalid clean-up mode " + mode); //$NON-NLS-1$
+ }
+ // WHITESPACE
+ StringBuilder result = new StringBuilder();
+ boolean lastWasEmpty = true;
+ for (String line : toProcess.split("\n")) { //$NON-NLS-1$
+ line = line.stripTrailing();
+ if (line.isEmpty()) {
+ if (!lastWasEmpty) {
+ result.append('\n');
+ lastWasEmpty = true;
+ }
+ } else if (!strip || !isComment(line, commentChar)) {
+ lastWasEmpty = false;
+ result.append(line).append('\n');
+ }
+ }
+ int bufferSize = result.length();
+ if (lastWasEmpty && bufferSize > 0) {
+ bufferSize--;
+ result.setLength(bufferSize);
+ }
+ if (bufferSize > 0 && !toProcess.endsWith("\n")) { //$NON-NLS-1$
+ if (result.charAt(bufferSize - 1) == '\n') {
+ result.setLength(bufferSize - 1);
+ }
+ }
+ return result.toString();
+ }
+
+ private static boolean isComment(String text, char commentChar) {
+ int len = text.length();
+ for (int i = 0; i < len; i++) {
+ char ch = text.charAt(i);
+ if (!Character.isWhitespace(ch)) {
+ return ch == commentChar;
+ }
+ }
+ return false;
+ }
} \ 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 4b21e4be4e..af2b4ccdd1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -182,6 +182,13 @@ public final class ConfigConstants {
public static final String CONFIG_TAG_SECTION = "tag";
/**
+ * The "cleanup" key
+ *
+ * @since 6.1
+ */
+ public static final String CONFIG_KEY_CLEANUP = "cleanup";
+
+ /**
* The "gpgSign" key
*
* @since 5.2