aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommitMessageProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommitMessageProvider.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommitMessageProvider.java72
1 files changed, 72 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommitMessageProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommitMessageProvider.java
new file mode 100644
index 0000000000..50d65b6fa8
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommitMessageProvider.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2023 Dmitrii Naumenko <dmitrii.naumenko@jetbrains.com>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is aailable at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.api;
+
+import java.util.List;
+
+import org.eclipse.jgit.revwalk.FooterLine;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+/**
+ * The interface is used to construct a cherry-picked commit message based on
+ * the original commit
+ *
+ * @see #ORIGINAL
+ * @see #ORIGINAL_WITH_REFERENCE
+ * @since 6.9
+ */
+public interface CherryPickCommitMessageProvider {
+
+ /**
+ * This provider returns the original commit message
+ */
+ static final CherryPickCommitMessageProvider ORIGINAL = RevCommit::getFullMessage;
+
+ /**
+ * This provider returns the original commit message with original commit
+ * hash in SHA-1 form.<br>
+ * Example:
+ *
+ * <pre>
+ * <code>my original commit message
+ *
+ * (cherry picked from commit 75355897dc28e9975afed028c1a6d8c6b97b2a3c)</code>
+ * </pre>
+ *
+ * This is similar to <code>-x</code> flag in git-scm (see <a href=
+ * "https://git-scm.com/docs/git-cherry-pick#_options">https://git-scm.com/docs/git-cherry-pick#_options</a>)
+ */
+ static final CherryPickCommitMessageProvider ORIGINAL_WITH_REFERENCE = srcCommit -> {
+ String fullMessage = srcCommit.getFullMessage();
+
+ // Don't add extra new line after footer (aka trailer)
+ // https://stackoverflow.com/questions/70007405/git-log-exclude-cherry-pick-messages-for-trailers
+ // https://lore.kernel.org/git/7vmx136cdc.fsf@alter.siamese.dyndns.org
+ String separator = messageEndsWithFooter(srcCommit) ? "\n" : "\n\n"; //$NON-NLS-1$//$NON-NLS-2$
+ String revisionString = srcCommit.getName();
+ return String.format("%s%s(cherry picked from commit %s)", //$NON-NLS-1$
+ fullMessage, separator, revisionString);
+ };
+
+ /**
+ * @param srcCommit
+ * original cherry-picked commit
+ * @return target cherry-picked commit message
+ */
+ String getCherryPickedCommitMessage(RevCommit srcCommit);
+
+ private static boolean messageEndsWithFooter(RevCommit srcCommit) {
+ byte[] rawBuffer = srcCommit.getRawBuffer();
+ List<FooterLine> footers = srcCommit.getFooterLines();
+ int maxFooterEnd = footers.stream().mapToInt(FooterLine::getEndOffset)
+ .max().orElse(-1);
+ return rawBuffer.length == maxFooterEnd;
+ }
+}