Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
3e0687f
Fix the wrong push commits in the pull request when force push
lunny Mar 17, 2026
2f1862c
fix test
lunny Mar 17, 2026
69242f3
Potential fix for pull request finding
lunny Mar 17, 2026
51d6a1d
Reimplement GetCommitIDsBetween
lunny Mar 18, 2026
6406de9
adjustment
lunny Mar 18, 2026
4dabf45
fix
lunny Mar 18, 2026
e0358ef
fix
lunny Mar 18, 2026
0047935
Merge branch 'main' into lunny/fix_force_push
lunny Mar 18, 2026
1fcacf0
Fix lint
lunny Mar 21, 2026
ab6d7f9
Merge branch 'main' into lunny/fix_force_push
lunny Mar 21, 2026
fdb0045
Update services/pull/comment.go
lunny Mar 21, 2026
5a3ee62
Fix
lunny Mar 21, 2026
c96aa3c
Merge branch 'main' into lunny/fix_force_push
lunny Mar 21, 2026
22f55d4
Update services/pull/comment.go
lunny Mar 21, 2026
d1ae492
Update modules/gitrepo/compare_test.go
lunny Mar 21, 2026
1e0efd2
remove unnecessary parameter
lunny Mar 21, 2026
da4811d
Fix bug
lunny Mar 22, 2026
97b4fcf
Merge branch 'main' into lunny/fix_force_push
lunny Mar 22, 2026
45694fb
Fix
lunny Mar 23, 2026
03e8865
Update modules/gitrepo/compare.go
wxiaoguang Mar 23, 2026
9f5bfae
improve test
lunny Mar 23, 2026
6f07441
Add comment back
lunny Mar 23, 2026
ae0b467
fix test
wxiaoguang Mar 23, 2026
9262d01
fix test
wxiaoguang Mar 23, 2026
b7ae643
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
e0d46c3
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
6f3d4ee
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
509a1f4
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
1471083
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
c5089f3
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
73a41e8
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
a023ef2
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 23, 2026
233663c
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 24, 2026
3cee251
Merge branch 'main' into lunny/fix_force_push
GiteaBot Mar 24, 2026
cf69efa
fix
lunny Mar 24, 2026
eeef1cd
Merge branch 'main' into lunny/fix_force_push
lunny Mar 24, 2026
4f78309
Merge branch 'lunny/fix_force_push' of github.com:lunny/gitea into lu…
lunny Mar 24, 2026
d893064
comment
lunny Mar 24, 2026
16e1d63
refactor
wxiaoguang Mar 29, 2026
3bfcd07
fix comment
wxiaoguang Mar 29, 2026
5a57466
fix comment
wxiaoguang Mar 29, 2026
40d9db7
Merge branch 'main' into lunny/fix_force_push
wxiaoguang Mar 29, 2026
22715e7
fix func name and comment
wxiaoguang Mar 29, 2026
3aed595
fix log
wxiaoguang Mar 29, 2026
b1a4248
Fix bug
lunny Mar 30, 2026
4934900
Some fix
lunny Mar 30, 2026
cf6232f
Merge branch 'main' into lunny/fix_force_push
lunny Mar 30, 2026
8980eb7
Some fix
lunny Mar 30, 2026
d3286f7
Fix test
lunny Mar 30, 2026
94345ee
improvement
lunny Mar 30, 2026
628d769
Rename prepareOldCommitCommentsToDelete
lunny Mar 30, 2026
26a2f9b
Merge branch 'main' into lunny/fix_force_push
lunny Apr 1, 2026
0094b0c
Merge branch 'main' into lunny/fix_force_push
lunny Apr 2, 2026
1df150f
Merge branch 'main' into lunny/fix_force_push
lunny Apr 2, 2026
9c56a6c
Merge branch 'main' into lunny/fix_force_push
lunny Apr 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions models/issues/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package issues

