Signed-off-by: a1012112796 <1012112796@qq.com>tags/v1.15.0-dev
@@ -698,6 +698,7 @@ type EditRepoFileForm struct { | |||||
CommitChoice string `binding:"Required;MaxSize(50)"` | CommitChoice string `binding:"Required;MaxSize(50)"` | ||||
NewBranchName string `binding:"GitRefName;MaxSize(100)"` | NewBranchName string `binding:"GitRefName;MaxSize(100)"` | ||||
LastCommit string | LastCommit string | ||||
Signoff bool | |||||
} | } | ||||
// Validate validates the fields | // Validate validates the fields | ||||
@@ -733,6 +734,7 @@ type UploadRepoFileForm struct { | |||||
CommitChoice string `binding:"Required;MaxSize(50)"` | CommitChoice string `binding:"Required;MaxSize(50)"` | ||||
NewBranchName string `binding:"GitRefName;MaxSize(100)"` | NewBranchName string `binding:"GitRefName;MaxSize(100)"` | ||||
Files []string | Files []string | ||||
Signoff bool | |||||
} | } | ||||
// Validate validates the fields | // Validate validates the fields | ||||
@@ -766,6 +768,7 @@ type DeleteRepoFileForm struct { | |||||
CommitChoice string `binding:"Required;MaxSize(50)"` | CommitChoice string `binding:"Required;MaxSize(50)"` | ||||
NewBranchName string `binding:"GitRefName;MaxSize(100)"` | NewBranchName string `binding:"GitRefName;MaxSize(100)"` | ||||
LastCommit string | LastCommit string | ||||
Signoff bool | |||||
} | } | ||||
// Validate validates the fields | // Validate validates the fields | ||||
@@ -25,6 +25,7 @@ type DeleteRepoFileOptions struct { | |||||
Author *IdentityOptions | Author *IdentityOptions | ||||
Committer *IdentityOptions | Committer *IdentityOptions | ||||
Dates *CommitDateOptions | Dates *CommitDateOptions | ||||
Signoff bool | |||||
} | } | ||||
// DeleteRepoFile deletes a file in the given repository | // 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 | // Now commit the tree | ||||
var commitHash string | var commitHash string | ||||
if opts.Dates != nil { | 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 { | } else { | ||||
commitHash, err = t.CommitTree(author, committer, treeHash, message) | |||||
commitHash, err = t.CommitTree(author, committer, treeHash, message, opts.Signoff) | |||||
} | } | ||||
if err != nil { | if err != nil { | ||||
return nil, err | 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 | // 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 | // 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() | authorSig := author.NewGitSig() | ||||
committerSig := committer.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, | env = append(env, | ||||
"GIT_COMMITTER_NAME="+committerSig.Name, | "GIT_COMMITTER_NAME="+committerSig.Name, | ||||
"GIT_COMMITTER_EMAIL="+committerSig.Email, | "GIT_COMMITTER_EMAIL="+committerSig.Email, | ||||
@@ -51,6 +51,7 @@ type UpdateRepoFileOptions struct { | |||||
Author *IdentityOptions | Author *IdentityOptions | ||||
Committer *IdentityOptions | Committer *IdentityOptions | ||||
Dates *CommitDateOptions | Dates *CommitDateOptions | ||||
Signoff bool | |||||
} | } | ||||
func detectEncodingAndBOM(entry *git.TreeEntry, repo *models.Repository) (string, 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 | // Now commit the tree | ||||
var commitHash string | var commitHash string | ||||
if opts.Dates != nil { | 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 { | } else { | ||||
commitHash, err = t.CommitTree(author, committer, treeHash, message) | |||||
commitHash, err = t.CommitTree(author, committer, treeHash, message, opts.Signoff) | |||||
} | } | ||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
@@ -24,6 +24,7 @@ type UploadRepoFileOptions struct { | |||||
TreePath string | TreePath string | ||||
Message string | Message string | ||||
Files []string // In UUID format. | Files []string // In UUID format. | ||||
Signoff bool | |||||
} | } | ||||
type uploadInfo struct { | type uploadInfo struct { | ||||
@@ -143,7 +144,7 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep | |||||
committer := doer | committer := doer | ||||
// Now commit the tree | // 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 { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
@@ -17,6 +17,8 @@ type FileOptions struct { | |||||
Author Identity `json:"author"` | Author Identity `json:"author"` | ||||
Committer Identity `json:"committer"` | Committer Identity `json:"committer"` | ||||
Dates CommitDateOptions `json:"dates"` | 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 | // CreateFileOptions options for creating files | ||||
@@ -874,6 +874,7 @@ editor.add = Add '%s' | |||||
editor.update = Update '%s' | editor.update = Update '%s' | ||||
editor.delete = Delete '%s' | editor.delete = Delete '%s' | ||||
editor.commit_message_desc = Add an optional extended description… | 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.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 = 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. | 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, | Author: apiOpts.Dates.Author, | ||||
Committer: apiOpts.Dates.Committer, | Committer: apiOpts.Dates.Committer, | ||||
}, | }, | ||||
Signoff: apiOpts.Signoff, | |||||
} | } | ||||
if opts.Dates.Author.IsZero() { | if opts.Dates.Author.IsZero() { | ||||
opts.Dates.Author = time.Now() | opts.Dates.Author = time.Now() | ||||
@@ -323,6 +324,7 @@ func UpdateFile(ctx *context.APIContext) { | |||||
Author: apiOpts.Dates.Author, | Author: apiOpts.Dates.Author, | ||||
Committer: apiOpts.Dates.Committer, | Committer: apiOpts.Dates.Committer, | ||||
}, | }, | ||||
Signoff: apiOpts.Signoff, | |||||
} | } | ||||
if opts.Dates.Author.IsZero() { | if opts.Dates.Author.IsZero() { | ||||
opts.Dates.Author = time.Now() | opts.Dates.Author = time.Now() | ||||
@@ -449,6 +451,7 @@ func DeleteFile(ctx *context.APIContext) { | |||||
Author: apiOpts.Dates.Author, | Author: apiOpts.Dates.Author, | ||||
Committer: apiOpts.Dates.Committer, | Committer: apiOpts.Dates.Committer, | ||||
}, | }, | ||||
Signoff: apiOpts.Signoff, | |||||
} | } | ||||
if opts.Dates.Author.IsZero() { | if opts.Dates.Author.IsZero() { | ||||
opts.Dates.Author = time.Now() | opts.Dates.Author = time.Now() | ||||
@@ -240,6 +240,7 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo | |||||
Message: message, | Message: message, | ||||
Content: strings.ReplaceAll(form.Content, "\r", ""), | Content: strings.ReplaceAll(form.Content, "\r", ""), | ||||
IsNewFile: isNewFile, | IsNewFile: isNewFile, | ||||
Signoff: form.Signoff, | |||||
}); err != nil { | }); err != nil { | ||||
// This is where we handle all the errors thrown by repofiles.CreateOrUpdateRepoFile | // This is where we handle all the errors thrown by repofiles.CreateOrUpdateRepoFile | ||||
if git.IsErrNotExist(err) { | if git.IsErrNotExist(err) { | ||||
@@ -442,6 +443,7 @@ func DeleteFilePost(ctx *context.Context) { | |||||
NewBranch: branchName, | NewBranch: branchName, | ||||
TreePath: ctx.Repo.TreePath, | TreePath: ctx.Repo.TreePath, | ||||
Message: message, | Message: message, | ||||
Signoff: form.Signoff, | |||||
}); err != nil { | }); err != nil { | ||||
// This is where we handle all the errors thrown by repofiles.DeleteRepoFile | // This is where we handle all the errors thrown by repofiles.DeleteRepoFile | ||||
if git.IsErrNotExist(err) || models.IsErrRepoFileDoesNotExist(err) { | if git.IsErrNotExist(err) || models.IsErrRepoFileDoesNotExist(err) { | ||||
@@ -650,6 +652,7 @@ func UploadFilePost(ctx *context.Context) { | |||||
TreePath: form.TreePath, | TreePath: form.TreePath, | ||||
Message: message, | Message: message, | ||||
Files: form.Files, | Files: form.Files, | ||||
Signoff: form.Signoff, | |||||
}); err != nil { | }); err != nil { | ||||
if models.IsErrLFSFileLocked(err) { | if models.IsErrLFSFileLocked(err) { | ||||
ctx.Data["Err_TreePath"] = true | ctx.Data["Err_TreePath"] = true | ||||
@@ -14,6 +14,12 @@ | |||||
<div class="field"> | <div class="field"> | ||||
<textarea name="commit_message" placeholder="{{.i18n.Tr "repo.editor.commit_message_desc"}}" rows="5">{{.commit_message}}</textarea> | <textarea name="commit_message" placeholder="{{.i18n.Tr "repo.editor.commit_message_desc"}}" rows="5">{{.commit_message}}</textarea> | ||||
</div> | </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="quick-pull-choice js-quick-pull-choice"> | ||||
<div class="field"> | <div class="field"> | ||||
<div class="ui radio checkbox {{if not .CanCommitToBranch.CanCommitToBranch}}disabled{{end}}"> | <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", | "description": "new_branch (optional) will make a new branch from `branch` before creating the file", | ||||
"type": "string", | "type": "string", | ||||
"x-go-name": "NewBranchName" | "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" | "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||
@@ -12731,6 +12736,11 @@ | |||||
"description": "sha is the SHA for the file that already exists", | "description": "sha is the SHA for the file that already exists", | ||||
"type": "string", | "type": "string", | ||||
"x-go-name": "SHA" | "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" | "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||
@@ -15762,6 +15772,11 @@ | |||||
"description": "sha is the SHA for the file that already exists", | "description": "sha is the SHA for the file that already exists", | ||||
"type": "string", | "type": "string", | ||||
"x-go-name": "SHA" | "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" | "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||