From 6e4480835f7688a089f6c018f97333138f64bd87 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Fri, 29 May 2020 22:14:00 +0100
Subject: [PATCH] Fix issue with DiffIndex on initial commit (#11677)

Unfortunately #11614 introduced a bug whereby the initial commit of a
repository could not be seen due to there being no parent commit to
create a clear diff from.

Here we create a diffstat from the difference between the parentless SHA and the SHA of the empty tree - a constant known to git. (With thanks to @L0veSunshine for informing me of this SHA)

Thanks to @a1012112796 for initial attempt to fix.

Fix #11650

Closes #11674

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-Authored-By: L0veSunshine <xuan199651@gmail.com>
---
 modules/git/sha1.go         | 3 +++
 services/gitdiff/gitdiff.go | 8 ++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/modules/git/sha1.go b/modules/git/sha1.go
index bccc94f103..06c8ad14b5 100644
--- a/modules/git/sha1.go
+++ b/modules/git/sha1.go
@@ -17,6 +17,9 @@ import (
 // EmptySHA defines empty git SHA
 const EmptySHA = "0000000000000000000000000000000000000000"
 
+// EmptyTreeSHA is the SHA of an empty tree
+const EmptyTreeSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
+
 // SHAPattern can be used to determine if a string is an valid sha
 var SHAPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`)
 
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index af88ed4d40..02aef70882 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -664,7 +664,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
 	ctx, cancel := context.WithCancel(git.DefaultContext)
 	defer cancel()
 	var cmd *exec.Cmd
-	if len(beforeCommitID) == 0 && commit.ParentCount() == 0 {
+	if (len(beforeCommitID) == 0 || beforeCommitID == git.EmptySHA) && commit.ParentCount() == 0 {
 		cmd = exec.CommandContext(ctx, git.GitExecutable, "show", afterCommitID)
 	} else {
 		actualBeforeCommitID := beforeCommitID
@@ -711,7 +711,11 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
 		return nil, fmt.Errorf("Wait: %v", err)
 	}
 
-	diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(repoPath, beforeCommitID+"..."+afterCommitID)
+	shortstatArgs := []string{beforeCommitID + "..." + afterCommitID}
+	if len(beforeCommitID) == 0 || beforeCommitID == git.EmptySHA {
+		shortstatArgs = []string{git.EmptyTreeSHA, afterCommitID}
+	}
+	diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(repoPath, shortstatArgs...)
 	if err != nil {
 		return nil, err
 	}