import (
"context"
"errors"
"fmt"
"html/template"
"slices"
Expand All @@ -21,6 +22,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/htmlutil"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/references"
Expand Down Expand Up @@ -326,21 +328,34 @@ type Comment struct {
RefIssue *Issue `xorm:"-"`
RefComment *Comment `xorm:"-"`

Commits []*git_model.SignCommitWithStatuses `xorm:"-"`
OldCommit string `xorm:"-"`
NewCommit string `xorm:"-"`
CommitsNum int64 `xorm:"-"`
IsForcePush bool `xorm:"-"`
Commits []*git_model.SignCommitWithStatuses `xorm:"-"`
OldCommit string `xorm:"-"`
NewCommit string `xorm:"-"`
CommitsNum int64 `xorm:"-"`

// Templates still use it. It is not persisted in database, it is only set when creating or loading
IsForcePush bool `xorm:"-"`
}

func init() {
db.RegisterModel(new(Comment))
}

// PushActionContent is content of push pull comment
// PushActionContent is content of pull request's push comment
type PushActionContent struct {
IsForcePush bool `json:"is_force_push"`
CommitIDs []string `json:"commit_ids"`
IsForcePush bool `json:"is_force_push"`
// if IsForcePush=true, CommitIDs contains the commit pair [old head, new head]
// if IsForcePush=false, CommitIDs contains the new commits newly pushed to the head branch
CommitIDs []string `json:"commit_ids"`
}

func (c *Comment) GetPushActionContent() (*PushActionContent, error) {
if c.Type != CommentTypePullRequestPush {
return nil, errors.New("not a pull request push comment")
}
var data PushActionContent
_ = json.Unmarshal(util.UnsafeStringToBytes(c.Content), &data)
Comment thread
wxiaoguang marked this conversation as resolved.
return &data, nil
}

// LoadIssue loads the issue reference for the comment
Expand Down
2 changes: 2 additions & 0 deletions modules/git/object_id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ func TestIsValidSHAPattern(t *testing.T) {
assert.Equal(t, "2e65efe2a145dda7ee51d1741299f848e5bf752e", ComputeBlobHash(Sha1ObjectFormat, []byte("a")).String())
assert.Equal(t, "473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813", ComputeBlobHash(Sha256ObjectFormat, nil).String())
assert.Equal(t, "eb337bcee2061c5313c9a1392116b6c76039e9e30d71467ae359b36277e17dc7", ComputeBlobHash(Sha256ObjectFormat, []byte("a")).String())
assert.True(t, IsEmptyCommitID(""))
assert.True(t, IsEmptyCommitID("0000000000000000000000000000000000000000"))
}
33 changes: 0 additions & 33 deletions modules/git/repo_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,39 +362,6 @@ func (repo *Repository) CommitsBetweenLimit(last, before *Commit, limit, skip in
return repo.parsePrettyFormatLogToList(bytes.TrimSpace(stdout))
}

// CommitsBetweenNotBase returns a list that contains commits between [before, last), excluding commits in baseBranch.
// If before is detached (removed by reset + push) it is not included.
func (repo *Repository) CommitsBetweenNotBase(last, before *Commit, baseBranch string) ([]*Commit, error) {
var stdout []byte
var err error
if before == nil {
stdout, _, err = gitcmd.NewCommand("rev-list").
AddDynamicArguments(last.ID.String()).
AddOptionValues("--not", baseBranch).
WithDir(repo.Path).
RunStdBytes(repo.Ctx)
} else {
stdout, _, err = gitcmd.NewCommand("rev-list").
AddDynamicArguments(before.ID.String()+".."+last.ID.String()).
AddOptionValues("--not", baseBranch).
WithDir(repo.Path).
RunStdBytes(repo.Ctx)
if err != nil && strings.Contains(err.Error(), "no merge base") {
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
// previously it would return the results of git rev-list before last so let's try that...
Comment thread
lunny marked this conversation as resolved.
stdout, _, err = gitcmd.NewCommand("rev-list").
AddDynamicArguments(before.ID.String(), last.ID.String()).
AddOptionValues("--not", baseBranch).
WithDir(repo.Path).
RunStdBytes(repo.Ctx)
}
}
if err != nil {
return nil, err
}
return repo.parsePrettyFormatLogToList(bytes.TrimSpace(stdout))
}

// CommitsBetweenIDs return commits between twoe commits
func (repo *Repository) CommitsBetweenIDs(last, before string) ([]*Commit, error) {
lastCommit, err := repo.GetCommit(last)
Expand Down
27 changes: 27 additions & 0 deletions modules/gitrepo/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,30 @@ func GetDivergingCommits(ctx context.Context, repo Repository, baseBranch, targe
}
return &DivergeObject{Ahead: ahead, Behind: behind}, nil
}

// GetCommitIDsBetweenReverse returns the last commit IDs between two commits in reverse order (from old to new) with limit.
// If the result exceeds the limit, the old commits IDs will be ignored
func GetCommitIDsBetweenReverse(ctx context.Context, repo Repository, startRef, endRef, notRef string, limit int) ([]string, error) {
genCmd := func(reversions ...string) *gitcmd.Command {
cmd := gitcmd.NewCommand("rev-list", "--reverse").
AddArguments("-n").AddDynamicArguments(strconv.Itoa(limit)).
AddDynamicArguments(reversions...)
if notRef != "" { // --not should be kept as the last parameter of git command, otherwise the result will be wrong
cmd.AddOptionValues("--not", notRef)
}
return cmd
}
stdout, _, err := RunCmdString(ctx, repo, genCmd(startRef+".."+endRef))
// example git error message: fatal: origin/main..HEAD: no merge base
if err != nil && strings.Contains(err.Stderr(), "no merge base") {
Comment thread
wxiaoguang marked this conversation as resolved.
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
Comment thread
wxiaoguang marked this conversation as resolved.
// previously it would return the results of git rev-list before last so let's try that...
stdout, _, err = RunCmdString(ctx, repo, genCmd(startRef, endRef))
}
if err != nil {
return nil, err
}

commitIDs := strings.Fields(strings.TrimSpace(stdout))
return commitIDs, nil
}
72 changes: 72 additions & 0 deletions modules/gitrepo/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,75 @@ func TestRepoGetDivergingCommits(t *testing.T) {
Behind: 2,
}, do)
}

