Subject: bug#78987: 30.1; Unable to create new Git repository in Dired mode

From: Eli Zaretskii <[email-masked]>
Date: Tue, 15 Jul 2025 15:29:10 +0300

> From: Sean Whitton <[email-masked]>
> Cc: Eli Zaretskii <[email-masked]>,  [email-masked],
>   [email-masked]
> Date: Tue, 15 Jul 2025 10:29:40 +0100
> 
> > Debugger entered--Lisp error: (error "Failed (status 128): git --no-pager
> > diff-index --exit-code -p HEAD -- file")
> >   signal(error ("Failed (status 128): git --no-pager diff-index --exit-code -p
> > HEAD -- file"))
> >   error("Failed (%s): %s" "status 128" "git --no-pager diff-index --exit-code
> > -p HEAD -- file")
> >   vc-do-command("*vc-diff*" 1 "git" ("/tmp/dir/file") "--no-pager"
> > "diff-index" "--exit-code" "-p" "HEAD" nil "--")
> >   vc-git-command("*vc-diff*" 1 ("/tmp/dir/file") "diff-index" "--exit-code"
> > "-p" "HEAD" nil "--")
> >   vc-git-diff(("/tmp/dir/file") nil nil "*vc-diff*" nil)
> >   vc-call-backend(Git diff ("/tmp/dir/file") nil nil "*vc-diff*" nil)
> >   vc-diff-internal(nil (Git ("/tmp/dir/file")) nil nil nil)
> >   vc-diff(nil not-essential (Git ("/tmp/dir/file")))
> >   log-edit-diff-fileset()
> >   log-edit-maybe-show-diff()
> >   log-edit(vc-finish-logentry t ...
> >   vc-log-edit(("/tmp/dir/file") ...
> >   vc-start-logentry(("/tmp/dir/file") nil nil ...
> >   vc-checkin(("/tmp/dir/file") Git nil nil nil nil nil)
> >   vc-next-action(nil)
> >   dired-vc-next-action(nil)
> >   funcall-interactively(dired-vc-next-action nil)
> >   command-execute(dired-vc-next-action)
> >
> > Do you have an idea how to handle an empty repository on the first commit?
> > Or this needs a separate bug report?
> 
> I think this is a bug in vc-git-diff.  Does this fix it:
> 
> --8<---------------cut here---------------start------------->8---
> diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
> index 13696a7a929..afcea8bdda6 100644
> --- a/lisp/vc/vc-git.el
> +++ b/lisp/vc/vc-git.el
> @@ -1818,7 +1818,10 @@ vc-git-diff
>          ;; Diffing against the empty tree.
>          (unless rev1 (setq rev1 "4b825dc642cb6eb9a060e54bf8d69288fbee4904"))
>        (setq command "diff-index")
> -      (unless rev1 (setq rev1 "HEAD")))
> +      (unless rev1
> +        (setq rev1 (if (vc-git--empty-db-p)
> +                       "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
> +                     "HEAD"))))
>      (if vc-git-diff-switches
>          (apply #'vc-git-command (or buffer "*vc-diff*")
>                 (if async 'async 1)
> --8<---------------cut here---------------end--------------->8---

Can we please have a comment there explaining the rationale for using
this literal SHA1?

And please make it a defconst instead of hard-coding it twice.

Thanks.