blob: 50d65b6fa83319cc43b263b0e107e20f32e7120f [file] [log] [blame]
/*
* 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;
}
}