@@ -8,30 +8,71 @@ import (
88 "strings"
99
1010 repo_model "code.gitea.io/gitea/models/repo"
11+ user_model "code.gitea.io/gitea/models/user"
12+ "code.gitea.io/gitea/modules/container"
1113 "code.gitea.io/gitea/modules/git"
1214 "code.gitea.io/gitea/modules/log"
1315 "code.gitea.io/gitea/modules/setting"
1416)
1517
18+ // doMergeStyleSquash gets a commit author signature for squash commits
19+ func getAuthorSignatureSquash (ctx * mergeContext ) (* git.Signature , error ) {
20+ if err := ctx .pr .Issue .LoadPoster (ctx ); err != nil {
21+ log .Error ("%-v Issue[%d].LoadPoster: %v" , ctx .pr , ctx .pr .Issue .ID , err )
22+ return nil , err
23+ }
24+
25+ // Try to get an signature from the same user in one of the commits, as the
26+ // poster email might be private or commits might have a different signature
27+ // than the primary email address of the poster.
28+ gitRepo , err := git .OpenRepository (ctx , ctx .tmpBasePath )
29+ if err != nil {
30+ log .Error ("%-v Unable to open base repository: %v" , ctx .pr , err )
31+ return nil , err
32+ }
33+ defer gitRepo .Close ()
34+
35+ commits , err := gitRepo .CommitsBetweenIDs (trackingBranch , "HEAD" )
36+ if err != nil {
37+ log .Error ("%-v Unable to get commits between: %s %s: %v" , ctx .pr , "HEAD" , trackingBranch , err )
38+ return nil , err
39+ }
40+
41+ uniqueEmails := make (container.Set [string ])
42+ for _ , commit := range commits {
43+ if commit .Author != nil && uniqueEmails .Add (commit .Author .Email ) {
44+ commitUser , _ := user_model .GetUserByEmail (ctx , commit .Author .Email )
45+ if commitUser != nil && commitUser .ID == ctx .pr .Issue .Poster .ID {
46+ return commit .Author , nil
47+ }
48+ }
49+ }
50+
51+ return ctx .pr .Issue .Poster .NewGitSig (), nil
52+ }
53+
1654// doMergeStyleSquash squashes the tracking branch on the current HEAD (=base)
1755func doMergeStyleSquash (ctx * mergeContext , message string ) error {
18- poster := ctx .pr .Issue .Poster .NewGitSig ()
56+ sig , err := getAuthorSignatureSquash (ctx )
57+ if err != nil {
58+ return fmt .Errorf ("getAuthorSignatureSquash: %w" , err )
59+ }
1960
2061 cmdMerge := git .NewCommand (ctx , "merge" , "--squash" ).AddDynamicArguments (trackingBranch )
2162 if err := runMergeCommand (ctx , repo_model .MergeStyleSquash , cmdMerge ); err != nil {
2263 log .Error ("%-v Unable to merge --squash tracking into base: %v" , ctx .pr , err )
2364 return err
2465 }
2566
26- if setting .Repository .PullRequest .AddCoCommitterTrailers && ctx .committer .String () != poster .String () {
67+ if setting .Repository .PullRequest .AddCoCommitterTrailers && ctx .committer .String () != sig .String () {
2768 // add trailer
28- if ! strings .Contains (message , fmt .Sprintf ("Co-authored-by: %s" , ctx . committer .String ())) {
29- message += fmt .Sprintf ("\n Co-authored-by: %s" , ctx . committer .String ())
69+ if ! strings .Contains (message , fmt .Sprintf ("Co-authored-by: %s" , sig .String ())) {
70+ message += fmt .Sprintf ("\n Co-authored-by: %s" , sig .String ())
3071 }
31- message += fmt .Sprintf ("\n Co-committed-by: %s\n " , ctx . committer .String ())
72+ message += fmt .Sprintf ("\n Co-committed-by: %s\n " , sig .String ())
3273 }
3374 cmdCommit := git .NewCommand (ctx , "commit" ).
34- AddOptionFormat ("--author='%s <%s>'" , poster .Name , poster .Email ).
75+ AddOptionFormat ("--author='%s <%s>'" , sig .Name , sig .Email ).
3576 AddOptionFormat ("--message=%s" , message )
3677 if ctx .signKeyID == "" {
3778 cmdCommit .AddArguments ("--no-gpg-sign" )
0 commit comments