@@ -306,9 +306,24 @@ export default class LandingSession extends Session {
306306 const original = runSync ( 'git' , [
307307 'show' , 'HEAD' , '-s' , '--format=%B'
308308 ] ) . trim ( ) ;
309+
310+ // git has very specific rules about what is a trailer and what is not.
311+ // Instead of trying to implement those ourselves, let git parse the
312+ // original commit message and see if it outputs any trailers.
313+ const originalHasTrailers = runSync ( 'git' , [
314+ 'interpret-trailers' , '--parse' , '--no-divider'
315+ ] , {
316+ input : `${ original } \n`
317+ } ) . trim ( ) . length !== 0 ;
318+
309319 const metadata = this . metadata . trim ( ) . split ( '\n' ) ;
310320 const amended = original . split ( '\n' ) ;
311- if ( amended [ amended . length - 1 ] !== '' ) {
321+
322+ // If the original commit message already contains trailers (such as
323+ // "Co-authored-by"), we simply add our own metadata after those. Otherwise,
324+ // we have to add an empty line so that git recognizes our own metadata as
325+ // trailers in the amended commit message.
326+ if ( ! originalHasTrailers ) {
312327 amended . push ( '' ) ;
313328 }
314329
@@ -317,9 +332,13 @@ export default class LandingSession extends Session {
317332 const REVIEW_RE = / R e v i e w e d - B y \s * : \s * ( \S + ) / i;
318333
319334 for ( const line of metadata ) {
320- if ( original . includes ( line ) ) {
321- if ( line ) {
335+ if ( line . length !== 0 && original . includes ( line ) ) {
336+ if ( originalHasTrailers ) {
322337 cli . warn ( `Found ${ line } , skipping..` ) ;
338+ } else {
339+ cli . error ( 'Git found no trailers in the original commit message, ' +
340+ `but '${ line } ' is present and should be a trailer.` ) ;
341+ process . exit ( 1 ) ; // make it work with git rebase -x
323342 }
324343 } else {
325344 if ( line . match ( BACKPORT_RE ) ) {
0 commit comments