func TestGetCommitIDsBetweenReverse(t *testing.T) {
repo := &mockRepository{path: "repo1_bare"}

// tests raw commit IDs
commitIDs, err := GetCommitIDsBetweenReverse(t.Context(), repo,
"8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
"ce064814f4a0d337b333e646ece456cd39fab612",
"",
100,
)
assert.NoError(t, err)
assert.Equal(t, []string{
"8006ff9adbf0cb94da7dad9e537e53817f9fa5c0",
"6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1",
"37991dec2c8e592043f47155ce4808d4580f9123",
"feaf4ba6bc635fec442f46ddd4512416ec43c2c2",
"ce064814f4a0d337b333e646ece456cd39fab612",
}, commitIDs)

commitIDs, err = GetCommitIDsBetweenReverse(t.Context(), repo,
"8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
"ce064814f4a0d337b333e646ece456cd39fab612",
"6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1",
100,
)
assert.NoError(t, err)
assert.Equal(t, []string{
"37991dec2c8e592043f47155ce4808d4580f9123",
"feaf4ba6bc635fec442f46ddd4512416ec43c2c2",
"ce064814f4a0d337b333e646ece456cd39fab612",
}, commitIDs)

commitIDs, err = GetCommitIDsBetweenReverse(t.Context(), repo,
"8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
"ce064814f4a0d337b333e646ece456cd39fab612",
"",
3,
)
assert.NoError(t, err)
assert.Equal(t, []string{
"37991dec2c8e592043f47155ce4808d4580f9123",
"feaf4ba6bc635fec442f46ddd4512416ec43c2c2",
"ce064814f4a0d337b333e646ece456cd39fab612",
}, commitIDs)

// test branch names instead of raw commit IDs.
commitIDs, err = GetCommitIDsBetweenReverse(t.Context(), repo,
"test",
"master",
"",
100,
)
assert.NoError(t, err)
assert.Equal(t, []string{
"feaf4ba6bc635fec442f46ddd4512416ec43c2c2",
"ce064814f4a0d337b333e646ece456cd39fab612",
}, commitIDs)

// add notref to exclude test
commitIDs, err = GetCommitIDsBetweenReverse(t.Context(), repo,
"test",
"master",
"test",
100,
)
assert.NoError(t, err)
assert.Equal(t, []string{
"feaf4ba6bc635fec442f46ddd4512416ec43c2c2",
"ce064814f4a0d337b333e646ece456cd39fab612",
}, commitIDs)
}
9 changes: 6 additions & 3 deletions services/agit/agit.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,12 +282,15 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
if err != nil {
return nil, fmt.Errorf("failed to load pull issue. Error: %w", err)
}
comment, err := pull_service.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i], forcePush.Value())
if err == nil && comment != nil {

isForcePush := forcePush.Value()
comment, commentCreated, err := pull_service.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i], isForcePush)
if err != nil {
log.Error("CreatePushPullComment: %v", err)
} else if commentCreated {
notify_service.PullRequestPushCommits(ctx, pusher, pr, comment)
}
notify_service.PullRequestSynchronized(ctx, pusher, pr)
isForcePush := comment != nil && comment.IsForcePush

results = append(results, private.HookProcReceiveRefResult{
OldOID: oldCommitID,
Expand Down
Loading