Remove legacy git code (ver < 2.0), fine tune markup tests (#19930)

* clean git support for ver < 2.0

* fine tune tests for markup (which requires git module)

* remove unnecessary comments

* try to fix tests

* try test again

* use const for GitVersionRequired instead of var

* try to fix integration test

* Refactor CheckAttributeReader to make a *git.Repository version

* update document for commit signing with Gitea's internal gitconfig

* update document for commit signing with Gitea's internal gitconfig

Co-authored-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
wxiaoguang 2022-06-16 23:47:44 +08:00 committed by GitHub
parent 70ce051f1a
commit 157b405753
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 178 additions and 226 deletions

View file

@ -308,6 +308,8 @@ func runHookPostReceive(c *cli.Context) error {
ctx, cancel := installSignals() ctx, cancel := installSignals()
defer cancel() defer cancel()
setup("hooks/post-receive.log", c.Bool("debug"))
// First of all run update-server-info no matter what // First of all run update-server-info no matter what
if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil { if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil {
return fmt.Errorf("Failed to call 'git update-server-info': %v", err) return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
@ -318,8 +320,6 @@ func runHookPostReceive(c *cli.Context) error {
return nil return nil
} }
setup("hooks/post-receive.log", c.Bool("debug"))
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
if setting.OnlyAllowPushIfGiteaEnvironmentSet { if setting.OnlyAllowPushIfGiteaEnvironmentSet {
return fail(`Rejecting changes as Gitea environment not set. return fail(`Rejecting changes as Gitea environment not set.

View file

@ -83,8 +83,7 @@ The first option to discuss is the `SIGNING_KEY`. There are three main
options: options:
- `none` - this prevents Gitea from signing any commits - `none` - this prevents Gitea from signing any commits
- `default` - Gitea will default to the key configured within - `default` - Gitea will default to the key configured within `git config`
`git config`
- `KEYID` - Gitea will sign commits with the gpg key with the ID - `KEYID` - Gitea will sign commits with the gpg key with the ID
`KEYID`. In this case you should provide a `SIGNING_NAME` and `KEYID`. In this case you should provide a `SIGNING_NAME` and
`SIGNING_EMAIL` to be displayed for this key. `SIGNING_EMAIL` to be displayed for this key.
@ -98,6 +97,12 @@ repositories, `SIGNING_KEY=default` could be used to provide different
signing keys on a per-repository basis. However, this is clearly not an signing keys on a per-repository basis. However, this is clearly not an
ideal UI and therefore subject to change. ideal UI and therefore subject to change.
**Since 1.17**, Gitea runs git in its own home directory `[repository].ROOT` and uses its own config `{[repository].ROOT}/.gitconfig`.
If you have your own customized git config for Gitea, you should set these configs in system git config (aka `/etc/gitconfig`)
or the Gitea internal git config `{[repository].ROOT}/.gitconfig`.
Related home files for git command (like `.gnupg`) should also be put in Gitea's git home directory `[repository].ROOT`.
### `INITIAL_COMMIT` ### `INITIAL_COMMIT`
This option determines whether Gitea should sign the initial commit This option determines whether Gitea should sign the initial commit
@ -118,7 +123,7 @@ The possible values are:
- `never`: Never sign - `never`: Never sign
- `pubkey`: Only sign if the user has a public key - `pubkey`: Only sign if the user has a public key
- `twofa`: Only sign if the user logs in with two factor authentication - `twofa`: Only sign if the user logs in with two-factor authentication
- `parentsigned`: Only sign if the parent commit is signed. - `parentsigned`: Only sign if the parent commit is signed.
- `always`: Always sign - `always`: Always sign
@ -132,7 +137,7 @@ editor or API CRUD actions. The possible values are:
- `never`: Never sign - `never`: Never sign
- `pubkey`: Only sign if the user has a public key - `pubkey`: Only sign if the user has a public key
- `twofa`: Only sign if the user logs in with two factor authentication - `twofa`: Only sign if the user logs in with two-factor authentication
- `parentsigned`: Only sign if the parent commit is signed. - `parentsigned`: Only sign if the parent commit is signed.
- `always`: Always sign - `always`: Always sign
@ -146,7 +151,7 @@ The possible options are:
- `never`: Never sign - `never`: Never sign
- `pubkey`: Only sign if the user has a public key - `pubkey`: Only sign if the user has a public key
- `twofa`: Only sign if the user logs in with two factor authentication - `twofa`: Only sign if the user logs in with two-factor authentication
- `basesigned`: Only sign if the parent commit in the base repo is signed. - `basesigned`: Only sign if the parent commit in the base repo is signed.
- `headsigned`: Only sign if the head commit in the head branch is signed. - `headsigned`: Only sign if the head commit in the head branch is signed.
- `commitssigned`: Only sign if all the commits in the head branch to the merge point are signed. - `commitssigned`: Only sign if all the commits in the head branch to the merge point are signed.

View file

@ -174,7 +174,12 @@ func initIntegrationTest() {
setting.LoadForTest() setting.LoadForTest()
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master" setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
_ = util.RemoveAll(repo_module.LocalCopyPath()) _ = util.RemoveAll(repo_module.LocalCopyPath())
if err := git.InitOnceWithSync(context.Background()); err != nil {
log.Fatal("git.InitOnceWithSync: %v", err)
}
git.CheckLFSVersion() git.CheckLFSVersion()
setting.InitDBConfig() setting.InitDBConfig()
if err := storage.Init(); err != nil { if err := storage.Init(); err != nil {
fmt.Printf("Init storage failed: %v", err) fmt.Printf("Init storage failed: %v", err)
@ -275,7 +280,7 @@ func prepareTestEnv(t testing.TB, skip ...int) func() {
assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, unittest.LoadFixtures())
assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
assert.NoError(t, git.InitOnceWithSync(context.Background())) assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
ownerDirs, err := os.ReadDir(setting.RepoRootPath) ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil { if err != nil {
assert.NoError(t, err, "unable to read the new repo root: %v\n", err) assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
@ -576,7 +581,7 @@ func resetFixtures(t *testing.T) {
assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, unittest.LoadFixtures())
assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
assert.NoError(t, git.InitOnceWithSync(context.Background())) assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
ownerDirs, err := os.ReadDir(setting.RepoRootPath) ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil { if err != nil {
assert.NoError(t, err, "unable to read the new repo root: %v\n", err) assert.NoError(t, err, "unable to read the new repo root: %v\n", err)

View file

@ -62,7 +62,6 @@ func initMigrationTest(t *testing.T) func() {
assert.True(t, len(setting.RepoRootPath) != 0) assert.True(t, len(setting.RepoRootPath) != 0)
assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
assert.NoError(t, git.InitOnceWithSync(context.Background()))
ownerDirs, err := os.ReadDir(setting.RepoRootPath) ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil { if err != nil {
assert.NoError(t, err, "unable to read the new repo root: %v\n", err) assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
@ -83,6 +82,7 @@ func initMigrationTest(t *testing.T) func() {
} }
} }
assert.NoError(t, git.InitOnceWithSync(context.Background()))
git.CheckLFSVersion() git.CheckLFSVersion()
setting.InitDBConfig() setting.InitDBConfig()
setting.NewLogServices(true) setting.NewLogServices(true)

View file

@ -66,6 +66,10 @@ func TestMain(m *testing.M) {
setting.SetCustomPathAndConf("", "", "") setting.SetCustomPathAndConf("", "", "")
setting.LoadForTest() setting.LoadForTest()
if err = git.InitOnceWithSync(context.Background()); err != nil {
fmt.Printf("Unable to InitOnceWithSync: %v\n", err)
os.Exit(1)
}
git.CheckLFSVersion() git.CheckLFSVersion()
setting.InitDBConfig() setting.InitDBConfig()
setting.NewLogServices(true) setting.NewLogServices(true)
@ -203,7 +207,7 @@ func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En
deferFn := PrintCurrentTest(t, ourSkip) deferFn := PrintCurrentTest(t, ourSkip)
assert.NoError(t, os.RemoveAll(setting.RepoRootPath)) assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
assert.NoError(t, git.InitOnceWithSync(context.Background())) assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
ownerDirs, err := os.ReadDir(setting.RepoRootPath) ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil { if err != nil {
assert.NoError(t, err, "unable to read the new repo root: %v\n", err) assert.NoError(t, err, "unable to read the new repo root: %v\n", err)

View file

@ -117,9 +117,11 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
if err = CopyDir(filepath.Join(testOpts.GiteaRootPath, "integrations", "gitea-repositories-meta"), setting.RepoRootPath); err != nil { if err = CopyDir(filepath.Join(testOpts.GiteaRootPath, "integrations", "gitea-repositories-meta"), setting.RepoRootPath); err != nil {
fatalTestError("util.CopyDir: %v\n", err) fatalTestError("util.CopyDir: %v\n", err)
} }
if err = git.InitOnceWithSync(context.Background()); err != nil { if err = git.InitOnceWithSync(context.Background()); err != nil {
fatalTestError("git.Init: %v\n", err) fatalTestError("git.Init: %v\n", err)
} }
git.CheckLFSVersion()
ownerDirs, err := os.ReadDir(setting.RepoRootPath) ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil { if err != nil {
@ -202,7 +204,7 @@ func PrepareTestEnv(t testing.TB) {
assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta") metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta")
assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath)) assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
assert.NoError(t, git.InitOnceWithSync(context.Background())) assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
ownerDirs, err := os.ReadDir(setting.RepoRootPath) ownerDirs, err := os.ReadDir(setting.RepoRootPath)
assert.NoError(t, err) assert.NoError(t, err)

View file

@ -206,7 +206,6 @@ func (c *Commit) HasPreviousCommit(commitHash SHA1) (bool, error) {
return false, nil return false, nil
} }
if err := CheckGitVersionAtLeast("1.8"); err == nil {
_, _, err := NewCommand(c.repo.Ctx, "merge-base", "--is-ancestor", that, this).RunStdString(&RunOpts{Dir: c.repo.Path}) _, _, err := NewCommand(c.repo.Ctx, "merge-base", "--is-ancestor", that, this).RunStdString(&RunOpts{Dir: c.repo.Path})
if err == nil { if err == nil {
return true, nil return true, nil
@ -220,14 +219,6 @@ func (c *Commit) HasPreviousCommit(commitHash SHA1) (bool, error) {
return false, err return false, err
} }
result, _, err := NewCommand(c.repo.Ctx, "rev-list", "--ancestry-path", "-n1", that+".."+this, "--").RunStdString(&RunOpts{Dir: c.repo.Path})
if err != nil {
return false, err
}
return len(strings.TrimSpace(result)) > 0, nil
}
// CommitsBeforeLimit returns num commits before current revision // CommitsBeforeLimit returns num commits before current revision
func (c *Commit) CommitsBeforeLimit(num int) ([]*Commit, error) { func (c *Commit) CommitsBeforeLimit(num int) ([]*Commit, error) {
return c.repo.getCommitsBeforeLimit(c.ID, num) return c.repo.getCommitsBeforeLimit(c.ID, num)

View file

@ -7,10 +7,10 @@ package git
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
"sync" "sync"
@ -22,20 +22,16 @@ import (
"github.com/hashicorp/go-version" "github.com/hashicorp/go-version"
) )
var (
// GitVersionRequired is the minimum Git version required // GitVersionRequired is the minimum Git version required
// At the moment, all code for git 1.x are not changed, if some users want to test with old git client const GitVersionRequired = "2.0.0"
// or bypass the check, they still have a chance to edit this variable manually.
// If everything works fine, the code for git 1.x could be removed in a separate PR before 1.17 frozen.
GitVersionRequired = "2.0.0"
var (
// GitExecutable is the command name of git // GitExecutable is the command name of git
// Could be updated to an absolute path while initialization // Could be updated to an absolute path while initialization
GitExecutable = "git" GitExecutable = "git"
// DefaultContext is the default context to run git commands in // DefaultContext is the default context to run git commands in, must be initialized by git.InitXxx
// will be overwritten by InitXxx with HammerContext DefaultContext context.Context
DefaultContext = context.Background()
// SupportProcReceive version >= 2.29.0 // SupportProcReceive version >= 2.29.0
SupportProcReceive bool SupportProcReceive bool
@ -128,36 +124,43 @@ func VersionInfo() string {
return fmt.Sprintf(format, args...) return fmt.Sprintf(format, args...)
} }
func checkInit() error {
if setting.RepoRootPath == "" {
return errors.New("can not init Git's HomeDir (RepoRootPath is empty), the setting and git modules are not initialized correctly")
}
if DefaultContext != nil {
log.Warn("git module has been initialized already, duplicate init should be fixed")
}
return nil
}
// HomeDir is the home dir for git to store the global config file used by Gitea internally // HomeDir is the home dir for git to store the global config file used by Gitea internally
func HomeDir() string { func HomeDir() string {
if setting.RepoRootPath == "" { if setting.RepoRootPath == "" {
// TODO: now, some unit test code call the git module directly without initialization, which is incorrect. // strict check, make sure the git module is initialized correctly.
// at the moment, we just use a temp HomeDir to prevent from conflicting with user's git config // attention: when the git module is called in gitea sub-command (serv/hook), the log module is not able to show messages to users.
// in the future, the git module should be initialized first before use. // for example: if there is gitea git hook code calling git.NewCommand before git.InitXxx, the integration test won't show the real failure reasons.
tmpHomeDir := filepath.Join(os.TempDir(), "gitea-temp-home") log.Fatal("can not get Git's HomeDir (RepoRootPath is empty), the setting and git modules are not initialized correctly")
log.Error("Git's HomeDir is empty (RepoRootPath is empty), the git module is not initialized correctly, using a temp HomeDir (%s) temporarily", tmpHomeDir) return ""
return tmpHomeDir
} }
return setting.RepoRootPath return setting.RepoRootPath
} }
// 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 "git serv" sub-command, no data-race // This method doesn't change anything to filesystem. At the moment, it is only used by "git serv" sub-command, no data-race
// However, in integration test, the sub-command function may be called in the current process, so the InitSimple would be called multiple times, too
func InitSimple(ctx context.Context) error { func InitSimple(ctx context.Context) error {
if err := checkInit(); err != nil {
return err
}
DefaultContext = ctx DefaultContext = ctx
if setting.Git.Timeout.Default > 0 { if setting.Git.Timeout.Default > 0 {
defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second
} }
if err := SetExecutablePath(setting.Git.Path); err != nil { return SetExecutablePath(setting.Git.Path)
return err
}
// force cleanup args
globalCommandArgs = []string{}
return nil
} }
var initOnce sync.Once var initOnce sync.Once
@ -166,6 +169,10 @@ var initOnce sync.Once
// This method will update the global variables ONLY ONCE (just like git.CheckLFSVersion -- which is not ideal too), // This method will update the global variables ONLY ONCE (just like git.CheckLFSVersion -- which is not ideal too),
// otherwise there will be data-race problem at the moment. // otherwise there will be data-race problem at the moment.
func InitOnceWithSync(ctx context.Context) (err error) { func InitOnceWithSync(ctx context.Context) (err error) {
if err = checkInit(); err != nil {
return err
}
initOnce.Do(func() { initOnce.Do(func() {
err = InitSimple(ctx) err = InitSimple(ctx)
if err != nil { if err != nil {

View file

@ -30,10 +30,10 @@ type CheckAttributeOpts struct {
func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[string]string, error) { func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[string]string, error) {
env := []string{} env := []string{}
if len(opts.IndexFile) > 0 && CheckGitVersionAtLeast("1.7.8") == nil { if len(opts.IndexFile) > 0 {
env = append(env, "GIT_INDEX_FILE="+opts.IndexFile) env = append(env, "GIT_INDEX_FILE="+opts.IndexFile)
} }
if len(opts.WorkTree) > 0 && CheckGitVersionAtLeast("1.7.8") == nil { if len(opts.WorkTree) > 0 {
env = append(env, "GIT_WORK_TREE="+opts.WorkTree) env = append(env, "GIT_WORK_TREE="+opts.WorkTree)
} }
@ -56,8 +56,7 @@ func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[
} }
} }
// git check-attr --cached first appears in git 1.7.8 if opts.CachedOnly {
if opts.CachedOnly && CheckGitVersionAtLeast("1.7.8") == nil {
cmdArgs = append(cmdArgs, "--cached") cmdArgs = append(cmdArgs, "--cached")
} }
@ -125,12 +124,12 @@ type CheckAttributeReader struct {
func (c *CheckAttributeReader) Init(ctx context.Context) error { func (c *CheckAttributeReader) Init(ctx context.Context) error {
cmdArgs := []string{"check-attr", "--stdin", "-z"} cmdArgs := []string{"check-attr", "--stdin", "-z"}
if len(c.IndexFile) > 0 && CheckGitVersionAtLeast("1.7.8") == nil { if len(c.IndexFile) > 0 {
cmdArgs = append(cmdArgs, "--cached") cmdArgs = append(cmdArgs, "--cached")
c.env = append(c.env, "GIT_INDEX_FILE="+c.IndexFile) c.env = append(c.env, "GIT_INDEX_FILE="+c.IndexFile)
} }
if len(c.WorkTree) > 0 && CheckGitVersionAtLeast("1.7.8") == nil { if len(c.WorkTree) > 0 {
c.env = append(c.env, "GIT_WORK_TREE="+c.WorkTree) c.env = append(c.env, "GIT_WORK_TREE="+c.WorkTree)
} }
@ -160,17 +159,10 @@ func (c *CheckAttributeReader) Init(ctx context.Context) error {
return err return err
} }
if CheckGitVersionAtLeast("1.8.5") == nil {
lw := new(nulSeparatedAttributeWriter) lw := new(nulSeparatedAttributeWriter)
lw.attributes = make(chan attributeTriple, 5) lw.attributes = make(chan attributeTriple, 5)
lw.closed = make(chan struct{}) lw.closed = make(chan struct{})
c.stdOut = lw c.stdOut = lw
} else {
lw := new(lineSeparatedAttributeWriter)
lw.attributes = make(chan attributeTriple, 5)
lw.closed = make(chan struct{})
c.stdOut = lw
}
return nil return nil
} }
@ -400,3 +392,37 @@ func (wr *lineSeparatedAttributeWriter) Close() error {
close(wr.closed) close(wr.closed)
return nil return nil
} }
// Create a check attribute reader for the current repository and provided commit ID
func (repo *Repository) CheckAttributeReader(commitID string) (*CheckAttributeReader, context.CancelFunc) {
indexFilename, worktree, deleteTemporaryFile, err := repo.ReadTreeToTemporaryIndex(commitID)
if err != nil {
return nil, func() {}
}
checker := &CheckAttributeReader{
Attributes: []string{"linguist-vendored", "linguist-generated", "linguist-language", "gitlab-language"},
Repo: repo,
IndexFile: indexFilename,
WorkTree: worktree,
}
ctx, cancel := context.WithCancel(repo.Ctx)
if err := checker.Init(ctx); err != nil {
log.Error("Unable to open checker for %s. Error: %v", commitID, err)
} else {
go func() {
err := checker.Run()
if err != nil && err != ctx.Err() {
log.Error("Unable to open checker for %s. Error: %v", commitID, err)
}
cancel()
}()
}
deferable := func() {
_ = checker.Close()
cancel()
deleteTemporaryFile()
}
return checker, deferable
}

View file

@ -255,17 +255,11 @@ func (repo *Repository) GetDiff(base, head string, w io.Writer) error {
// GetDiffBinary generates and returns patch data between given revisions, including binary diffs. // GetDiffBinary generates and returns patch data between given revisions, including binary diffs.
func (repo *Repository) GetDiffBinary(base, head string, w io.Writer) error { func (repo *Repository) GetDiffBinary(base, head string, w io.Writer) error {
if CheckGitVersionAtLeast("1.7.7") == nil {
return NewCommand(repo.Ctx, "diff", "-p", "--binary", "--histogram", base, head).Run(&RunOpts{ return NewCommand(repo.Ctx, "diff", "-p", "--binary", "--histogram", base, head).Run(&RunOpts{
Dir: repo.Path, Dir: repo.Path,
Stdout: w, Stdout: w,
}) })
} }
return NewCommand(repo.Ctx, "diff", "-p", "--binary", "--patience", base, head).Run(&RunOpts{
Dir: repo.Path,
Stdout: w,
})
}
// GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply` // GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply`
func (repo *Repository) GetPatch(base, head string, w io.Writer) error { func (repo *Repository) GetPatch(base, head string, w io.Writer) error {

View file

@ -8,12 +8,10 @@ package git
import ( import (
"bytes" "bytes"
"context"
"io" "io"
"strings" "strings"
"code.gitea.io/gitea/modules/analyze" "code.gitea.io/gitea/modules/analyze"
"code.gitea.io/gitea/modules/log"
"github.com/go-enry/go-enry/v2" "github.com/go-enry/go-enry/v2"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
@ -43,33 +41,8 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
return nil, err return nil, err
} }
var checker *CheckAttributeReader checker, deferable := repo.CheckAttributeReader(commitID)
defer deferable()
if CheckGitVersionAtLeast("1.7.8") == nil {
indexFilename, workTree, deleteTemporaryFile, err := repo.ReadTreeToTemporaryIndex(commitID)
if err == nil {
defer deleteTemporaryFile()
checker = &CheckAttributeReader{
Attributes: []string{"linguist-vendored", "linguist-generated", "linguist-language", "gitlab-language"},
Repo: repo,
IndexFile: indexFilename,
WorkTree: workTree,
}
ctx, cancel := context.WithCancel(DefaultContext)
if err := checker.Init(ctx); err != nil {
log.Error("Unable to open checker for %s. Error: %v", commitID, err)
} else {
go func() {
err = checker.Run()
if err != nil {
log.Error("Unable to open checker for %s. Error: %v", commitID, err)
cancel()
}
}()
}
defer cancel()
}
}
sizes := make(map[string]int64) sizes := make(map[string]int64)
err = tree.Files().ForEach(func(f *object.File) error { err = tree.Files().ForEach(func(f *object.File) error {

View file

@ -9,7 +9,6 @@ package git
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"context"
"io" "io"
"math" "math"
"strings" "strings"
@ -63,36 +62,8 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
return nil, err return nil, err
} }
var checker *CheckAttributeReader checker, deferable := repo.CheckAttributeReader(commitID)
defer deferable()
if CheckGitVersionAtLeast("1.7.8") == nil {
indexFilename, worktree, deleteTemporaryFile, err := repo.ReadTreeToTemporaryIndex(commitID)
if err == nil {
defer deleteTemporaryFile()
checker = &CheckAttributeReader{
Attributes: []string{"linguist-vendored", "linguist-generated", "linguist-language", "gitlab-language"},
Repo: repo,
IndexFile: indexFilename,
WorkTree: worktree,
}
ctx, cancel := context.WithCancel(repo.Ctx)
if err := checker.Init(ctx); err != nil {
log.Error("Unable to open checker for %s. Error: %v", commitID, err)
} else {
go func() {
err = checker.Run()
if err != nil {
log.Error("Unable to open checker for %s. Error: %v", commitID, err)
cancel()
}
}()
}
defer func() {
_ = checker.Close()
cancel()
}()
}
}
contentBuf := bytes.Buffer{} contentBuf := bytes.Buffer{}
var content []byte var content []byte

View file

@ -45,11 +45,11 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt
_, _ = messageBytes.WriteString(opts.Message) _, _ = messageBytes.WriteString(opts.Message)
_, _ = messageBytes.WriteString("\n") _, _ = messageBytes.WriteString("\n")
if CheckGitVersionAtLeast("1.7.9") == nil && (opts.KeyID != "" || opts.AlwaysSign) { if opts.KeyID != "" || opts.AlwaysSign {
cmd.AddArguments(fmt.Sprintf("-S%s", opts.KeyID)) cmd.AddArguments(fmt.Sprintf("-S%s", opts.KeyID))
} }
if CheckGitVersionAtLeast("2.0.0") == nil && opts.NoGPGSign { if opts.NoGPGSign {
cmd.AddArguments("--no-gpg-sign") cmd.AddArguments("--no-gpg-sign")
} }

View file

@ -5,12 +5,14 @@
package markup_test package markup_test
import ( import (
"context"
"io" "io"
"strings" "strings"
"testing" "testing"
"code.gitea.io/gitea/modules/emoji" "code.gitea.io/gitea/modules/emoji"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
. "code.gitea.io/gitea/modules/markup" . "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -25,6 +27,13 @@ var localMetas = map[string]string{
"repoPath": "../../integrations/gitea-repositories-meta/user13/repo11.git/", "repoPath": "../../integrations/gitea-repositories-meta/user13/repo11.git/",
} }
func TestMain(m *testing.M) {
setting.LoadAllowEmpty()
if err := git.InitSimple(context.Background()); err != nil {
log.Fatal("git init failed, err: %v", err)
}
}
func TestRender_Commits(t *testing.T) { func TestRender_Commits(t *testing.T) {
setting.AppURL = TestAppURL setting.AppURL = TestAppURL
test := func(input, expected string) { test := func(input, expected string) {

View file

@ -5,6 +5,7 @@
package markdown_test package markdown_test
import ( import (
"context"
"strings" "strings"
"testing" "testing"
@ -31,6 +32,13 @@ var localMetas = map[string]string{
"repoPath": "../../../integrations/gitea-repositories-meta/user13/repo11.git/", "repoPath": "../../../integrations/gitea-repositories-meta/user13/repo11.git/",
} }
func TestMain(m *testing.M) {
setting.LoadAllowEmpty()
if err := git.InitSimple(context.Background()); err != nil {
log.Fatal("git init failed, err: %v", err)
}
}
func TestRender_StandardLinks(t *testing.T) { func TestRender_StandardLinks(t *testing.T) {
setting.AppURL = AppURL setting.AppURL = AppURL
setting.AppSubURL = AppSubURL setting.AppSubURL = AppSubURL

View file

@ -323,7 +323,6 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
"-m", "Initial commit", "-m", "Initial commit",
} }
if git.CheckGitVersionAtLeast("1.7.9") == nil {
sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u) sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u)
if sign { if sign {
args = append(args, "-S"+keyID) args = append(args, "-S"+keyID)
@ -333,10 +332,9 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
committerName = signer.Name committerName = signer.Name
committerEmail = signer.Email committerEmail = signer.Email
} }
} else if git.CheckGitVersionAtLeast("2.0.0") == nil { } else {
args = append(args, "--no-gpg-sign") args = append(args, "--no-gpg-sign")
} }
}
env = append(env, env = append(env,
"GIT_COMMITTER_NAME="+committerName, "GIT_COMMITTER_NAME="+committerName,

View file

@ -1417,37 +1417,8 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff
} }
diff.Start = opts.SkipTo diff.Start = opts.SkipTo
var checker *git.CheckAttributeReader checker, deferable := gitRepo.CheckAttributeReader(opts.AfterCommitID)
defer deferable()
if git.CheckGitVersionAtLeast("1.7.8") == nil {
indexFilename, worktree, deleteTemporaryFile, err := gitRepo.ReadTreeToTemporaryIndex(opts.AfterCommitID)
if err == nil {
defer deleteTemporaryFile()
checker = &git.CheckAttributeReader{
Attributes: []string{"linguist-vendored", "linguist-generated", "linguist-language", "gitlab-language"},
Repo: gitRepo,
IndexFile: indexFilename,
WorkTree: worktree,
}
ctx, cancel := context.WithCancel(gitRepo.Ctx)
if err := checker.Init(ctx); err != nil {
log.Error("Unable to open checker for %s. Error: %v", opts.AfterCommitID, err)
} else {
go func() {
err := checker.Run()
if err != nil && err != ctx.Err() {
log.Error("Unable to open checker for %s. Error: %v", opts.AfterCommitID, err)
}
cancel()
}()
}
defer func() {
_ = checker.Close()
cancel()
}()
}
}
for _, diffFile := range diff.Files { for _, diffFile := range diff.Files {

View file

@ -276,16 +276,9 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode
return "", fmt.Errorf("Unable to write .git/info/sparse-checkout file in tmpBasePath: %v", err) return "", fmt.Errorf("Unable to write .git/info/sparse-checkout file in tmpBasePath: %v", err)
} }
var gitConfigCommand func() *git.Command gitConfigCommand := func() *git.Command {
if git.CheckGitVersionAtLeast("1.8.0") == nil {
gitConfigCommand = func() *git.Command {
return git.NewCommand(ctx, "config", "--local") return git.NewCommand(ctx, "config", "--local")
} }
} else {
gitConfigCommand = func() *git.Command {
return git.NewCommand(ctx, "config")
}
}
// Switch off LFS process (set required, clean and smudge here also) // Switch off LFS process (set required, clean and smudge here also)
if err := gitConfigCommand().AddArguments("filter.lfs.process", ""). if err := gitConfigCommand().AddArguments("filter.lfs.process", "").
@ -366,17 +359,15 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode
// Determine if we should sign // Determine if we should sign
signArg := "" signArg := ""
if git.CheckGitVersionAtLeast("1.7.9") == nil {
sign, keyID, signer, _ := asymkey_service.SignMerge(ctx, pr, doer, tmpBasePath, "HEAD", trackingBranch) sign, keyID, signer, _ := asymkey_service.SignMerge(ctx, pr, doer, tmpBasePath, "HEAD", trackingBranch)
if sign { if sign {
signArg = "-S" + keyID signArg = "-S" + keyID
if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
committer = signer committer = signer
} }
} else if git.CheckGitVersionAtLeast("2.0.0") == nil { } else {
signArg = "--no-gpg-sign" signArg = "--no-gpg-sign"
} }
}
commitTimeStr := time.Now().Format(time.RFC3339) commitTimeStr := time.Now().Format(time.RFC3339)

View file

@ -248,8 +248,6 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(parent string, author, co
args = []string{"commit-tree", treeHash} args = []string{"commit-tree", treeHash}
} }
// Determine if we should sign
if git.CheckGitVersionAtLeast("1.7.9") == nil {
var sign bool var sign bool
var keyID string var keyID string
var signer *git.Signature var signer *git.Signature
@ -273,10 +271,9 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(parent string, author, co
} }
committerSig = signer committerSig = signer
} }
} else if git.CheckGitVersionAtLeast("2.0.0") == nil { } else {
args = append(args, "--no-gpg-sign") args = append(args, "--no-gpg-sign")
} }
}
if signoff { if signoff {
// Signed-off-by // Signed-off-by