As mentioned by @NickD in the comments, adding the below line to my init.el solved the issue,
(add-to-list 'exec-path "C:/Program Files/Git/usr/bin/")
I also had the following earlier (this allows M-x diff to work),
(setenv "PATH" (concat "C:/Program Files/Git/usr/bin/" path-separator (getenv "PATH")))
EDIT based on questions from @phils:
@phils raised a valid question that exec-path is derived from the PATH environment variable. So, I investigated this further,
When I put the following in the batch file,
set PATH="C:\Program Files\Git\usr\bin\";%PATH% D:\Programs\emacs-29.3\bin\emacs.exe -Q
Both variables diff-command and ediff-diff-program showed the value as diff.
However, M-x diff worked but M-x ediff failed with ediff-exec-process: Searching for program: No such file or directory, diff error
The variable exec-path value showed the following (trimmed the additional directory paths),
("\"C:/Program Files/Git/usr/bin/\"" "C:/Program Files/Python312/Scripts/" "C:/Program Files/Python312/" "D:/Programs/jdk-11.0.2/bin"...
Here you can see that the double quotes in the path are preserved.
The M-x getenv followed by PATH gave (trimmed later dir paths),
"C:\Program Files\Git\usr\bin\";C:\Program Files\Python312\Scripts\;C:\Program Files\Python312\;D:\Programs\jdk-11.0.2\bin;...
When I used a directory name without spaces in the PATH things started working smoothly.
Here is the modified batch file,
set PATH=d:\Programs\cygwin64\bin;%PATH% D:\Programs\emacs-29.3\bin\emacs.exe -Q
Now I got exec-path value as,
("d:/Programs/cygwin64/bin" "C:/Program Files/Python312/Scripts/" "C:/Program Files/Python312/" "D:/Programs/jdk-11.0.2/bin" ...
The program M-x ediff too started working without issues.
Summary: If you have spaces in the directory name, you need to use the double quotes to set PATH properly. But this breaks the exec-path behavior in Windows.
EDIT2: Based on the link given in the comments, double quotes in the path are not necessary. So, M-x ediff should work with the below batch file.
set PATH=C:\Program Files\Git\usr\bin\;%PATH% D:\Programs\emacs-29.3\bin\emacs.exe -Q
exec-pathas well. That's what used for subprocesses.set PATH=...actually export the variable to the environment inherited by subsequent commands? In sh/bash one would need toexport PATHexplicitly. Under GNU/Linux Emacs initialisesexec-pathbased on the inheritedPATH, so either Windows is different (entirely possible), or else you're perhaps not testing what you thought you were testing?SETcommand documentation saysChanges made with SET will remain only for the duration of the current CMD session. I confirmed that Emacs inherits it. I will add more analysis in my answer. It is too difficult to mention everything in this comment. In short, the space in the directory name is spoiling things.