Skip to content

Commit

Permalink
Only write to global gitconfig if necessary (go-gitea#11876)
Browse files Browse the repository at this point in the history
* Only write to global gitconfig if necessary

Fix go-gitea#11855

Signed-off-by: Andrew Thornton <[email protected]>

* placate lint

Signed-off-by: Andrew Thornton <[email protected]>

Co-authored-by: techknowlogick <[email protected]>
  • Loading branch information
2 people authored and Yohann Delafollye committed Jul 31, 2020
1 parent 38642fc commit 4d7e78e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 25 deletions.
62 changes: 38 additions & 24 deletions modules/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,44 +108,58 @@ func SetExecutablePath(path string) error {
// Init initializes git module
func Init(ctx context.Context) error {
DefaultContext = ctx
// Git requires setting user.name and user.email in order to commit changes.
// Git requires setting user.name and user.email in order to commit changes - if they're not set just add some defaults
for configKey, defaultValue := range map[string]string{"user.name": "Gitea", "user.email": "[email protected]"} {
if stdout, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", configKey); err != nil || strings.TrimSpace(stdout) == "" {
// ExitError indicates this config is not set
if _, ok := err.(*exec.ExitError); ok || strings.TrimSpace(stdout) == "" {
if _, stderr, gerr := process.GetManager().Exec("git.Init(set "+configKey+")", "git", "config", "--global", configKey, defaultValue); gerr != nil {
return fmt.Errorf("Failed to set git %s(%s): %s", configKey, gerr, stderr)
}
} else {
return fmt.Errorf("Failed to get git %s(%s): %s", configKey, err, stderr)
}
if err := checkAndSetConfig(configKey, defaultValue, false); err != nil {
return err
}
}

// Set git some configurations.
if _, stderr, err := process.GetManager().Exec("git.Init(git config --global core.quotepath false)",
GitExecutable, "config", "--global", "core.quotepath", "false"); err != nil {
return fmt.Errorf("Failed to execute 'git config --global core.quotepath false': %s", stderr)
// Set git some configurations - these must be set to these values for gitea to work correctly
if err := checkAndSetConfig("core.quotePath", "false", true); err != nil {
return err
}

if version.Compare(gitVersion, "2.18", ">=") {
if _, stderr, err := process.GetManager().Exec("git.Init(git config --global core.commitGraph true)",
GitExecutable, "config", "--global", "core.commitGraph", "true"); err != nil {
return fmt.Errorf("Failed to execute 'git config --global core.commitGraph true': %s", stderr)
if err := checkAndSetConfig("core.commitGraph", "true", true); err != nil {
return err
}

if _, stderr, err := process.GetManager().Exec("git.Init(git config --global gc.writeCommitGraph true)",
GitExecutable, "config", "--global", "gc.writeCommitGraph", "true"); err != nil {
return fmt.Errorf("Failed to execute 'git config --global gc.writeCommitGraph true': %s", stderr)
if err := checkAndSetConfig("gc.writeCommitGraph", "true", true); err != nil {
return err
}
}

if runtime.GOOS == "windows" {
if _, stderr, err := process.GetManager().Exec("git.Init(git config --global core.longpaths true)",
GitExecutable, "config", "--global", "core.longpaths", "true"); err != nil {
return fmt.Errorf("Failed to execute 'git config --global core.longpaths true': %s", stderr)
if err := checkAndSetConfig("core.longpaths", "true", true); err != nil {
return err
}
}
return nil
}

func checkAndSetConfig(key, defaultValue string, forceToDefault bool) error {
stdout, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", key)
if err != nil {
perr, ok := err.(*process.Error)
if !ok {
return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr)
}
eerr, ok := perr.Err.(*exec.ExitError)
if !ok || eerr.ExitCode() != 1 {
return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr)
}
}

currValue := strings.TrimSpace(stdout)

if currValue == defaultValue || (!forceToDefault && len(currValue) > 0) {
return nil
}

if _, stderr, err = process.GetManager().Exec(fmt.Sprintf("git.Init(set %s)", key), "git", "config", "--global", key, defaultValue); err != nil {
return fmt.Errorf("Failed to set git %s(%s): %s", key, err, stderr)
}

return nil
}

Expand Down
28 changes: 27 additions & 1 deletion modules/process/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,14 @@ func (pm *Manager) ExecDirEnvStdIn(timeout time.Duration, dir, desc string, env
pm.Remove(pid)

if err != nil {
err = fmt.Errorf("exec(%d:%s) failed: %v(%v) stdout: %v stderr: %v", pid, desc, err, ctx.Err(), stdOut, stdErr)
err = &Error{
PID: pid,
Description: desc,
Err: err,
CtxErr: ctx.Err(),
Stdout: stdOut.String(),
Stderr: stdErr.String(),
}
}

return stdOut.String(), stdErr.String(), err
Expand All @@ -176,3 +183,22 @@ func (l processList) Less(i, j int) bool {
func (l processList) Swap(i, j int) {
l[i], l[j] = l[j], l[i]
}

// Error is a wrapped error describing the error results of Process Execution
type Error struct {
PID int64
Description string
Err error
CtxErr error
Stdout string
Stderr string
}

func (err *Error) Error() string {
return fmt.Sprintf("exec(%d:%s) failed: %v(%v) stdout: %s stderr: %s", err.PID, err.Description, err.Err, err.CtxErr, err.Stdout, err.Stderr)
}

// Unwrap implements the unwrappable implicit interface for go1.13 Unwrap()
func (err *Error) Unwrap() error {
return err.Err
}

0 comments on commit 4d7e78e

Please sign in to comment.