Commit 694ca4e4 authored by Nick Thomas's avatar Nick Thomas

Always use the newest commit in a branch for push events

Prior to this commit, when creating a new default branch, the push
event would reference the *oldest* commit in the branch, rather than
the newest. This is the opposite of what we do when creating any other
branch, or when updating any branch, whether it's the default branch or
not.

Even worse, when the new default branch contained more than 100 commits
we would return the 100th commit, rather than the oldest. This is
unambiguously a bug - that behaviour is not useful at all.

Fix the ordering of commits when pulling data from the default branch
so we always use the newest one when creating the default branch.

Changelog: fixed
parent 4280e2f3
...@@ -25,6 +25,7 @@ module Git ...@@ -25,6 +25,7 @@ module Git
raise NotImplementedError, "Please implement #{self.class}##{__method__}" raise NotImplementedError, "Please implement #{self.class}##{__method__}"
end end
# The changeset, ordered with the newest commit last
def commits def commits
raise NotImplementedError, "Please implement #{self.class}##{__method__}" raise NotImplementedError, "Please implement #{self.class}##{__method__}"
end end
...@@ -132,10 +133,10 @@ module Git ...@@ -132,10 +133,10 @@ module Git
end end
def event_push_data def event_push_data
# We only need the last commit for the event push, and we don't # We only need the newest commit for the event push, and we don't
# need the full deltas either. # need the full deltas either.
@event_push_data ||= Gitlab::DataBuilder::Push.build( @event_push_data ||= Gitlab::DataBuilder::Push.build(
**push_data_params(commits: commits.last, with_changed_files: false) **push_data_params(commits: limited_commits.last, with_changed_files: false)
) )
end end
......
...@@ -21,8 +21,9 @@ module Git ...@@ -21,8 +21,9 @@ module Git
def commits def commits
strong_memoize(:commits) do strong_memoize(:commits) do
if creating_default_branch? if creating_default_branch?
# The most recent PROCESS_COMMIT_LIMIT commits in the default branch # The most recent PROCESS_COMMIT_LIMIT commits in the default branch.
project.repository.commits(newrev, limit: PROCESS_COMMIT_LIMIT) # They are returned newest-to-oldest, but we need to present them oldest-to-newest
project.repository.commits(newrev, limit: PROCESS_COMMIT_LIMIT).reverse
elsif creating_branch? elsif creating_branch?
# Use the pushed commits that aren't reachable by the default branch # Use the pushed commits that aren't reachable by the default branch
# as a heuristic. This may include more commits than are actually # as a heuristic. This may include more commits than are actually
......
...@@ -94,7 +94,7 @@ Triggered when you push to the repository except when pushing tags. ...@@ -94,7 +94,7 @@ Triggered when you push to the repository except when pushing tags.
NOTE: NOTE:
When more than 20 commits are pushed at once, the `commits` webhook When more than 20 commits are pushed at once, the `commits` webhook
attribute only contains the first 20 for performance reasons. Loading attribute only contains the newest 20 for performance reasons. Loading
detailed commit data is expensive. Note that despite only 20 commits being detailed commit data is expensive. Note that despite only 20 commits being
present in the `commits` attribute, the `total_commits_count` attribute contains the actual total. present in the `commits` attribute, the `total_commits_count` attribute contains the actual total.
......
...@@ -92,7 +92,7 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do ...@@ -92,7 +92,7 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
end end
describe 'Push Event' do describe 'Push Event' do
let(:event) { Event.pushed_action.first } let(:event) { Event.pushed_action.take }
subject(:execute_service) { service.execute } subject(:execute_service) { service.execute }
...@@ -171,7 +171,7 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do ...@@ -171,7 +171,7 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
end end
end end
context "with a new branch" do context "with a new default branch" do
let(:oldrev) { Gitlab::Git::BLANK_SHA } let(:oldrev) { Gitlab::Git::BLANK_SHA }
it 'generates a push event with more than one commit' do it 'generates a push event with more than one commit' do
...@@ -183,12 +183,32 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do ...@@ -183,12 +183,32 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
expect(event.push_event_payload).to be_an_instance_of(PushEventPayload) expect(event.push_event_payload).to be_an_instance_of(PushEventPayload)
expect(event.push_event_payload.commit_from).to be_nil expect(event.push_event_payload.commit_from).to be_nil
expect(event.push_event_payload.commit_to).to eq(newrev) expect(event.push_event_payload.commit_to).to eq(newrev)
expect(event.push_event_payload.commit_title).to eq('Initial commit') expect(event.push_event_payload.commit_title).to eq('Change some files')
expect(event.push_event_payload.ref).to eq('master') expect(event.push_event_payload.ref).to eq('master')
expect(event.push_event_payload.commit_count).to be > 1 expect(event.push_event_payload.commit_count).to be > 1
end end
end end
context "with a new non-default branch" do
let(:oldrev) { Gitlab::Git::BLANK_SHA }
let(:branch) { 'fix' }
let(:commit_id) { project.commit(branch).id }
it 'generates a push event with more than one commit' do
execute_service
expect(event).to be_an_instance_of(PushEvent)
expect(event.project).to eq(project)
expect(event).to be_pushed_action
expect(event.push_event_payload).to be_an_instance_of(PushEventPayload)
expect(event.push_event_payload.commit_from).to be_nil
expect(event.push_event_payload.commit_to).to eq(newrev)
expect(event.push_event_payload.commit_title).to eq('Test file for directories with a leading dot')
expect(event.push_event_payload.ref).to eq('fix')
expect(event.push_event_payload.commit_count).to be > 1
end
end
context 'removing a branch' do context 'removing a branch' do
let(:newrev) { Gitlab::Git::BLANK_SHA } let(:newrev) { Gitlab::Git::BLANK_SHA }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment