Description
Steps to reproduce
- Set the git merge tool, e.g.
git config merge.tool vimdiff3
. - Run
rails app:update
- Select the
m
(merge) option for one of the files.
Expected behavior
Rails launches a configured or default merge tool
Actual behavior
sh: 1: vimdiff3: not found
Rails attempts to read the merge tool from the git configuration, but misinterprets the configuration.
Specifically, it assumes that the value of git config merge.tool
is an executable on the system. However, this isn't the case. In fact, the merge.tool
setting either refers to a command built in to git (there's a list in the git-config
manpage), or to a mergetool.<tool>
block in the git configuration.
By coincidence, some of the tool names are the same as system executables (e.g., vimdiff
), but there are also many builtin commands that don't have a matching system command (e.g., vimdiff1
, vimdiff2
, vimdiff3
, which are all different configurations of vimdiff using different sets of parameters). Even when the git tool name matches a system executable, it's not guaranteed that the system executable will work in the same way when called directly, since the git tool name refers to a script under (on my system) /usr/lib/git-core/mergetools
(or equivalent path), which might at the least add specific parameters to the command to be called.
If the value of merge.tool
is not one of git's builtins then what git would actually run is the value of mergetool.<tool>.cmd
. Here merge.tool
is just an identifier; e.g., I could set merge.tool
to emacs
and then mergetool.emacs.cmd
to emacs --eval '(some complex lisp stuff)'
; trying to run emacs directly would not do anything useful (and again it's not required that this key even match the name of a system command; I could have called that emacsmerge
instead).
System configuration
Rails version: 8.0.2
Ruby version: 3.4.2