mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	enhancement: add signoff option in commit form (#14516)
Signed-off-by: a1012112796 <1012112796@qq.com>
This commit is contained in:
		@@ -698,6 +698,7 @@ type EditRepoFileForm struct {
 | 
			
		||||
	CommitChoice  string `binding:"Required;MaxSize(50)"`
 | 
			
		||||
	NewBranchName string `binding:"GitRefName;MaxSize(100)"`
 | 
			
		||||
	LastCommit    string
 | 
			
		||||
	Signoff       bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate validates the fields
 | 
			
		||||
@@ -733,6 +734,7 @@ type UploadRepoFileForm struct {
 | 
			
		||||
	CommitChoice  string `binding:"Required;MaxSize(50)"`
 | 
			
		||||
	NewBranchName string `binding:"GitRefName;MaxSize(100)"`
 | 
			
		||||
	Files         []string
 | 
			
		||||
	Signoff       bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate validates the fields
 | 
			
		||||
@@ -766,6 +768,7 @@ type DeleteRepoFileForm struct {
 | 
			
		||||
	CommitChoice  string `binding:"Required;MaxSize(50)"`
 | 
			
		||||
	NewBranchName string `binding:"GitRefName;MaxSize(100)"`
 | 
			
		||||
	LastCommit    string
 | 
			
		||||
	Signoff       bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate validates the fields
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ type DeleteRepoFileOptions struct {
 | 
			
		||||
	Author       *IdentityOptions
 | 
			
		||||
	Committer    *IdentityOptions
 | 
			
		||||
	Dates        *CommitDateOptions
 | 
			
		||||
	Signoff      bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteRepoFile deletes a file in the given repository
 | 
			
		||||
@@ -199,9 +200,9 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo
 | 
			
		||||
	// Now commit the tree
 | 
			
		||||
	var commitHash string
 | 
			
		||||
	if opts.Dates != nil {
 | 
			
		||||
		commitHash, err = t.CommitTreeWithDate(author, committer, treeHash, message, opts.Dates.Author, opts.Dates.Committer)
 | 
			
		||||
		commitHash, err = t.CommitTreeWithDate(author, committer, treeHash, message, opts.Signoff, opts.Dates.Author, opts.Dates.Committer)
 | 
			
		||||
	} else {
 | 
			
		||||
		commitHash, err = t.CommitTree(author, committer, treeHash, message)
 | 
			
		||||
		commitHash, err = t.CommitTree(author, committer, treeHash, message, opts.Signoff)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
@@ -185,12 +185,12 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ref string) (string, erro
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CommitTree creates a commit from a given tree for the user with provided message
 | 
			
		||||
func (t *TemporaryUploadRepository) CommitTree(author, committer *models.User, treeHash string, message string) (string, error) {
 | 
			
		||||
	return t.CommitTreeWithDate(author, committer, treeHash, message, time.Now(), time.Now())
 | 
			
		||||
func (t *TemporaryUploadRepository) CommitTree(author, committer *models.User, treeHash string, message string, signoff bool) (string, error) {
 | 
			
		||||
	return t.CommitTreeWithDate(author, committer, treeHash, message, signoff, time.Now(), time.Now())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CommitTreeWithDate creates a commit from a given tree for the user with provided message
 | 
			
		||||
func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *models.User, treeHash string, message string, authorDate, committerDate time.Time) (string, error) {
 | 
			
		||||
func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *models.User, treeHash string, message string, signoff bool, authorDate, committerDate time.Time) (string, error) {
 | 
			
		||||
	authorSig := author.NewGitSig()
 | 
			
		||||
	committerSig := committer.NewGitSig()
 | 
			
		||||
 | 
			
		||||
@@ -236,6 +236,13 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *models
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if signoff {
 | 
			
		||||
		// Signed-off-by
 | 
			
		||||
		_, _ = messageBytes.WriteString("\n")
 | 
			
		||||
		_, _ = messageBytes.WriteString("Signed-off-by: ")
 | 
			
		||||
		_, _ = messageBytes.WriteString(committerSig.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	env = append(env,
 | 
			
		||||
		"GIT_COMMITTER_NAME="+committerSig.Name,
 | 
			
		||||
		"GIT_COMMITTER_EMAIL="+committerSig.Email,
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,7 @@ type UpdateRepoFileOptions struct {
 | 
			
		||||
	Author       *IdentityOptions
 | 
			
		||||
	Committer    *IdentityOptions
 | 
			
		||||
	Dates        *CommitDateOptions
 | 
			
		||||
	Signoff      bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func detectEncodingAndBOM(entry *git.TreeEntry, repo *models.Repository) (string, bool) {
 | 
			
		||||
@@ -417,9 +418,9 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
 | 
			
		||||
	// Now commit the tree
 | 
			
		||||
	var commitHash string
 | 
			
		||||
	if opts.Dates != nil {
 | 
			
		||||
		commitHash, err = t.CommitTreeWithDate(author, committer, treeHash, message, opts.Dates.Author, opts.Dates.Committer)
 | 
			
		||||
		commitHash, err = t.CommitTreeWithDate(author, committer, treeHash, message, opts.Signoff, opts.Dates.Author, opts.Dates.Committer)
 | 
			
		||||
	} else {
 | 
			
		||||
		commitHash, err = t.CommitTree(author, committer, treeHash, message)
 | 
			
		||||
		commitHash, err = t.CommitTree(author, committer, treeHash, message, opts.Signoff)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@ type UploadRepoFileOptions struct {
 | 
			
		||||
	TreePath     string
 | 
			
		||||
	Message      string
 | 
			
		||||
	Files        []string // In UUID format.
 | 
			
		||||
	Signoff      bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type uploadInfo struct {
 | 
			
		||||
@@ -143,7 +144,7 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
 | 
			
		||||
	committer := doer
 | 
			
		||||
 | 
			
		||||
	// Now commit the tree
 | 
			
		||||
	commitHash, err := t.CommitTree(author, committer, treeHash, opts.Message)
 | 
			
		||||
	commitHash, err := t.CommitTree(author, committer, treeHash, opts.Message, opts.Signoff)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,8 @@ type FileOptions struct {
 | 
			
		||||
	Author    Identity          `json:"author"`
 | 
			
		||||
	Committer Identity          `json:"committer"`
 | 
			
		||||
	Dates     CommitDateOptions `json:"dates"`
 | 
			
		||||
	// Add a Signed-off-by trailer by the committer at the end of the commit log message.
 | 
			
		||||
	Signoff bool `json:"signoff"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateFileOptions options for creating files
 | 
			
		||||
 
 | 
			
		||||
@@ -874,6 +874,7 @@ editor.add = Add '%s'
 | 
			
		||||
editor.update = Update '%s'
 | 
			
		||||
editor.delete = Delete '%s'
 | 
			
		||||
editor.commit_message_desc = Add an optional extended description…
 | 
			
		||||
editor.signoff_desc = Add a Signed-off-by trailer by the committer at the end of the commit log message.
 | 
			
		||||
editor.commit_directly_to_this_branch = Commit directly to the <strong class="branch-name">%s</strong> branch.
 | 
			
		||||
editor.create_new_branch = Create a <strong>new branch</strong> for this commit and start a pull request.
 | 
			
		||||
editor.create_new_branch_np = Create a <strong>new branch</strong> for this commit.
 | 
			
		||||
 
 | 
			
		||||
@@ -235,6 +235,7 @@ func CreateFile(ctx *context.APIContext) {
 | 
			
		||||
			Author:    apiOpts.Dates.Author,
 | 
			
		||||
			Committer: apiOpts.Dates.Committer,
 | 
			
		||||
		},
 | 
			
		||||
		Signoff: apiOpts.Signoff,
 | 
			
		||||
	}
 | 
			
		||||
	if opts.Dates.Author.IsZero() {
 | 
			
		||||
		opts.Dates.Author = time.Now()
 | 
			
		||||
@@ -323,6 +324,7 @@ func UpdateFile(ctx *context.APIContext) {
 | 
			
		||||
			Author:    apiOpts.Dates.Author,
 | 
			
		||||
			Committer: apiOpts.Dates.Committer,
 | 
			
		||||
		},
 | 
			
		||||
		Signoff: apiOpts.Signoff,
 | 
			
		||||
	}
 | 
			
		||||
	if opts.Dates.Author.IsZero() {
 | 
			
		||||
		opts.Dates.Author = time.Now()
 | 
			
		||||
@@ -449,6 +451,7 @@ func DeleteFile(ctx *context.APIContext) {
 | 
			
		||||
			Author:    apiOpts.Dates.Author,
 | 
			
		||||
			Committer: apiOpts.Dates.Committer,
 | 
			
		||||
		},
 | 
			
		||||
		Signoff: apiOpts.Signoff,
 | 
			
		||||
	}
 | 
			
		||||
	if opts.Dates.Author.IsZero() {
 | 
			
		||||
		opts.Dates.Author = time.Now()
 | 
			
		||||
 
 | 
			
		||||
@@ -240,6 +240,7 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
 | 
			
		||||
		Message:      message,
 | 
			
		||||
		Content:      strings.ReplaceAll(form.Content, "\r", ""),
 | 
			
		||||
		IsNewFile:    isNewFile,
 | 
			
		||||
		Signoff:      form.Signoff,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		// This is where we handle all the errors thrown by repofiles.CreateOrUpdateRepoFile
 | 
			
		||||
		if git.IsErrNotExist(err) {
 | 
			
		||||
@@ -442,6 +443,7 @@ func DeleteFilePost(ctx *context.Context) {
 | 
			
		||||
		NewBranch:    branchName,
 | 
			
		||||
		TreePath:     ctx.Repo.TreePath,
 | 
			
		||||
		Message:      message,
 | 
			
		||||
		Signoff:      form.Signoff,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		// This is where we handle all the errors thrown by repofiles.DeleteRepoFile
 | 
			
		||||
		if git.IsErrNotExist(err) || models.IsErrRepoFileDoesNotExist(err) {
 | 
			
		||||
@@ -650,6 +652,7 @@ func UploadFilePost(ctx *context.Context) {
 | 
			
		||||
		TreePath:     form.TreePath,
 | 
			
		||||
		Message:      message,
 | 
			
		||||
		Files:        form.Files,
 | 
			
		||||
		Signoff:      form.Signoff,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		if models.IsErrLFSFileLocked(err) {
 | 
			
		||||
			ctx.Data["Err_TreePath"] = true
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,12 @@
 | 
			
		||||
		<div class="field">
 | 
			
		||||
			<textarea name="commit_message" placeholder="{{.i18n.Tr "repo.editor.commit_message_desc"}}" rows="5">{{.commit_message}}</textarea>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="inline field">
 | 
			
		||||
			<div class="ui checkbox">
 | 
			
		||||
				<input name="signoff" type="checkbox" tabindex="0" class="hidden">
 | 
			
		||||
				<label>{{.i18n.Tr "repo.editor.signoff_desc"}}</label>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="quick-pull-choice js-quick-pull-choice">
 | 
			
		||||
			<div class="field">
 | 
			
		||||
				<div class="ui radio checkbox {{if not .CanCommitToBranch.CanCommitToBranch}}disabled{{end}}">
 | 
			
		||||
 
 | 
			
		||||
@@ -12023,6 +12023,11 @@
 | 
			
		||||
          "description": "new_branch (optional) will make a new branch from `branch` before creating the file",
 | 
			
		||||
          "type": "string",
 | 
			
		||||
          "x-go-name": "NewBranchName"
 | 
			
		||||
        },
 | 
			
		||||
        "signoff": {
 | 
			
		||||
          "description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "x-go-name": "Signoff"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "x-go-package": "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
@@ -12731,6 +12736,11 @@
 | 
			
		||||
          "description": "sha is the SHA for the file that already exists",
 | 
			
		||||
          "type": "string",
 | 
			
		||||
          "x-go-name": "SHA"
 | 
			
		||||
        },
 | 
			
		||||
        "signoff": {
 | 
			
		||||
          "description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "x-go-name": "Signoff"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "x-go-package": "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
@@ -15762,6 +15772,11 @@
 | 
			
		||||
          "description": "sha is the SHA for the file that already exists",
 | 
			
		||||
          "type": "string",
 | 
			
		||||
          "x-go-name": "SHA"
 | 
			
		||||
        },
 | 
			
		||||
        "signoff": {
 | 
			
		||||
          "description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "x-go-name": "Signoff"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "x-go-package": "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user