@@ -381,38 +381,103 @@ func (self *MergeAndRebaseHelper) MergeRefIntoCheckedOutBranch(refName string) e
381381 return errors .New (self .c .Tr .CantMergeBranchIntoItself )
382382 }
383383
384+ wantFastForward , wantNonFastForward := self .fastForwardMergeUserPreference ()
385+ canFastForward := self .c .Git ().Branch .CanDoFastForwardMerge (refName )
386+
387+ var firstRegularMergeItem * types.MenuItem
388+ var secondRegularMergeItem * types.MenuItem
389+ var fastForwardMergeItem * types.MenuItem
390+
391+ if ! wantNonFastForward && (wantFastForward || canFastForward ) {
392+ firstRegularMergeItem = & types.MenuItem {
393+ Label : self .c .Tr .RegularMergeFastForward ,
394+ OnPress : self .RegularMerge (refName , git_commands .MERGE_VARIANT_REGULAR ),
395+ Key : 'm' ,
396+ Tooltip : utils .ResolvePlaceholderString (
397+ self .c .Tr .RegularMergeFastForwardTooltip ,
398+ map [string ]string {
399+ "checkedOutBranch" : checkedOutBranchName ,
400+ "selectedBranch" : refName ,
401+ },
402+ ),
403+ }
404+ fastForwardMergeItem = firstRegularMergeItem
405+
406+ secondRegularMergeItem = & types.MenuItem {
407+ Label : self .c .Tr .RegularMergeNonFastForward ,
408+ OnPress : self .RegularMerge (refName , git_commands .MERGE_VARIANT_NON_FAST_FORWARD ),
409+ Key : 'n' ,
410+ Tooltip : utils .ResolvePlaceholderString (
411+ self .c .Tr .RegularMergeNonFastForwardTooltip ,
412+ map [string ]string {
413+ "checkedOutBranch" : checkedOutBranchName ,
414+ "selectedBranch" : refName ,
415+ },
416+ ),
417+ }
418+ } else {
419+ firstRegularMergeItem = & types.MenuItem {
420+ Label : self .c .Tr .RegularMergeNonFastForward ,
421+ OnPress : self .RegularMerge (refName , git_commands .MERGE_VARIANT_REGULAR ),
422+ Key : 'm' ,
423+ Tooltip : utils .ResolvePlaceholderString (
424+ self .c .Tr .RegularMergeNonFastForwardTooltip ,
425+ map [string ]string {
426+ "checkedOutBranch" : checkedOutBranchName ,
427+ "selectedBranch" : refName ,
428+ },
429+ ),
430+ }
431+
432+ secondRegularMergeItem = & types.MenuItem {
433+ Label : self .c .Tr .RegularMergeFastForward ,
434+ OnPress : self .RegularMerge (refName , git_commands .MERGE_VARIANT_FAST_FORWARD ),
435+ Key : 'f' ,
436+ Tooltip : utils .ResolvePlaceholderString (
437+ self .c .Tr .RegularMergeFastForwardTooltip ,
438+ map [string ]string {
439+ "checkedOutBranch" : checkedOutBranchName ,
440+ "selectedBranch" : refName ,
441+ },
442+ ),
443+ }
444+ fastForwardMergeItem = secondRegularMergeItem
445+ }
446+
447+ if ! canFastForward {
448+ fastForwardMergeItem .DisabledReason = & types.DisabledReason {
449+ Text : utils .ResolvePlaceholderString (
450+ self .c .Tr .CannotFastForwardMerge ,
451+ map [string ]string {
452+ "checkedOutBranch" : checkedOutBranchName ,
453+ "selectedBranch" : refName ,
454+ },
455+ ),
456+ }
457+ }
458+
384459 return self .c .Menu (types.CreateMenuOptions {
385460 Title : self .c .Tr .Merge ,
386461 Items : []* types.MenuItem {
462+ firstRegularMergeItem ,
463+ secondRegularMergeItem ,
387464 {
388- Label : self .c .Tr .RegularMerge ,
389- OnPress : self .RegularMerge (refName ),
390- Key : 'm' ,
391- Tooltip : utils .ResolvePlaceholderString (
392- self .c .Tr .RegularMergeTooltip ,
393- map [string ]string {
394- "checkedOutBranch" : checkedOutBranchName ,
395- "selectedBranch" : refName ,
396- },
397- ),
398- },
399- {
400- Label : self .c .Tr .SquashMergeUncommittedTitle ,
465+ Label : self .c .Tr .SquashMergeUncommitted ,
401466 OnPress : self .SquashMergeUncommitted (refName ),
402467 Key : 's' ,
403468 Tooltip : utils .ResolvePlaceholderString (
404- self .c .Tr .SquashMergeUncommitted ,
469+ self .c .Tr .SquashMergeUncommittedTooltip ,
405470 map [string ]string {
406471 "selectedBranch" : refName ,
407472 },
408473 ),
409474 },
410475 {
411- Label : self .c .Tr .SquashMergeCommittedTitle ,
476+ Label : self .c .Tr .SquashMergeCommitted ,
412477 OnPress : self .SquashMergeCommitted (refName , checkedOutBranchName ),
413478 Key : 'S' ,
414479 Tooltip : utils .ResolvePlaceholderString (
415- self .c .Tr .SquashMergeCommitted ,
480+ self .c .Tr .SquashMergeCommittedTooltip ,
416481 map [string ]string {
417482 "checkedOutBranch" : checkedOutBranchName ,
418483 "selectedBranch" : refName ,
@@ -423,26 +488,26 @@ func (self *MergeAndRebaseHelper) MergeRefIntoCheckedOutBranch(refName string) e
423488 })
424489}
425490
426- func (self * MergeAndRebaseHelper ) RegularMerge (refName string ) func () error {
491+ func (self * MergeAndRebaseHelper ) RegularMerge (refName string , variant git_commands. MergeVariant ) func () error {
427492 return func () error {
428493 self .c .LogAction (self .c .Tr .Actions .Merge )
429- err := self .c .Git ().Branch .Merge (refName , git_commands. MergeOpts {} )
494+ err := self .c .Git ().Branch .Merge (refName , variant )
430495 return self .CheckMergeOrRebase (err )
431496 }
432497}
433498
434499func (self * MergeAndRebaseHelper ) SquashMergeUncommitted (refName string ) func () error {
435500 return func () error {
436501 self .c .LogAction (self .c .Tr .Actions .SquashMerge )
437- err := self .c .Git ().Branch .Merge (refName , git_commands.MergeOpts { Squash : true } )
502+ err := self .c .Git ().Branch .Merge (refName , git_commands .MERGE_VARIANT_SQUASH )
438503 return self .CheckMergeOrRebase (err )
439504 }
440505}
441506
442507func (self * MergeAndRebaseHelper ) SquashMergeCommitted (refName , checkedOutBranchName string ) func () error {
443508 return func () error {
444509 self .c .LogAction (self .c .Tr .Actions .SquashMerge )
445- err := self .c .Git ().Branch .Merge (refName , git_commands.MergeOpts { Squash : true } )
510+ err := self .c .Git ().Branch .Merge (refName , git_commands .MERGE_VARIANT_SQUASH )
446511 if err = self .CheckMergeOrRebase (err ); err != nil {
447512 return err
448513 }
@@ -459,6 +524,31 @@ func (self *MergeAndRebaseHelper) SquashMergeCommitted(refName, checkedOutBranch
459524 }
460525}
461526
527+ // Returns wantsFastForward, wantsNonFastForward. These will never both be true, but they can both be false.
528+ func (self * MergeAndRebaseHelper ) fastForwardMergeUserPreference () (bool , bool ) {
529+ // Check user config first, because it takes precedence over git config
530+ mergingArgs := self .c .UserConfig ().Git .Merging .Args
531+ if strings .Contains (mergingArgs , "--ff" ) { // also covers "--ff-only"
532+ return true , false
533+ }
534+
535+ if strings .Contains (mergingArgs , "--no-ff" ) {
536+ return false , true
537+ }
538+
539+ // Then check git config
540+ mergeFfConfig := self .c .Git ().Config .GetMergeFF ()
541+ if mergeFfConfig == "true" || mergeFfConfig == "only" {
542+ return true , false
543+ }
544+
545+ if mergeFfConfig == "false" {
546+ return false , true
547+ }
548+
549+ return false , false
550+ }
551+
462552func (self * MergeAndRebaseHelper ) ResetMarkedBaseCommit () error {
463553 self .c .Modes ().MarkedBaseCommit .Reset ()
464554 self .c .PostRefreshUpdate (self .c .Contexts ().LocalCommits )
0 commit comments