mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 09:44:21 +00:00 
			
		
		
		
	Fix IsObjectExist with gogit (#31790)
				
					
				
			Fix #31271. When gogit is enabled, `IsObjectExist` calls `repo.gogitRepo.ResolveRevision`, which is not correct. It's for checking references not objects, it could work with commit hash since it's both a valid reference and a commit object, but it doesn't work with blob objects. So it causes #31271 because it reports that all blob objects do not exist.
This commit is contained in:
		@@ -14,30 +14,35 @@ import (
 | 
				
			|||||||
	"github.com/go-git/go-git/v5/plumbing/storer"
 | 
						"github.com/go-git/go-git/v5/plumbing/storer"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsObjectExist returns true if given reference exists in the repository.
 | 
					// IsObjectExist returns true if the given object exists in the repository.
 | 
				
			||||||
 | 
					// FIXME: Inconsistent behavior with nogogit edition
 | 
				
			||||||
 | 
					// Unlike the implementation of IsObjectExist in nogogit edition, it does not support short hashes here.
 | 
				
			||||||
 | 
					// For example, IsObjectExist("153f451") will return false, but it will return true in nogogit edition.
 | 
				
			||||||
 | 
					// To fix this, the solution could be adding support for short hashes in gogit edition if it's really needed.
 | 
				
			||||||
func (repo *Repository) IsObjectExist(name string) bool {
 | 
					func (repo *Repository) IsObjectExist(name string) bool {
 | 
				
			||||||
	if name == "" {
 | 
						if name == "" {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := repo.gogitRepo.Object(plumbing.AnyObject, plumbing.NewHash(name))
 | 
				
			||||||
 | 
						return err == nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsReferenceExist returns true if given reference exists in the repository.
 | 
				
			||||||
 | 
					// FIXME: Inconsistent behavior with nogogit edition
 | 
				
			||||||
 | 
					// Unlike the implementation of IsObjectExist in nogogit edition, it does not support blob hashes here.
 | 
				
			||||||
 | 
					// For example, IsObjectExist([existing_blob_hash]) will return false, but it will return true in nogogit edition.
 | 
				
			||||||
 | 
					// To fix this, the solution could be refusing to support blob hashes in nogogit edition since a blob hash is not a reference.
 | 
				
			||||||
 | 
					func (repo *Repository) IsReferenceExist(name string) bool {
 | 
				
			||||||
 | 
						if name == "" {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := repo.gogitRepo.ResolveRevision(plumbing.Revision(name))
 | 
						_, err := repo.gogitRepo.ResolveRevision(plumbing.Revision(name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err == nil
 | 
						return err == nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsReferenceExist returns true if given reference exists in the repository.
 | 
					 | 
				
			||||||
func (repo *Repository) IsReferenceExist(name string) bool {
 | 
					 | 
				
			||||||
	if name == "" {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	reference, err := repo.gogitRepo.Reference(plumbing.ReferenceName(name), true)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return reference.Type() != plumbing.InvalidReference
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// IsBranchExist returns true if given branch exists in current repository.
 | 
					// IsBranchExist returns true if given branch exists in current repository.
 | 
				
			||||||
func (repo *Repository) IsBranchExist(name string) bool {
 | 
					func (repo *Repository) IsBranchExist(name string) bool {
 | 
				
			||||||
	if name == "" {
 | 
						if name == "" {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsObjectExist returns true if given reference exists in the repository.
 | 
					// IsObjectExist returns true if the given object exists in the repository.
 | 
				
			||||||
func (repo *Repository) IsObjectExist(name string) bool {
 | 
					func (repo *Repository) IsObjectExist(name string) bool {
 | 
				
			||||||
	if name == "" {
 | 
						if name == "" {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/require"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRepository_GetBranches(t *testing.T) {
 | 
					func TestRepository_GetBranches(t *testing.T) {
 | 
				
			||||||
@@ -94,3 +95,107 @@ func BenchmarkGetRefsBySha(b *testing.B) {
 | 
				
			|||||||
	_, _ = bareRepo5.GetRefsBySha("c83380d7056593c51a699d12b9c00627bd5743e9", "")
 | 
						_, _ = bareRepo5.GetRefsBySha("c83380d7056593c51a699d12b9c00627bd5743e9", "")
 | 
				
			||||||
	_, _ = bareRepo5.GetRefsBySha("58a4bcc53ac13e7ff76127e0fb518b5262bf09af", "")
 | 
						_, _ = bareRepo5.GetRefsBySha("58a4bcc53ac13e7ff76127e0fb518b5262bf09af", "")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRepository_IsObjectExist(t *testing.T) {
 | 
				
			||||||
 | 
						repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
 | 
				
			||||||
 | 
						require.NoError(t, err)
 | 
				
			||||||
 | 
						defer repo.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// FIXME: Inconsistent behavior between gogit and nogogit editions
 | 
				
			||||||
 | 
						// See the comment of IsObjectExist in gogit edition for more details.
 | 
				
			||||||
 | 
						supportShortHash := !isGogit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name string
 | 
				
			||||||
 | 
							arg  string
 | 
				
			||||||
 | 
							want bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "empty",
 | 
				
			||||||
 | 
								arg:  "",
 | 
				
			||||||
 | 
								want: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "branch",
 | 
				
			||||||
 | 
								arg:  "master",
 | 
				
			||||||
 | 
								want: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "commit hash",
 | 
				
			||||||
 | 
								arg:  "ce064814f4a0d337b333e646ece456cd39fab612",
 | 
				
			||||||
 | 
								want: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "short commit hash",
 | 
				
			||||||
 | 
								arg:  "ce06481",
 | 
				
			||||||
 | 
								want: supportShortHash,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "blob hash",
 | 
				
			||||||
 | 
								arg:  "153f451b9ee7fa1da317ab17a127e9fd9d384310",
 | 
				
			||||||
 | 
								want: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "short blob hash",
 | 
				
			||||||
 | 
								arg:  "153f451",
 | 
				
			||||||
 | 
								want: supportShortHash,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								assert.Equal(t, tt.want, repo.IsObjectExist(tt.arg))
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRepository_IsReferenceExist(t *testing.T) {
 | 
				
			||||||
 | 
						repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
 | 
				
			||||||
 | 
						require.NoError(t, err)
 | 
				
			||||||
 | 
						defer repo.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// FIXME: Inconsistent behavior between gogit and nogogit editions
 | 
				
			||||||
 | 
						// See the comment of IsReferenceExist in gogit edition for more details.
 | 
				
			||||||
 | 
						supportBlobHash := !isGogit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name string
 | 
				
			||||||
 | 
							arg  string
 | 
				
			||||||
 | 
							want bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "empty",
 | 
				
			||||||
 | 
								arg:  "",
 | 
				
			||||||
 | 
								want: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "branch",
 | 
				
			||||||
 | 
								arg:  "master",
 | 
				
			||||||
 | 
								want: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "commit hash",
 | 
				
			||||||
 | 
								arg:  "ce064814f4a0d337b333e646ece456cd39fab612",
 | 
				
			||||||
 | 
								want: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "short commit hash",
 | 
				
			||||||
 | 
								arg:  "ce06481",
 | 
				
			||||||
 | 
								want: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "blob hash",
 | 
				
			||||||
 | 
								arg:  "153f451b9ee7fa1da317ab17a127e9fd9d384310",
 | 
				
			||||||
 | 
								want: supportBlobHash,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "short blob hash",
 | 
				
			||||||
 | 
								arg:  "153f451",
 | 
				
			||||||
 | 
								want: supportBlobHash,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								assert.Equal(t, tt.want, repo.IsReferenceExist(tt.arg))
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1144,7 +1144,8 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
 | 
				
			|||||||
				})
 | 
									})
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			exist = ctx.GitRepo.IsObjectExist(hash)
 | 
								// Don't use IsObjectExist since it doesn't support short hashs with gogit edition.
 | 
				
			||||||
 | 
								exist = ctx.GitRepo.IsReferenceExist(hash)
 | 
				
			||||||
			ctx.ShaExistCache[hash] = exist
 | 
								ctx.ShaExistCache[hash] = exist
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user