diff --git a/lib/landing_session.js b/lib/landing_session.js index e5115fe..e4478ea 100644 --- a/lib/landing_session.js +++ b/lib/landing_session.js @@ -306,9 +306,24 @@ export default class LandingSession extends Session { const original = runSync('git', [ 'show', 'HEAD', '-s', '--format=%B' ]).trim(); + + // git has very specific rules about what is a trailer and what is not. + // Instead of trying to implement those ourselves, let git parse the + // original commit message and see if it outputs any trailers. + const originalHasTrailers = runSync('git', [ + 'interpret-trailers', '--parse', '--no-divider' + ], { + input: `${original}\n` + }).trim().length !== 0; + const metadata = this.metadata.trim().split('\n'); const amended = original.split('\n'); - if (amended[amended.length - 1] !== '') { + + // If the original commit message already contains trailers (such as + // "Co-authored-by"), we simply add our own metadata after those. Otherwise, + // we have to add an empty line so that git recognizes our own metadata as + // trailers in the amended commit message. + if (!originalHasTrailers) { amended.push(''); } @@ -317,9 +332,13 @@ export default class LandingSession extends Session { const REVIEW_RE = /Reviewed-By\s*:\s*(\S+)/i; for (const line of metadata) { - if (original.includes(line)) { - if (line) { + if (line.length !== 0 && original.includes(line)) { + if (originalHasTrailers) { cli.warn(`Found ${line}, skipping..`); + } else { + cli.error('Git found no trailers in the original commit message, ' + + `but '${line}' is present and should be a trailer.`); + process.exit(1); // make it work with git rebase -x } } else { if (line.match(BACKPORT_RE)) {