Make sure git version&feature are always prepared (#30877)
Otherwise there would be more similar issues like #29287
This commit is contained in:
parent
8e8ca6c653
commit
7c613f100e
@ -220,10 +220,7 @@ Gitea or set your environment appropriately.`, "")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
supportProcReceive := false
|
supportProcReceive := git.DefaultFeatures().SupportProcReceive
|
||||||
if git.CheckGitVersionAtLeast("2.29") == nil {
|
|
||||||
supportProcReceive = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
// TODO: support news feeds for wiki
|
// TODO: support news feeds for wiki
|
||||||
@ -497,7 +494,7 @@ Gitea or set your environment appropriately.`, "")
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if git.CheckGitVersionAtLeast("2.29") != nil {
|
if !git.DefaultFeatures().SupportProcReceive {
|
||||||
return fail(ctx, "No proc-receive support", "current git version doesn't support proc-receive.")
|
return fail(ctx, "No proc-receive support", "current git version doesn't support proc-receive.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ func runServ(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(words) < 2 {
|
if len(words) < 2 {
|
||||||
if git.CheckGitVersionAtLeast("2.29") == nil {
|
if git.DefaultFeatures().SupportProcReceive {
|
||||||
// for AGit Flow
|
// for AGit Flow
|
||||||
if cmd == "ssh_info" {
|
if cmd == "ssh_info" {
|
||||||
fmt.Print(`{"type":"gitea","version":1}`)
|
fmt.Print(`{"type":"gitea","version":1}`)
|
||||||
|
@ -132,7 +132,7 @@ func (r *BlameReader) Close() error {
|
|||||||
// CreateBlameReader creates reader for given repository, commit and file
|
// CreateBlameReader creates reader for given repository, commit and file
|
||||||
func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) {
|
func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) {
|
||||||
var ignoreRevsFile *string
|
var ignoreRevsFile *string
|
||||||
if CheckGitVersionAtLeast("2.23") == nil && !bypassBlameIgnore {
|
if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore {
|
||||||
ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit)
|
ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
|
|||||||
// GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only')
|
// GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only')
|
||||||
func (c *Commit) GetBranchName() (string, error) {
|
func (c *Commit) GetBranchName() (string, error) {
|
||||||
cmd := NewCommand(c.repo.Ctx, "name-rev")
|
cmd := NewCommand(c.repo.Ctx, "name-rev")
|
||||||
if CheckGitVersionAtLeast("2.13.0") == nil {
|
if DefaultFeatures().CheckVersionAtLeast("2.13.0") {
|
||||||
cmd.AddArguments("--exclude", "refs/tags/*")
|
cmd.AddArguments("--exclude", "refs/tags/*")
|
||||||
}
|
}
|
||||||
cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String())
|
cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String())
|
||||||
|
@ -22,42 +22,63 @@ import (
|
|||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RequiredVersion is the minimum Git version required
|
const RequiredVersion = "2.0.0" // the minimum Git version required
|
||||||
const RequiredVersion = "2.0.0"
|
|
||||||
|
type Features struct {
|
||||||
|
gitVersion *version.Version
|
||||||
|
|
||||||
|
UsingGogit bool
|
||||||
|
SupportProcReceive bool // >= 2.29
|
||||||
|
SupportHashSha256 bool // >= 2.42, SHA-256 repositories no longer an ‘experimental curiosity’
|
||||||
|
SupportedObjectFormats []ObjectFormat // sha1, sha256
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// GitExecutable is the command name of git
|
GitExecutable = "git" // the command name of git, will be updated to an absolute path during initialization
|
||||||
// Could be updated to an absolute path while initialization
|
DefaultContext context.Context // the default context to run git commands in, must be initialized by git.InitXxx
|
||||||
GitExecutable = "git"
|
defaultFeatures *Features
|
||||||
|
|
||||||
// DefaultContext is the default context to run git commands in, must be initialized by git.InitXxx
|
|
||||||
DefaultContext context.Context
|
|
||||||
|
|
||||||
DefaultFeatures struct {
|
|
||||||
GitVersion *version.Version
|
|
||||||
|
|
||||||
SupportProcReceive bool // >= 2.29
|
|
||||||
SupportHashSha256 bool // >= 2.42, SHA-256 repositories no longer an ‘experimental curiosity’
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// loadGitVersion tries to get the current git version and stores it into a global variable
|
func (f *Features) CheckVersionAtLeast(atLeast string) bool {
|
||||||
func loadGitVersion() error {
|
return f.gitVersion.Compare(version.Must(version.NewVersion(atLeast))) >= 0
|
||||||
// doesn't need RWMutex because it's executed by Init()
|
}
|
||||||
if DefaultFeatures.GitVersion != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// VersionInfo returns git version information
|
||||||
|
func (f *Features) VersionInfo() string {
|
||||||
|
return f.gitVersion.Original()
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultFeatures() *Features {
|
||||||
|
if defaultFeatures == nil {
|
||||||
|
if !setting.IsProd || setting.IsInTesting {
|
||||||
|
log.Warn("git.DefaultFeatures is called before git.InitXxx, initializing with default values")
|
||||||
|
}
|
||||||
|
if err := InitSimple(context.Background()); err != nil {
|
||||||
|
log.Fatal("git.InitSimple failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultFeatures
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadGitVersionFeatures() (*Features, error) {
|
||||||
stdout, _, runErr := NewCommand(DefaultContext, "version").RunStdString(nil)
|
stdout, _, runErr := NewCommand(DefaultContext, "version").RunStdString(nil)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
|
|
||||||
ver, err := parseGitVersionLine(strings.TrimSpace(stdout))
|
ver, err := parseGitVersionLine(strings.TrimSpace(stdout))
|
||||||
if err == nil {
|
if err != nil {
|
||||||
DefaultFeatures.GitVersion = ver
|
return nil, err
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
|
features := &Features{gitVersion: ver, UsingGogit: isGogit}
|
||||||
|
features.SupportProcReceive = features.CheckVersionAtLeast("2.29")
|
||||||
|
features.SupportHashSha256 = features.CheckVersionAtLeast("2.42") && !isGogit
|
||||||
|
features.SupportedObjectFormats = []ObjectFormat{Sha1ObjectFormat}
|
||||||
|
if features.SupportHashSha256 {
|
||||||
|
features.SupportedObjectFormats = append(features.SupportedObjectFormats, Sha256ObjectFormat)
|
||||||
|
}
|
||||||
|
return features, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseGitVersionLine(s string) (*version.Version, error) {
|
func parseGitVersionLine(s string) (*version.Version, error) {
|
||||||
@ -85,56 +106,24 @@ func SetExecutablePath(path string) error {
|
|||||||
return fmt.Errorf("git not found: %w", err)
|
return fmt.Errorf("git not found: %w", err)
|
||||||
}
|
}
|
||||||
GitExecutable = absPath
|
GitExecutable = absPath
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if err = loadGitVersion(); err != nil {
|
func ensureGitVersion() error {
|
||||||
return fmt.Errorf("unable to load git version: %w", err)
|
if !DefaultFeatures().CheckVersionAtLeast(RequiredVersion) {
|
||||||
}
|
|
||||||
|
|
||||||
versionRequired, err := version.NewVersion(RequiredVersion)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if DefaultFeatures.GitVersion.LessThan(versionRequired) {
|
|
||||||
moreHint := "get git: https://git-scm.com/download/"
|
moreHint := "get git: https://git-scm.com/download/"
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
// there are a lot of CentOS/RHEL users using old git, so we add a special hint for them
|
// there are a lot of CentOS/RHEL users using old git, so we add a special hint for them
|
||||||
if _, err = os.Stat("/etc/redhat-release"); err == nil {
|
if _, err := os.Stat("/etc/redhat-release"); err == nil {
|
||||||
// ius.io is the recommended official(git-scm.com) method to install git
|
// ius.io is the recommended official(git-scm.com) method to install git
|
||||||
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
|
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", DefaultFeatures.GitVersion.Original(), RequiredVersion, moreHint)
|
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", DefaultFeatures().gitVersion.Original(), RequiredVersion, moreHint)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = checkGitVersionCompatibility(DefaultFeatures.GitVersion); err != nil {
|
if err := checkGitVersionCompatibility(DefaultFeatures().gitVersion); err != nil {
|
||||||
return fmt.Errorf("installed git version %s has a known compatibility issue with Gitea: %w, please upgrade (or downgrade) git", DefaultFeatures.GitVersion.String(), err)
|
return fmt.Errorf("installed git version %s has a known compatibility issue with Gitea: %w, please upgrade (or downgrade) git", DefaultFeatures().gitVersion.String(), err)
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VersionInfo returns git version information
|
|
||||||
func VersionInfo() string {
|
|
||||||
if DefaultFeatures.GitVersion == nil {
|
|
||||||
return "(git not found)"
|
|
||||||
}
|
|
||||||
format := "%s"
|
|
||||||
args := []any{DefaultFeatures.GitVersion.Original()}
|
|
||||||
// Since git wire protocol has been released from git v2.18
|
|
||||||
if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
|
|
||||||
format += ", Wire Protocol %s Enabled"
|
|
||||||
args = append(args, "Version 2") // for focus color
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkInit() error {
|
|
||||||
if setting.Git.HomePath == "" {
|
|
||||||
return errors.New("unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
|
|
||||||
}
|
|
||||||
if DefaultContext != nil {
|
|
||||||
log.Warn("git module has been initialized already, duplicate init may work but it's better to fix it")
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -154,8 +143,12 @@ func HomeDir() string {
|
|||||||
// InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
|
// InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
|
||||||
// This method doesn't change anything to filesystem. At the moment, it is only used by some Gitea sub-commands.
|
// This method doesn't change anything to filesystem. At the moment, it is only used by some Gitea sub-commands.
|
||||||
func InitSimple(ctx context.Context) error {
|
func InitSimple(ctx context.Context) error {
|
||||||
if err := checkInit(); err != nil {
|
if setting.Git.HomePath == "" {
|
||||||
return err
|
return errors.New("unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
|
||||||
|
}
|
||||||
|
|
||||||
|
if DefaultContext != nil && (!setting.IsProd || setting.IsInTesting) {
|
||||||
|
log.Warn("git module has been initialized already, duplicate init may work but it's better to fix it")
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultContext = ctx
|
DefaultContext = ctx
|
||||||
@ -165,7 +158,24 @@ func InitSimple(ctx context.Context) error {
|
|||||||
defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second
|
defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetExecutablePath(setting.Git.Path)
|
if err := SetExecutablePath(setting.Git.Path); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
defaultFeatures, err = loadGitVersionFeatures()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = ensureGitVersion(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// when git works with gnupg (commit signing), there should be a stable home for gnupg commands
|
||||||
|
if _, ok := os.LookupEnv("GNUPGHOME"); !ok {
|
||||||
|
_ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitFull initializes git module with version check and change global variables, sync gitconfig.
|
// InitFull initializes git module with version check and change global variables, sync gitconfig.
|
||||||
@ -175,30 +185,18 @@ func InitFull(ctx context.Context) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// when git works with gnupg (commit signing), there should be a stable home for gnupg commands
|
|
||||||
if _, ok := os.LookupEnv("GNUPGHOME"); !ok {
|
|
||||||
_ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since git wire protocol has been released from git v2.18
|
// Since git wire protocol has been released from git v2.18
|
||||||
if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
|
if setting.Git.EnableAutoGitWireProtocol && DefaultFeatures().CheckVersionAtLeast("2.18") {
|
||||||
globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
|
globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly disable credential helper, otherwise Git credentials might leak
|
// Explicitly disable credential helper, otherwise Git credentials might leak
|
||||||
if CheckGitVersionAtLeast("2.9") == nil {
|
if DefaultFeatures().CheckVersionAtLeast("2.9") {
|
||||||
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
|
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
|
||||||
}
|
}
|
||||||
DefaultFeatures.SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
|
|
||||||
DefaultFeatures.SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil && !isGogit
|
|
||||||
if DefaultFeatures.SupportHashSha256 {
|
|
||||||
SupportedObjectFormats = append(SupportedObjectFormats, Sha256ObjectFormat)
|
|
||||||
} else {
|
|
||||||
log.Warn("sha256 hash support is disabled - requires Git >= 2.42. Gogit is currently unsupported")
|
|
||||||
}
|
|
||||||
|
|
||||||
if setting.LFS.StartServer {
|
if setting.LFS.StartServer {
|
||||||
if CheckGitVersionAtLeast("2.1.2") != nil {
|
if !DefaultFeatures().CheckVersionAtLeast("2.1.2") {
|
||||||
return errors.New("LFS server support requires Git >= 2.1.2")
|
return errors.New("LFS server support requires Git >= 2.1.2")
|
||||||
}
|
}
|
||||||
globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=", "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
|
globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=", "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
|
||||||
@ -238,13 +236,13 @@ func syncGitConfig() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if CheckGitVersionAtLeast("2.10") == nil {
|
if DefaultFeatures().CheckVersionAtLeast("2.10") {
|
||||||
if err := configSet("receive.advertisePushOptions", "true"); err != nil {
|
if err := configSet("receive.advertisePushOptions", "true"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if CheckGitVersionAtLeast("2.18") == nil {
|
if DefaultFeatures().CheckVersionAtLeast("2.18") {
|
||||||
if err := configSet("core.commitGraph", "true"); err != nil {
|
if err := configSet("core.commitGraph", "true"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -256,7 +254,7 @@ func syncGitConfig() (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if DefaultFeatures.SupportProcReceive {
|
if DefaultFeatures().SupportProcReceive {
|
||||||
// set support for AGit flow
|
// set support for AGit flow
|
||||||
if err := configAddNonExist("receive.procReceiveRefs", "refs/for"); err != nil {
|
if err := configAddNonExist("receive.procReceiveRefs", "refs/for"); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -294,7 +292,7 @@ func syncGitConfig() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// By default partial clones are disabled, enable them from git v2.22
|
// By default partial clones are disabled, enable them from git v2.22
|
||||||
if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
|
if !setting.Git.DisablePartialClone && DefaultFeatures().CheckVersionAtLeast("2.22") {
|
||||||
if err = configSet("uploadpack.allowfilter", "true"); err != nil {
|
if err = configSet("uploadpack.allowfilter", "true"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -309,21 +307,6 @@ func syncGitConfig() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckGitVersionAtLeast check git version is at least the constraint version
|
|
||||||
func CheckGitVersionAtLeast(atLeast string) error {
|
|
||||||
if DefaultFeatures.GitVersion == nil {
|
|
||||||
panic("git module is not initialized") // it shouldn't happen
|
|
||||||
}
|
|
||||||
atLeastVersion, err := version.NewVersion(atLeast)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if DefaultFeatures.GitVersion.Compare(atLeastVersion) < 0 {
|
|
||||||
return fmt.Errorf("installed git binary version %s is not at least %s", DefaultFeatures.GitVersion.Original(), atLeast)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkGitVersionCompatibility(gitVer *version.Version) error {
|
func checkGitVersionCompatibility(gitVer *version.Version) error {
|
||||||
badVersions := []struct {
|
badVersions := []struct {
|
||||||
Version *version.Version
|
Version *version.Version
|
||||||
|
@ -120,12 +120,8 @@ var (
|
|||||||
Sha256ObjectFormat ObjectFormat = Sha256ObjectFormatImpl{}
|
Sha256ObjectFormat ObjectFormat = Sha256ObjectFormatImpl{}
|
||||||
)
|
)
|
||||||
|
|
||||||
var SupportedObjectFormats = []ObjectFormat{
|
|
||||||
Sha1ObjectFormat,
|
|
||||||
}
|
|
||||||
|
|
||||||
func ObjectFormatFromName(name string) ObjectFormat {
|
func ObjectFormatFromName(name string) ObjectFormat {
|
||||||
for _, objectFormat := range SupportedObjectFormats {
|
for _, objectFormat := range DefaultFeatures().SupportedObjectFormats {
|
||||||
if name == objectFormat.Name() {
|
if name == objectFormat.Name() {
|
||||||
return objectFormat
|
return objectFormat
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ func (*Sha256Hash) Type() ObjectFormat { return Sha256ObjectFormat }
|
|||||||
|
|
||||||
func NewIDFromString(hexHash string) (ObjectID, error) {
|
func NewIDFromString(hexHash string) (ObjectID, error) {
|
||||||
var theObjectFormat ObjectFormat
|
var theObjectFormat ObjectFormat
|
||||||
for _, objectFormat := range SupportedObjectFormats {
|
for _, objectFormat := range DefaultFeatures().SupportedObjectFormats {
|
||||||
if len(hexHash) == objectFormat.FullLength() {
|
if len(hexHash) == objectFormat.FullLength() {
|
||||||
theObjectFormat = objectFormat
|
theObjectFormat = objectFormat
|
||||||
break
|
break
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
// GetRemoteAddress returns remote url of git repository in the repoPath with special remote name
|
// GetRemoteAddress returns remote url of git repository in the repoPath with special remote name
|
||||||
func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, error) {
|
func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, error) {
|
||||||
var cmd *Command
|
var cmd *Command
|
||||||
if CheckGitVersionAtLeast("2.7") == nil {
|
if DefaultFeatures().CheckVersionAtLeast("2.7") {
|
||||||
cmd = NewCommand(ctx, "remote", "get-url").AddDynamicArguments(remoteName)
|
cmd = NewCommand(ctx, "remote", "get-url").AddDynamicArguments(remoteName)
|
||||||
} else {
|
} else {
|
||||||
cmd = NewCommand(ctx, "config", "--get").AddDynamicArguments("remote." + remoteName + ".url")
|
cmd = NewCommand(ctx, "config", "--get").AddDynamicArguments("remote." + remoteName + ".url")
|
||||||
|
@ -101,7 +101,7 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma
|
|||||||
if !IsValidObjectFormat(objectFormatName) {
|
if !IsValidObjectFormat(objectFormatName) {
|
||||||
return fmt.Errorf("invalid object format: %s", objectFormatName)
|
return fmt.Errorf("invalid object format: %s", objectFormatName)
|
||||||
}
|
}
|
||||||
if DefaultFeatures.SupportHashSha256 {
|
if DefaultFeatures().SupportHashSha256 {
|
||||||
cmd.AddOptionValues("--object-format", objectFormatName)
|
cmd.AddOptionValues("--object-format", objectFormatName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package git
|
|
||||||
|
|
||||||
var isGogit bool
|
|
@ -22,9 +22,7 @@ import (
|
|||||||
"github.com/go-git/go-git/v5/storage/filesystem"
|
"github.com/go-git/go-git/v5/storage/filesystem"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
const isGogit = true
|
||||||
isGogit = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repository represents a Git repository.
|
// Repository represents a Git repository.
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
|
@ -15,9 +15,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
const isGogit = false
|
||||||
isGogit = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repository represents a Git repository.
|
// Repository represents a Git repository.
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
|
@ -438,7 +438,7 @@ func (repo *Repository) getCommitsBeforeLimit(id ObjectID, num int) ([]*Commit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) getBranches(commit *Commit, limit int) ([]string, error) {
|
func (repo *Repository) getBranches(commit *Commit, limit int) ([]string, error) {
|
||||||
if CheckGitVersionAtLeast("2.7.0") == nil {
|
if DefaultFeatures().CheckVersionAtLeast("2.7.0") {
|
||||||
stdout, _, err := NewCommand(repo.Ctx, "for-each-ref", "--format=%(refname:strip=2)").
|
stdout, _, err := NewCommand(repo.Ctx, "for-each-ref", "--format=%(refname:strip=2)").
|
||||||
AddOptionFormat("--count=%d", limit).
|
AddOptionFormat("--count=%d", limit).
|
||||||
AddOptionValues("--contains", commit.ID.String(), BranchPrefix).
|
AddOptionValues("--contains", commit.ID.String(), BranchPrefix).
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
// WriteCommitGraph write commit graph to speed up repo access
|
// WriteCommitGraph write commit graph to speed up repo access
|
||||||
// this requires git v2.18 to be installed
|
// this requires git v2.18 to be installed
|
||||||
func WriteCommitGraph(ctx context.Context, repoPath string) error {
|
func WriteCommitGraph(ctx context.Context, repoPath string) error {
|
||||||
if CheckGitVersionAtLeast("2.18") == nil {
|
if DefaultFeatures().CheckVersionAtLeast("2.18") {
|
||||||
if _, _, err := NewCommand(ctx, "commit-graph", "write").RunStdString(&RunOpts{Dir: repoPath}); err != nil {
|
if _, _, err := NewCommand(ctx, "commit-graph", "write").RunStdString(&RunOpts{Dir: repoPath}); err != nil {
|
||||||
return fmt.Errorf("unable to write commit-graph for '%s' : %w", repoPath, err)
|
return fmt.Errorf("unable to write commit-graph for '%s' : %w", repoPath, err)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func SearchPointerBlobs(ctx context.Context, repo *git.Repository, pointerChan c
|
|||||||
go pipeline.BlobsLessThan1024FromCatFileBatchCheck(catFileCheckReader, shasToBatchWriter, &wg)
|
go pipeline.BlobsLessThan1024FromCatFileBatchCheck(catFileCheckReader, shasToBatchWriter, &wg)
|
||||||
|
|
||||||
// 1. Run batch-check on all objects in the repository
|
// 1. Run batch-check on all objects in the repository
|
||||||
if git.CheckGitVersionAtLeast("2.6.0") != nil {
|
if !git.DefaultFeatures().CheckVersionAtLeast("2.6.0") {
|
||||||
revListReader, revListWriter := io.Pipe()
|
revListReader, revListWriter := io.Pipe()
|
||||||
shasToCheckReader, shasToCheckWriter := io.Pipe()
|
shasToCheckReader, shasToCheckWriter := io.Pipe()
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/system"
|
"code.gitea.io/gitea/modules/system"
|
||||||
"code.gitea.io/gitea/modules/templates"
|
"code.gitea.io/gitea/modules/templates"
|
||||||
"code.gitea.io/gitea/modules/translation"
|
"code.gitea.io/gitea/modules/translation"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/modules/web"
|
"code.gitea.io/gitea/modules/web"
|
||||||
"code.gitea.io/gitea/modules/web/routing"
|
"code.gitea.io/gitea/modules/web/routing"
|
||||||
actions_router "code.gitea.io/gitea/routers/api/actions"
|
actions_router "code.gitea.io/gitea/routers/api/actions"
|
||||||
@ -112,7 +113,10 @@ func InitWebInstallPage(ctx context.Context) {
|
|||||||
// InitWebInstalled is for global installed configuration.
|
// InitWebInstalled is for global installed configuration.
|
||||||
func InitWebInstalled(ctx context.Context) {
|
func InitWebInstalled(ctx context.Context) {
|
||||||
mustInitCtx(ctx, git.InitFull)
|
mustInitCtx(ctx, git.InitFull)
|
||||||
log.Info("Git version: %s (home: %s)", git.VersionInfo(), git.HomeDir())
|
log.Info("Git version: %s (home: %s)", git.DefaultFeatures().VersionInfo(), git.HomeDir())
|
||||||
|
if !git.DefaultFeatures().SupportHashSha256 {
|
||||||
|
log.Warn("sha256 hash support is disabled - requires Git >= 2.42." + util.Iif(git.DefaultFeatures().UsingGogit, " Gogit is currently unsupported.", ""))
|
||||||
|
}
|
||||||
|
|
||||||
// Setup i18n
|
// Setup i18n
|
||||||
translation.InitLocales(ctx)
|
translation.InitLocales(ctx)
|
||||||
|
@ -122,7 +122,7 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) {
|
|||||||
preReceiveBranch(ourCtx, oldCommitID, newCommitID, refFullName)
|
preReceiveBranch(ourCtx, oldCommitID, newCommitID, refFullName)
|
||||||
case refFullName.IsTag():
|
case refFullName.IsTag():
|
||||||
preReceiveTag(ourCtx, refFullName)
|
preReceiveTag(ourCtx, refFullName)
|
||||||
case git.DefaultFeatures.SupportProcReceive && refFullName.IsFor():
|
case git.DefaultFeatures().SupportProcReceive && refFullName.IsFor():
|
||||||
preReceiveFor(ourCtx, refFullName)
|
preReceiveFor(ourCtx, refFullName)
|
||||||
default:
|
default:
|
||||||
ourCtx.AssertCanWriteCode()
|
ourCtx.AssertCanWriteCode()
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
// HookProcReceive proc-receive hook - only handles agit Proc-Receive requests at present
|
// HookProcReceive proc-receive hook - only handles agit Proc-Receive requests at present
|
||||||
func HookProcReceive(ctx *gitea_context.PrivateContext) {
|
func HookProcReceive(ctx *gitea_context.PrivateContext) {
|
||||||
opts := web.GetForm(ctx).(*private.HookOptions)
|
opts := web.GetForm(ctx).(*private.HookOptions)
|
||||||
if !git.DefaultFeatures.SupportProcReceive {
|
if !git.DefaultFeatures().SupportProcReceive {
|
||||||
ctx.Status(http.StatusNotFound)
|
ctx.Status(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ func ServCommand(ctx *context.PrivateContext) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Because of the special ref "refs/for" we will need to delay write permission check
|
// Because of the special ref "refs/for" we will need to delay write permission check
|
||||||
if git.DefaultFeatures.SupportProcReceive && unitType == unit.TypeCode {
|
if git.DefaultFeatures().SupportProcReceive && unitType == unit.TypeCode {
|
||||||
mode = perm.AccessModeRead
|
mode = perm.AccessModeRead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ func Config(ctx *context.Context) {
|
|||||||
ctx.Data["OfflineMode"] = setting.OfflineMode
|
ctx.Data["OfflineMode"] = setting.OfflineMode
|
||||||
ctx.Data["RunUser"] = setting.RunUser
|
ctx.Data["RunUser"] = setting.RunUser
|
||||||
ctx.Data["RunMode"] = util.ToTitleCase(setting.RunMode)
|
ctx.Data["RunMode"] = util.ToTitleCase(setting.RunMode)
|
||||||
ctx.Data["GitVersion"] = git.VersionInfo()
|
ctx.Data["GitVersion"] = git.DefaultFeatures().VersionInfo()
|
||||||
|
|
||||||
ctx.Data["AppDataPath"] = setting.AppDataPath
|
ctx.Data["AppDataPath"] = setting.AppDataPath
|
||||||
ctx.Data["RepoRootPath"] = setting.RepoRootPath
|
ctx.Data["RepoRootPath"] = setting.RepoRootPath
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SSHInfo(rw http.ResponseWriter, req *http.Request) {
|
func SSHInfo(rw http.ResponseWriter, req *http.Request) {
|
||||||
if !git.DefaultFeatures.SupportProcReceive {
|
if !git.DefaultFeatures().SupportProcReceive {
|
||||||
rw.WriteHeader(http.StatusNotFound)
|
rw.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
|
|||||||
|
|
||||||
if repoExist {
|
if repoExist {
|
||||||
// Because of special ref "refs/for" .. , need delay write permission check
|
// Because of special ref "refs/for" .. , need delay write permission check
|
||||||
if git.DefaultFeatures.SupportProcReceive {
|
if git.DefaultFeatures().SupportProcReceive {
|
||||||
accessMode = perm.AccessModeRead
|
accessMode = perm.AccessModeRead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ func Create(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
|
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
|
||||||
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
|
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
|
||||||
ctx.Data["SupportedObjectFormats"] = git.SupportedObjectFormats
|
ctx.Data["SupportedObjectFormats"] = git.DefaultFeatures().SupportedObjectFormats
|
||||||
ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
|
ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplCreate)
|
ctx.HTML(http.StatusOK, tplCreate)
|
||||||
|
@ -1143,7 +1143,7 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi
|
|||||||
// so if we are using at least this version of git we don't have to tell ParsePatch to do
|
// so if we are using at least this version of git we don't have to tell ParsePatch to do
|
||||||
// the skipping for us
|
// the skipping for us
|
||||||
parsePatchSkipToFile := opts.SkipTo
|
parsePatchSkipToFile := opts.SkipTo
|
||||||
if opts.SkipTo != "" && git.CheckGitVersionAtLeast("2.31") == nil {
|
if opts.SkipTo != "" && git.DefaultFeatures().CheckVersionAtLeast("2.31") {
|
||||||
cmdDiff.AddOptionFormat("--skip-to=%s", opts.SkipTo)
|
cmdDiff.AddOptionFormat("--skip-to=%s", opts.SkipTo)
|
||||||
parsePatchSkipToFile = ""
|
parsePatchSkipToFile = ""
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
|||||||
cmdApply.AddArguments("--ignore-whitespace")
|
cmdApply.AddArguments("--ignore-whitespace")
|
||||||
}
|
}
|
||||||
is3way := false
|
is3way := false
|
||||||
if git.CheckGitVersionAtLeast("2.32.0") == nil {
|
if git.DefaultFeatures().CheckVersionAtLeast("2.32.0") {
|
||||||
cmdApply.AddArguments("--3way")
|
cmdApply.AddArguments("--3way")
|
||||||
is3way = true
|
is3way = true
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
|
|||||||
baseBranch := "base"
|
baseBranch := "base"
|
||||||
|
|
||||||
fetchArgs := git.TrustedCmdArgs{"--no-tags"}
|
fetchArgs := git.TrustedCmdArgs{"--no-tags"}
|
||||||
if git.CheckGitVersionAtLeast("2.25.0") == nil {
|
if git.DefaultFeatures().CheckVersionAtLeast("2.25.0") {
|
||||||
// Writing the commit graph can be slow and is not needed here
|
// Writing the commit graph can be slow and is not needed here
|
||||||
fetchArgs = append(fetchArgs, "--no-write-commit-graph")
|
fetchArgs = append(fetchArgs, "--no-write-commit-graph")
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user
|
|||||||
stderr := &strings.Builder{}
|
stderr := &strings.Builder{}
|
||||||
|
|
||||||
cmdApply := git.NewCommand(ctx, "apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary")
|
cmdApply := git.NewCommand(ctx, "apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary")
|
||||||
if git.CheckGitVersionAtLeast("2.32") == nil {
|
if git.DefaultFeatures().CheckVersionAtLeast("2.32") {
|
||||||
cmdApply.AddArguments("-3")
|
cmdApply.AddArguments("-3")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, headBranch string
|
|||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
// skip this test if git version is low
|
// skip this test if git version is low
|
||||||
if git.CheckGitVersionAtLeast("2.29") != nil {
|
if !git.DefaultFeatures().SupportProcReceive {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user