Skip to content

Commit d732ea7

Browse files
committed
fix
1 parent a89c735 commit d732ea7

File tree

19 files changed

+347
-179
lines changed

19 files changed

+347
-179
lines changed

models/user/email_address.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,3 +542,13 @@ func IsEmailDomainAllowed(email string) bool {
542542

543543
return validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email)
544544
}
545+
546+
func GetActivatedEmailAddresses(ctx context.Context, uid int64) ([]string, error) {
547+
emails := make([]string, 0, 2)
548+
if err := db.GetEngine(ctx).Table("email_address").Select("email").
549+
Where("uid=? AND is_activated=?", uid, true).Asc("id").
550+
Find(&emails); err != nil {
551+
return nil, err
552+
}
553+
return emails, nil
554+
}

models/user/user.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ func (u *User) GetPlaceholderEmail() string {
214214
return fmt.Sprintf("%s@%s", u.LowerName, setting.Service.NoReplyAddress)
215215
}
216216

217-
// GetEmail returns an noreply email, if the user has set to keep his
217+
// GetEmail returns a noreply email, if the user has set to keep his
218218
// email address private, otherwise the primary email address.
219219
func (u *User) GetEmail() string {
220220
if u.KeepEmailPrivate {

options/locale/locale_en-US.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,8 @@ editor.new_branch_name_desc = New branch name…
13451345
editor.cancel = Cancel
13461346
editor.filename_cannot_be_empty = The filename cannot be empty.
13471347
editor.filename_is_invalid = The filename is invalid: "%s".
1348+
editor.commit_email = Commit email
1349+
editor.invalid_commit_email = The email for the commit is invalid.
13481350
editor.branch_does_not_exist = Branch "%s" does not exist in this repository.
13491351
editor.branch_already_exists = Branch "%s" already exists in this repository.
13501352
editor.directory_is_a_file = Directory name "%s" is already used as a filename in this repository.

routers/api/v1/repo/file.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -489,12 +489,12 @@ func ChangeFiles(ctx *context.APIContext) {
489489
OldBranch: apiOpts.BranchName,
490490
NewBranch: apiOpts.NewBranchName,
491491
Committer: &files_service.IdentityOptions{
492-
Name: apiOpts.Committer.Name,
493-
Email: apiOpts.Committer.Email,
492+
GitUserName: apiOpts.Committer.Name,
493+
GitUserEmail: apiOpts.Committer.Email,
494494
},
495495
Author: &files_service.IdentityOptions{
496-
Name: apiOpts.Author.Name,
497-
Email: apiOpts.Author.Email,
496+
GitUserName: apiOpts.Author.Name,
497+
GitUserEmail: apiOpts.Author.Email,
498498
},
499499
Dates: &files_service.CommitDateOptions{
500500
Author: apiOpts.Dates.Author,
@@ -586,12 +586,12 @@ func CreateFile(ctx *context.APIContext) {
586586
OldBranch: apiOpts.BranchName,
587587
NewBranch: apiOpts.NewBranchName,
588588
Committer: &files_service.IdentityOptions{
589-
Name: apiOpts.Committer.Name,
590-
Email: apiOpts.Committer.Email,
589+
GitUserName: apiOpts.Committer.Name,
590+
GitUserEmail: apiOpts.Committer.Email,
591591
},
592592
Author: &files_service.IdentityOptions{
593-
Name: apiOpts.Author.Name,
594-
Email: apiOpts.Author.Email,
593+
GitUserName: apiOpts.Author.Name,
594+
GitUserEmail: apiOpts.Author.Email,
595595
},
596596
Dates: &files_service.CommitDateOptions{
597597
Author: apiOpts.Dates.Author,
@@ -689,12 +689,12 @@ func UpdateFile(ctx *context.APIContext) {
689689
OldBranch: apiOpts.BranchName,
690690
NewBranch: apiOpts.NewBranchName,
691691
Committer: &files_service.IdentityOptions{
692-
Name: apiOpts.Committer.Name,
693-
Email: apiOpts.Committer.Email,
692+
GitUserName: apiOpts.Committer.Name,
693+
GitUserEmail: apiOpts.Committer.Email,
694694
},
695695
Author: &files_service.IdentityOptions{
696-
Name: apiOpts.Author.Name,
697-
Email: apiOpts.Author.Email,
696+
GitUserName: apiOpts.Author.Name,
697+
GitUserEmail: apiOpts.Author.Email,
698698
},
699699
Dates: &files_service.CommitDateOptions{
700700
Author: apiOpts.Dates.Author,
@@ -848,12 +848,12 @@ func DeleteFile(ctx *context.APIContext) {
848848
OldBranch: apiOpts.BranchName,
849849
NewBranch: apiOpts.NewBranchName,
850850
Committer: &files_service.IdentityOptions{
851-
Name: apiOpts.Committer.Name,
852-
Email: apiOpts.Committer.Email,
851+
GitUserName: apiOpts.Committer.Name,
852+
GitUserEmail: apiOpts.Committer.Email,
853853
},
854854
Author: &files_service.IdentityOptions{
855-
Name: apiOpts.Author.Name,
856-
Email: apiOpts.Author.Email,
855+
GitUserName: apiOpts.Author.Name,
856+
GitUserEmail: apiOpts.Author.Email,
857857
},
858858
Dates: &files_service.CommitDateOptions{
859859
Author: apiOpts.Dates.Author,

routers/api/v1/repo/patch.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ func ApplyDiffPatch(ctx *context.APIContext) {
5858
OldBranch: apiOpts.BranchName,
5959
NewBranch: apiOpts.NewBranchName,
6060
Committer: &files.IdentityOptions{
61-
Name: apiOpts.Committer.Name,
62-
Email: apiOpts.Committer.Email,
61+
GitUserName: apiOpts.Committer.Name,
62+
GitUserEmail: apiOpts.Committer.Email,
6363
},
6464
Author: &files.IdentityOptions{
65-
Name: apiOpts.Author.Name,
66-
Email: apiOpts.Author.Email,
65+
GitUserName: apiOpts.Author.Name,
66+
GitUserEmail: apiOpts.Author.Email,
6767
},
6868
Dates: &files.CommitDateOptions{
6969
Author: apiOpts.Dates.Author,

routers/web/repo/editor.go

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
git_model "code.gitea.io/gitea/models/git"
1414
repo_model "code.gitea.io/gitea/models/repo"
1515
"code.gitea.io/gitea/models/unit"
16+
user_model "code.gitea.io/gitea/models/user"
1617
"code.gitea.io/gitea/modules/charset"
1718
"code.gitea.io/gitea/modules/git"
1819
"code.gitea.io/gitea/modules/json"
@@ -102,10 +103,33 @@ func getParentTreeFields(treePath string) (treeNames, treePaths []string) {
102103
return treeNames, treePaths
103104
}
104105

105-
func editFile(ctx *context.Context, isNewFile bool) {
106-
ctx.Data["PageIsViewCode"] = true
106+
func getCandidateEmailAddresses(ctx *context.Context) []string {
107+
emails, err := user_model.GetActivatedEmailAddresses(ctx, ctx.Doer.ID)
108+
if err != nil {
109+
log.Error("getCandidateEmailAddresses: GetActivatedEmailAddresses: %v", err)
110+
}
111+
112+
placeholderMail := ctx.Doer.GetPlaceholderEmail()
113+
if ctx.Doer.KeepEmailPrivate {
114+
emails = append([]string{placeholderMail}, emails...)
115+
}
116+
return emails
117+
}
118+
119+
func editFileCommon(ctx *context.Context, isNewFile bool) {
107120
ctx.Data["PageIsEdit"] = true
108121
ctx.Data["IsNewFile"] = isNewFile
122+
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
123+
ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",")
124+
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
125+
ctx.Data["IsEditingFileOnly"] = ctx.FormString("return_uri") != ""
126+
ctx.Data["ReturnURI"] = ctx.FormString("return_uri")
127+
ctx.Data["CommitCandidateEmails"] = getCandidateEmailAddresses(ctx)
128+
ctx.Data["CommitDefaultEmail"] = ctx.Doer.GetEmail()
129+
}
130+
131+
func editFile(ctx *context.Context, isNewFile bool) {
132+
editFileCommon(ctx, isNewFile)
109133
canCommit := renderCommitRights(ctx)
110134

111135
treePath := cleanUploadFileName(ctx.Repo.TreePath)
@@ -174,28 +198,19 @@ func editFile(ctx *context.Context, isNewFile bool) {
174198
ctx.Data["FileContent"] = content
175199
}
176200
} else {
177-
// Append filename from query, or empty string to allow user name the new file.
201+
// Append filename from query, or empty string to allow username the new file.
178202
treeNames = append(treeNames, fileName)
179203
}
180204

181205
ctx.Data["TreeNames"] = treeNames
182206
ctx.Data["TreePaths"] = treePaths
183-
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
184207
ctx.Data["commit_summary"] = ""
185208
ctx.Data["commit_message"] = ""
186-
if canCommit {
187-
ctx.Data["commit_choice"] = frmCommitChoiceDirect
188-
} else {
189-
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
190-
}
209+
ctx.Data["commit_choice"] = util.Iif(canCommit, frmCommitChoiceDirect, frmCommitChoiceNewBranch)
191210
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
192211
ctx.Data["last_commit"] = ctx.Repo.CommitID
193-
ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",")
194-
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
195-
ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, treePath)
196212

197-
ctx.Data["IsEditingFileOnly"] = ctx.FormString("return_uri") != ""
198-
ctx.Data["ReturnURI"] = ctx.FormString("return_uri")
213+
ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, treePath)
199214

200215
ctx.HTML(http.StatusOK, tplEditFile)
201216
}
@@ -224,36 +239,33 @@ func NewFile(ctx *context.Context) {
224239
}
225240

226241
func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile bool) {
242+
editFileCommon(ctx, isNewFile)
243+
ctx.Data["PageHasPosted"] = true
244+
227245
canCommit := renderCommitRights(ctx)
228246
treeNames, treePaths := getParentTreeFields(form.TreePath)
229247
branchName := ctx.Repo.BranchName
230248
if form.CommitChoice == frmCommitChoiceNewBranch {
231249
branchName = form.NewBranchName
232250
}
233251

234-
ctx.Data["PageIsEdit"] = true
235-
ctx.Data["PageHasPosted"] = true
236-
ctx.Data["IsNewFile"] = isNewFile
237252
ctx.Data["TreePath"] = form.TreePath
238253
ctx.Data["TreeNames"] = treeNames
239254
ctx.Data["TreePaths"] = treePaths
240-
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName)
241255
ctx.Data["FileContent"] = form.Content
242256
ctx.Data["commit_summary"] = form.CommitSummary
243257
ctx.Data["commit_message"] = form.CommitMessage
244258
ctx.Data["commit_choice"] = form.CommitChoice
245259
ctx.Data["new_branch_name"] = form.NewBranchName
246260
ctx.Data["last_commit"] = ctx.Repo.CommitID
247-
ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",")
248-
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
249261
ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, form.TreePath)
250262

251263
if ctx.HasError() {
252264
ctx.HTML(http.StatusOK, tplEditFile)
253265
return
254266
}
255267

256-
// Cannot commit to a an existing branch if user doesn't have rights
268+
// Cannot commit to an existing branch if user doesn't have rights
257269
if branchName == ctx.Repo.BranchName && !canCommit {
258270
ctx.Data["Err_NewBranchName"] = true
259271
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
@@ -276,6 +288,17 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
276288
message += "\n\n" + form.CommitMessage
277289
}
278290

291+
gitCommitter := &files_service.IdentityOptions{}
292+
if form.CommitEmail != "" {
293+
if util.SliceContainsString(getCandidateEmailAddresses(ctx), form.CommitEmail, true) {
294+
gitCommitter.GitUserEmail = form.CommitEmail
295+
} else {
296+
ctx.Data["Err_CommitEmail"] = true
297+
ctx.RenderWithErr(ctx.Tr("repo.editor.invalid_commit_email"), tplEditFile, &form)
298+
return
299+
}
300+
}
301+
279302
operation := "update"
280303
if isNewFile {
281304
operation = "create"
@@ -294,7 +317,9 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
294317
ContentReader: strings.NewReader(strings.ReplaceAll(form.Content, "\r", "")),
295318
},
296319
},
297-
Signoff: form.Signoff,
320+
Signoff: form.Signoff,
321+
Author: gitCommitter,
322+
Committer: gitCommitter,
298323
}); err != nil {
299324
// This is where we handle all the errors thrown by files_service.ChangeRepoFiles
300325
if git.IsErrNotExist(err) {

services/forms/repo_form.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ type EditRepoFileForm struct {
720720
NewBranchName string `binding:"GitRefName;MaxSize(100)"`
721721
LastCommit string
722722
Signoff bool
723+
CommitEmail string
723724
}
724725

725726
// Validate validates the fields

services/packages/cargo/index.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"io"
1212
"path"
1313
"strconv"
14-
"time"
1514

1615
packages_model "code.gitea.io/gitea/models/packages"
1716
repo_model "code.gitea.io/gitea/models/repo"
@@ -296,8 +295,13 @@ func alterRepositoryContent(ctx context.Context, doer *user_model.User, repo *re
296295
return err
297296
}
298297

299-
now := time.Now()
300-
commitHash, err := t.CommitTreeWithDate(lastCommitID, doer, doer, treeHash, commitMessage, false, now, now)
298+
commitOpts := &files_service.CommitTreeUserOptions{
299+
ParentCommitID: lastCommitID,
300+
TreeHash: treeHash,
301+
CommitMessage: commitMessage,
302+
DoerUser: doer,
303+
}
304+
commitHash, err := t.CommitTree(commitOpts)
301305
if err != nil {
302306
return err
303307
}

services/repository/files/cherry_pick.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,13 @@ func (err ErrCommitIDDoesNotMatch) Error() string {
3232
return fmt.Sprintf("file CommitID does not match [given: %s, expected: %s]", err.GivenCommitID, err.CurrentCommitID)
3333
}
3434

35-
// CherryPick cherrypicks or reverts a commit to the given repository
35+
// CherryPick cherry-picks or reverts a commit to the given repository
3636
func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, revert bool, opts *ApplyDiffPatchOptions) (*structs.FileResponse, error) {
3737
if err := opts.Validate(ctx, repo, doer); err != nil {
3838
return nil, err
3939
}
4040
message := strings.TrimSpace(opts.Message)
4141

42-
author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer)
43-
4442
t, err := NewTemporaryUploadRepository(ctx, repo)
4543
if err != nil {
4644
log.Error("NewTemporaryUploadRepository failed: %v", err)
@@ -112,12 +110,21 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod
112110
}
113111

114112
// Now commit the tree
115-
var commitHash string
113+
commitOpts := &CommitTreeUserOptions{
114+
ParentCommitID: "HEAD",
115+
TreeHash: treeHash,
116+
CommitMessage: message,
117+
SignOff: opts.Signoff,
118+
DoerUser: doer,
119+
AuthorIdentity: opts.Author,
120+
AuthorTime: nil,
121+
CommitterIdentity: opts.Committer,
122+
CommitterTime: nil,
123+
}
116124
if opts.Dates != nil {
117-
commitHash, err = t.CommitTreeWithDate("HEAD", author, committer, treeHash, message, opts.Signoff, opts.Dates.Author, opts.Dates.Committer)
118-
} else {
119-
commitHash, err = t.CommitTree("HEAD", author, committer, treeHash, message, opts.Signoff)
125+
commitOpts.AuthorTime, commitOpts.CommitterTime = &opts.Dates.Author, &opts.Dates.Committer
120126
}
127+
commitHash, err := t.CommitTree(commitOpts)
121128
if err != nil {
122129
return nil, err
123130
}

services/repository/files/file.go

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"time"
1212

1313
repo_model "code.gitea.io/gitea/models/repo"
14-
user_model "code.gitea.io/gitea/models/user"
1514
"code.gitea.io/gitea/modules/git"
1615
api "code.gitea.io/gitea/modules/structs"
1716
"code.gitea.io/gitea/modules/util"
@@ -111,51 +110,6 @@ func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*ap
111110
return fileCommit, nil
112111
}
113112

114-
// GetAuthorAndCommitterUsers Gets the author and committer user objects from the IdentityOptions
115-
func GetAuthorAndCommitterUsers(author, committer *IdentityOptions, doer *user_model.User) (authorUser, committerUser *user_model.User) {
116-
// Committer and author are optional. If they are not the doer (not same email address)
117-
// then we use bogus User objects for them to store their FullName and Email.
118-
// If only one of the two are provided, we set both of them to it.
119-
// If neither are provided, both are the doer.
120-
if committer != nil && committer.Email != "" {
121-
if doer != nil && strings.EqualFold(doer.Email, committer.Email) {
122-
committerUser = doer // the committer is the doer, so will use their user object
123-
if committer.Name != "" {
124-
committerUser.FullName = committer.Name
125-
}
126-
} else {
127-
committerUser = &user_model.User{
128-
FullName: committer.Name,
129-
Email: committer.Email,
130-
}
131-
}
132-
}
133-
if author != nil && author.Email != "" {
134-
if doer != nil && strings.EqualFold(doer.Email, author.Email) {
135-
authorUser = doer // the author is the doer, so will use their user object
136-
if authorUser.Name != "" {
137-
authorUser.FullName = author.Name
138-
}
139-
} else {
140-
authorUser = &user_model.User{
141-
FullName: author.Name,
142-
Email: author.Email,
143-
}
144-
}
145-
}
146-
if authorUser == nil {
147-
if committerUser != nil {
148-
authorUser = committerUser // No valid author was given so use the committer
149-
} else if doer != nil {
150-
authorUser = doer // No valid author was given and no valid committer so use the doer
151-
}
152-
}
153-
if committerUser == nil {
154-
committerUser = authorUser // No valid committer so use the author as the committer (was set to a valid user above)
155-
}
156-
return authorUser, committerUser
157-
}
158-
159113
// ErrFilenameInvalid represents a "FilenameInvalid" kind of error.
160114
type ErrFilenameInvalid struct {
161115
Path string

0 commit comments

Comments
 (0)