code.gitea.io/gitea@v1.22.3/services/repository/init.go (about)

     1  // Copyright 2024 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repository
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"time"
    11  
    12  	repo_model "code.gitea.io/gitea/models/repo"
    13  	user_model "code.gitea.io/gitea/models/user"
    14  	"code.gitea.io/gitea/modules/git"
    15  	"code.gitea.io/gitea/modules/log"
    16  	repo_module "code.gitea.io/gitea/modules/repository"
    17  	"code.gitea.io/gitea/modules/setting"
    18  	asymkey_service "code.gitea.io/gitea/services/asymkey"
    19  )
    20  
    21  // initRepoCommit temporarily changes with work directory.
    22  func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Repository, u *user_model.User, defaultBranch string) (err error) {
    23  	commitTimeStr := time.Now().Format(time.RFC3339)
    24  
    25  	sig := u.NewGitSig()
    26  	// Because this may call hooks we should pass in the environment
    27  	env := append(os.Environ(),
    28  		"GIT_AUTHOR_NAME="+sig.Name,
    29  		"GIT_AUTHOR_EMAIL="+sig.Email,
    30  		"GIT_AUTHOR_DATE="+commitTimeStr,
    31  		"GIT_COMMITTER_DATE="+commitTimeStr,
    32  	)
    33  	committerName := sig.Name
    34  	committerEmail := sig.Email
    35  
    36  	if stdout, _, err := git.NewCommand(ctx, "add", "--all").
    37  		SetDescription(fmt.Sprintf("initRepoCommit (git add): %s", tmpPath)).
    38  		RunStdString(&git.RunOpts{Dir: tmpPath}); err != nil {
    39  		log.Error("git add --all failed: Stdout: %s\nError: %v", stdout, err)
    40  		return fmt.Errorf("git add --all: %w", err)
    41  	}
    42  
    43  	cmd := git.NewCommand(ctx, "commit", "--message=Initial commit").
    44  		AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email)
    45  
    46  	sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u)
    47  	if sign {
    48  		cmd.AddOptionFormat("-S%s", keyID)
    49  
    50  		if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
    51  			// need to set the committer to the KeyID owner
    52  			committerName = signer.Name
    53  			committerEmail = signer.Email
    54  		}
    55  	} else {
    56  		cmd.AddArguments("--no-gpg-sign")
    57  	}
    58  
    59  	env = append(env,
    60  		"GIT_COMMITTER_NAME="+committerName,
    61  		"GIT_COMMITTER_EMAIL="+committerEmail,
    62  	)
    63  
    64  	if stdout, _, err := cmd.
    65  		SetDescription(fmt.Sprintf("initRepoCommit (git commit): %s", tmpPath)).
    66  		RunStdString(&git.RunOpts{Dir: tmpPath, Env: env}); err != nil {
    67  		log.Error("Failed to commit: %v: Stdout: %s\nError: %v", cmd.String(), stdout, err)
    68  		return fmt.Errorf("git commit: %w", err)
    69  	}
    70  
    71  	if len(defaultBranch) == 0 {
    72  		defaultBranch = setting.Repository.DefaultBranch
    73  	}
    74  
    75  	if stdout, _, err := git.NewCommand(ctx, "push", "origin").AddDynamicArguments("HEAD:" + defaultBranch).
    76  		SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)).
    77  		RunStdString(&git.RunOpts{Dir: tmpPath, Env: repo_module.InternalPushingEnvironment(u, repo)}); err != nil {
    78  		log.Error("Failed to push back to HEAD: Stdout: %s\nError: %v", stdout, err)
    79  		return fmt.Errorf("git push: %w", err)
    80  	}
    81  
    82  	return nil
    83  }