diff options
author | Dmitriy Zaporozhets <dzaporozhets@gitlab.com> | 2014-12-02 16:20:50 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dzaporozhets@gitlab.com> | 2014-12-02 16:20:50 +0000 |
commit | c2e5343849fdfc24d7f363da7eb881214bf1b327 (patch) | |
tree | f8a5b9aef22e89c24db97b80cb04cdf54084c3af | |
parent | 1587c36b0489731c1248dfa3a6e8750ca5fcab88 (diff) | |
parent | 835cbc06d8d9c773a3b405eca81650378a8ccdcd (diff) | |
download | gitlab-ce-c2e5343849fdfc24d7f363da7eb881214bf1b327.tar.gz |
Merge branch 'improve-mr-reloading' into 'master'
Improve MR reloading
## Theory
Every time you pushed to master it updates merge requests that has master
as target branch. So if you have 50 open merge requests point to master
it will reload all of them every time you push a single commit to
master. The funny thing is that after reloading diff of most merge
requests looks the same.
After this patch we update diff only if we push commit to master that
includes in MR commits list.
For example we have next repository:
feature: A - B - C
master: A
We create merge request with code from feature to master.
MR: B - C
If we push to master commit D - MR will not be reloaded. So picture will
look next:
feature: A - B - C
master: A - D
MR: B - C
And if we push to master commit B - MR will be reloaded. So picture will
look next:
feature: A - B - C
master: A - B
MR: C
## Benchmark
For project with 45 open merge requests to master
Before
```
Benchmark post-receive | Cache and size: 0.060000 0.040000 0.100000 ( 0.379720)
Benchmark post-receive | Push commits selection: 0.130000 0.020000 0.150000 ( 0.149299)
Benchmark post-receive | Update merge requests: 9.180000 2.030000 11.210000 ( 11.971747)
Benchmark post-receive | Process commit messages: 0.140000 0.010000 0.150000 ( 0.168810)
Benchmark post-receive | Push data: 0.020000 0.000000 0.020000 ( 0.016363)
Benchmark post-receive | Push event and services: 0.030000 0.000000 0.030000 ( 0.088062)
```
After
```
Benchmark post-receive | Cache and size: 0.070000 0.030000 0.100000 ( 0.106676)
Benchmark post-receive | Push commits selection: 0.130000 0.020000 0.150000 ( 0.143081)
Benchmark post-receive | Update merge requests: 0.660000 0.210000 0.870000 ( 0.892663)
Benchmark post-receive | Process commit messages: 0.030000 0.000000 0.030000 ( 0.029263)
Benchmark post-receive | Push data: 0.020000 0.000000 0.020000 ( 0.018479)
Benchmark post-receive | Push event and services: 0.030000 0.000000 0.030000 ( 0.038230)
```
- - -
## References
Discussion in gitlab/gitlabhq#1796
See merge request !1288
-rw-r--r-- | app/services/merge_requests/refresh_service.rb | 23 | ||||
-rw-r--r-- | lib/gitlab/force_push_check.rb | 15 | ||||
-rw-r--r-- | lib/gitlab/git_access.rb | 9 |
3 files changed, 37 insertions, 10 deletions
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index 74448998ddd..baf0936cc3d 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -3,6 +3,7 @@ module MergeRequests def execute(oldrev, newrev, ref) return true unless ref =~ /heads/ + @oldrev, @newrev = oldrev, newrev @branch_name = ref.gsub("refs/heads/", "") @fork_merge_requests = @project.fork_merge_requests.opened @commits = @project.repository.commits_between(oldrev, newrev) @@ -35,6 +36,10 @@ module MergeRequests end end + def force_push? + Gitlab::ForcePushCheck.force_push?(@project, @oldrev, @newrev) + end + # Refresh merge request diff if we push to source or target branch of merge request # Note: we should update merge requests from forks too def reload_merge_requests @@ -43,8 +48,22 @@ module MergeRequests merge_requests = filter_merge_requests(merge_requests) merge_requests.each do |merge_request| - merge_request.reload_code - merge_request.mark_as_unchecked + + if merge_request.source_branch == @branch_name || force_push? + merge_request.reload_code + merge_request.mark_as_unchecked + else + mr_commit_ids = merge_request.commits.map(&:id) + push_commit_ids = @commits.map(&:id) + matches = mr_commit_ids & push_commit_ids + + if matches.any? + merge_request.reload_code + merge_request.mark_as_unchecked + else + merge_request.mark_as_unchecked + end + end end end diff --git a/lib/gitlab/force_push_check.rb b/lib/gitlab/force_push_check.rb new file mode 100644 index 00000000000..6a52cdba608 --- /dev/null +++ b/lib/gitlab/force_push_check.rb @@ -0,0 +1,15 @@ +module Gitlab + class ForcePushCheck + def self.force_push?(project, oldrev, newrev) + return false if project.empty_repo? + + if oldrev != Gitlab::Git::BLANK_SHA && newrev != Gitlab::Git::BLANK_SHA + missed_refs = IO.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev})).read + missed_refs.split("\n").size > 0 + else + false + end + end + end +end + diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 5f8cb19efdf..8b4729896b5 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -94,14 +94,7 @@ module Gitlab end def forced_push?(project, oldrev, newrev) - return false if project.empty_repo? - - if oldrev != Gitlab::Git::BLANK_SHA && newrev != Gitlab::Git::BLANK_SHA - missed_refs = IO.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev})).read - missed_refs.split("\n").size > 0 - else - false - end + Gitlab::ForcePushCheck.force_push?(project, oldrev, newrev) end private |