Merge Request on forked projects
Created by: karlhungus
The good:
- You can do a merge request for a forked commit and it will merge properly (i.e. it does work).
- Push events take into account merge requests on forked projects
- Tests around merge_actions now present, spinach, and other rspec tests
- Satellites now clean themselves up rather then recreate
The questionable:
- Events only know about target projects
- Project's merge requests only hold on to MR's where they are the target
- All operations performed in the satellite -- Not completely true anymore, post review with @randx, non forking MR's now do some operations in the projects repo
The bad:
- Duplication between project's repositories and satellites (e.g. commits_between) No longer the case, post review with @randx
(for reference: http://feedback.gitlab.com/forums/176466-general/suggestions/3456722-merge-requests-between-projects-repos)
Fixes:
Make test repos/satellites only create when needed -Spinach/Rspec now only initialize test directory, and setup stubs (things that are relatively cheap) -project_with_code, source_project_with_code, and target_project_with_code now create/destroy their repos individually -fixed remote removal -How to merge renders properly -Update emails to show project/branches -Edit MR doesn't set target branch -Fix some failures on editing/creating merge requests, added a test -Added back a test around merge request observer -Clean up project_transfer_spec, Remove duplicate enable/disable observers -Ensure satellite lock files are cleaned up, Attempted to add some testing around these as well -Signifant speed ups for tests -Update formatting ordering in notes_on_merge_requests -Remove wiki schema update Fixes for search/search results -Search results was using by_project for a list of projects, updated this to use in_projects -updated search results to reference the correct (target) project -udpated search results to print both sides of the merge request
Reference to old PR: https://github.com/gitlabhq/gitlabhq/pull/4051
Merge request reports
Activity
Created by: karlhungus
There are still three known issues with this (I'll submit fixes for these in the coming days): -notes on commits take you to the wrong project -api should error out if a target project is specified that source project is not a fork of. -I get intermittent failures on: ./spec/features/notes_on_merge_requests_spec.rb:173. and ./spec/services/notification_service_spec.rb:12
Would really appreciate any feedback, especially from core developers.
By Administrator on 2013-06-03T20:34:25 (imported from GitLab project)
By Administrator on 2013-06-03T20:34:25 (imported from GitLab)
Created by: coveralls
Coverage increased (+0%) when pulling 8286960f68aa173781c99c5441aece31ff92785a on karlhungus:mr-on-fork into 0611c5c6 on gitlabhq:master.
By Administrator on 2013-06-03T19:38:50 (imported from GitLab project)
By Administrator on 2013-06-03T19:38:50 (imported from GitLab)
Created by: MrKeiKun
i have a question have you tested this system with gitlab-ci? what if the project your forked is under gitlab-ci will it build whenever you do merge request?
By Administrator on 2013-06-05T18:06:45 (imported from GitLab project)
By Administrator on 2013-06-05T18:06:45 (imported from GitLab)
Created by: karlhungus
I haven't run it against gitlab-ci -- I'm not aware how gitlab-ci is triggered, I'd expect it would be hooked on the push back to master (if this is the case then the build will get triggered). Do you know if existing merge requests trigger ci builds; if they do then this should as well -- the code for the final push back to the target is identical.
Below i've highlighted how the part where the push back to master happens; default_options is the same hash as the original -- i extracted it since it gets used in multiple places.
By Administrator on 2013-06-05T18:57:11 (imported from GitLab project)
By Administrator on 2013-06-05T18:57:11 (imported from GitLab)
21 # pushes it back to the repository. 22 # It also removes the source branch if requested in the merge request (and this is permitted by the merge request). 22 23 # 23 24 # Returns false if the merge produced conflicts 24 # Returns false if pushing from the satellite to Gitolite failed or was rejected 25 # Returns false if pushing from the satellite to the repository failed or was rejected 25 26 # Returns true otherwise 26 27 def merge! 27 28 in_locked_and_timed_satellite do |merge_repo| 29 prepare_satellite!(merge_repo) 28 30 if merge_in_satellite!(merge_repo) 29 31 # push merge back to Gitolite 30 32 # will raise CommandFailed when push fails 31 merge_repo.git.push({raise: true, timeout: true}, :origin, merge_request.target_branch) 32 33 merge_repo.git.push(default_options, :origin, merge_request.target_branch) Created by: karlhungus
With the above fixes, i still have some remaining:
-Address TODO's -There are currently multiple calls to the satellite code, and the satellite code has a tendency to silently fail -I get intermittent failures on: ./spec/features/notes_on_merge_requests_spec.rb:173. and ./spec/services/notification_service_spec.rb:12
My intent here is: -to prevent multiple calls with lazy initialization (which i'm not a huge fan of)), -log the failures that occur in the satellite -change the return type to a token with the status, and value someting like
SatelliteResult, this way we can query if the result was a success etc etc.
By Administrator on 2013-06-05T20:33:29 (imported from GitLab project)
By Administrator on 2013-06-05T20:33:29 (imported from GitLab)
Created by: karlhungus
So that's what a force push does on github! :)...
I've got my fixes to the satellite code mostly done, I think in the interest of keeping this already large commit to a reasonable size i'll keep from doing the "SatelliteResult" thing.
By Administrator on 2013-06-07T16:48:39 (imported from GitLab project)
By Administrator on 2013-06-07T16:48:39 (imported from GitLab)
Created by: coveralls
Coverage decreased (-0%) when pulling 12c50ea885e89ae45a07e8209d7955793589bd68 on karlhungus:mr-on-fork into d0357f3b on gitlabhq:master.
By Administrator on 2013-06-07T17:10:23 (imported from GitLab project)
By Administrator on 2013-06-07T17:10:23 (imported from GitLab)
Created by: coveralls
Coverage decreased (-0%) when pulling 7c660994fde9d7503939b8d0c989607982bfb78c on karlhungus:mr-on-fork into d0357f3b on gitlabhq:master.
By Administrator on 2013-06-07T17:07:35 (imported from GitLab project)
By Administrator on 2013-06-07T17:07:35 (imported from GitLab)
Created by: coveralls
Coverage increased (+0%) when pulling 7c660994fde9d7503939b8d0c989607982bfb78c on karlhungus:mr-on-fork into d0357f3b on gitlabhq:master.
By Administrator on 2013-06-07T17:21:27 (imported from GitLab project)
By Administrator on 2013-06-07T17:21:27 (imported from GitLab)
Created by: karlhungus
I'm still based on http://ci.gitlab.org/projects/1/builds/d0357f3bbe9258bcb2ca9732e25f34fc9933af57, so i'm getting some failing tests from that build, but the rest seems fine
By Administrator on 2013-06-07T20:41:42 (imported from GitLab project)
By Administrator on 2013-06-07T20:41:42 (imported from GitLab)
Created by: coveralls
Coverage increased (+0%) when pulling 9d64deb9332ee6abdb101b73bd229fa2484189a7 on karlhungus:mr-on-fork into d0357f3b on gitlabhq:master.
By Administrator on 2013-06-07T20:59:27 (imported from GitLab project)
By Administrator on 2013-06-07T20:59:27 (imported from GitLab)
Created by: coveralls
Coverage decreased (-0%) when pulling a80ab85533c8b68a7ce738c2c77351e618e85eb7 on karlhungus:mr-on-fork into 05bc6589 on gitlabhq:master.
By Administrator on 2013-06-08T20:51:50 (imported from GitLab project)
By Administrator on 2013-06-08T20:51:50 (imported from GitLab)
Created by: karlhungus
@randx I added source/target project to merge request, as the basic requirement. I choose not to encapsulate these with the source/target branch to avoid changes, this might be a good future refactoring, giving an opportunity to move any presentation logic/equality logic on to that.
This lead to me having to decide which project owned the merge request, target was the obvious choice because it is the receiver of the change and therefore should deal with the change. Another option would be to have the source own the project, i couldn't think of a reason you'd want that, and it seemed like it would make any presentation of merge requests very difficult.
I pushed all logic dealing with repositories to the satellites, because it would require adding forks in the merge case, this seemed like the simplest solution to contain both problems. I didn't remove the commits_between etc from the Repository class, but i think removing that duplication or pushing it to the satellite level is probably a sane thing to do. I also didn't preserve state between any satellite operations, there is opportunity for optimization here, but it seemed like correctness should have precedence.
I added significant tests to the satellite code, I think this is a big win for gitlab. To do this I had to have a clone of the repo, this lead to some pretty extensive changes to the tests (at first because my additions made them very slow, then subsequent changes to make them fast(ish) again). I added a source/target project as extensions of the project_with_code factory, these still are symbolic links to the same root project. I also extended the project_with_code factories to have satellites, to allow the testing of the satellite code.
I changed merge request artifacts to reflect their project/namespace as well as their branch.
Events i dealt with on a case by case basis, but i did not associate them with two projects, just with the target.
By Administrator on 2013-06-26T14:02:19 (imported from GitLab project)
By Administrator on 2013-06-26T14:02:19 (imported from GitLab)
Created by: karlhungus
@randx continuing the explanation above:
The addition of the source/target projects to merge request meant I had to handle that case in the observers, and notifications. For observers i made another one for merge requests, the assigned project is always the target project (I'm not sure that is always the correct answer, but I think it is). For notifications i changed the methods to take the project as well as the target.
In order to handle the
@project
not being the container for a given commit/note I modified these haml files to take the project as a variable (this could lead to confusion, as the only difference is that one is an inst var). This allowed a merge request that is owned by a target to click on a commit/note that is owned by the source, and still get to the correct place.There could be some confusion in that people using back and forward on a merge of fork project will be switching between owning projects, I can't really think of a better way to do this however; also i think it can wait.
I did disallow the removal of the source branch on a merge on fork, I saw later that github allows this however, so maybe it's worth putting in (I think this can also wait however).
I should be available tomorrow around 9am (EST), we have a stand up at 10am, but i'll try to keep an eye out for you.
By Administrator on 2013-06-26T19:19:39 (imported from GitLab project)
By Administrator on 2013-06-26T19:19:39 (imported from GitLab)
Created by: karlhungus
@randx Let me know when a good time to talk to you about this is -- or if you just want me to add more details to the PR (or if you've got enough as is). Best times for me are generally 9-5 EST weekdays (july 1st monday i'm off -- canada day).
I could also re-trigger the build if that helps not positive why it wouldn't have run db:migrate (it has in the past) -- Ugh, kind of missed this one, will try to reproduce on my machine. All right, so db:migrate seems to work on a fresh install for me -- possible you could try this? I'll look at re-triggering it tonight
After looking at the failure, and making several commits i realized it's not something i've introduced...so leaving this for now, please feel free to contact me if you want me to rebsae and retrigger, or if you want some explination
By Administrator on 2013-06-30T04:24:05 (imported from GitLab project)
By Administrator on 2013-06-30T04:24:05 (imported from GitLab)
Created by: coveralls
Coverage remained the same when pulling bf988371bc7a1bf05eae2305a5be303a70c3c85f on karlhungus:mr-on-fork into 315d4cc8 on gitlabhq:master.
By Administrator on 2013-07-01T00:37:26 (imported from GitLab project)
By Administrator on 2013-07-01T00:37:26 (imported from GitLab)
1 Feature: Project Forked Merge Requests 2 Background: 3 Given I sign in as a user 4 And I am a member of project "Shop" 5 And I have a project forked off of "Shop" called "Forked Shop" 6 7 @javascript 1 class ProjectForkedMergeRequests < Spinach::FeatureSteps 2 include SharedAuthentication 3 include SharedProject 4 include SharedNote 5 include SharedPaths 6 7 Given 'I am a member of project "Shop"' do 8 @project = Project.find_by_name "Shop" 1 1 require 'spec_helper' 2 2 3 3 INVALID_FACTORIES = [ 4 :key_with_a_space_in_the_middle, 5 :invalid_key, 4 :key_with_a_space_in_the_middle, 5 :invalid_key, 6 6 ] 7 7 8 8 FactoryGirl.factories.map(&:name).each do |factory_name| 1 1 = "Merge Request #{@merge_request.id} was merged" 2 2 3 Merge Request Url: #{project_merge_request_url(@merge_request.project, @merge_request)} 3 Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} 4 4 5 Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch} 5 = merge_path_description(@merge_request, 'to') 1 1 %p 2 2 = "New Merge Request !#{@merge_request.id}" 3 3 %p 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request) 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) 5 5 %p 6 Branches: #{@merge_request.source_branch} → #{@merge_request.target_branch} 6 != merge_path_description(@merge_request, '→') 1 1 = "Merge Request #{@merge_request.id} was closed by #{@updated_by.name}" 2 2 3 Merge Request url: #{project_merge_request_url(@merge_request.project, @merge_request)} 3 Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} 4 4 5 Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch} 5 = merge_path_description(@merge_request, 'to') Created by: karlhungus
@randx I'm still available for any help explaining this, I know we have a bit of a timezone mismatch, but if you'd have good times that work for you let me know I'll see if i can schedule around them.
By Administrator on 2013-07-12T19:03:09 (imported from GitLab project)
By Administrator on 2013-07-12T19:03:09 (imported from GitLab)
Created by: dzaporozhets
@karlhungus also it will be great if you can do it mergeable. Since
6-0-dev
merged in master it may take some effort to get it mergeable.By Administrator on 2013-07-15T07:28:09 (imported from GitLab project)
By Administrator on 2013-07-15T07:28:09 (imported from GitLab)
Created by: karlhungus
@randx Weird, i didn't get (emailed) your first comment -- I'm available for all of today, will start on making it mergable again after morning coffee :)
By Administrator on 2013-07-15T13:01:05 (imported from GitLab project)
By Administrator on 2013-07-15T13:01:05 (imported from GitLab)
Created by: karlhungus
@karlhungus also it will be great if you can do it mergeable. Since 6-0-dev merged in master it may take some effort to get it mergeable.
@randx Why couldn't you have merged my stuff earlier! this is awful!
By Administrator on 2013-07-15T15:11:06 (imported from GitLab project)
By Administrator on 2013-07-15T15:11:06 (imported from GitLab)
Created by: karlhungus
@randx sorry for the outburst, just a bit frustrated at having to redo work. I'm on campfire if you want to go over what i have. I'm still in the midst of the merge, i think going over the code i have posted is still useful. I'll push the merged base asap
By Administrator on 2013-07-15T15:59:23 (imported from GitLab project)
By Administrator on 2013-07-15T15:59:23 (imported from GitLab)
Created by: karlhungus
@ShidoKun @bertjwregeer It looks like they won't go out until 6.0 is released (based purely off the milestone setting). I'm not privy to the meaning of that being: 6 will be the next release or a release next month.
By Administrator on 2013-07-15T18:11:44 (imported from GitLab project)
By Administrator on 2013-07-15T18:11:44 (imported from GitLab)
Created by: coveralls
Coverage increased (+0%) when pulling 585f28d84ceee8fbe98e02dc90b91cc583667312 on karlhungus:mr-on-fork into a6cfb54c on gitlabhq:master.
By Administrator on 2013-07-15T21:39:29 (imported from GitLab project)
By Administrator on 2013-07-15T21:39:29 (imported from GitLab)
Unable to load the diff 19 # merge_status :string(255) 19 20 # 20 21 21 22 require Rails.root.join("app/models/commit") 22 23 require Rails.root.join("lib/static_model") 23 24 24 25 class MergeRequest < ActiveRecord::Base 26 25 27 include Issuable 26 28 27 attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id, 28 :author_id_of_changes, :state_event 29 belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project" 30 belongs_to :source_project, foreign_key: :source_project_id, class_name: "Project" 31 32 attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :author_id_of_changes, :state_event 15 33 16 34 def after_reopen(merge_request, transition) 17 Note.create_status_change_note(merge_request, current_user, merge_request.state) 35 create_event(merge_request, Event::REOPENED) 36 Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state) 18 37 end 19 38 20 39 def after_update(merge_request) 21 40 notification.reassigned_merge_request(merge_request, current_user) if merge_request.is_being_reassigned? 22 41 end 42 43 def create_event(record, status) 44 Event.create( 45 project: record.target_project, 46 target_id: record.id, 47 target_type: record.class.name, 7 Note.create_status_change_note(merge_request, current_user, merge_request.state) 13 create_event(merge_request, Event::CLOSED) 14 Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state) 8 15 9 16 notification.close_mr(merge_request, current_user) 10 17 end 11 18 12 19 def after_merge(merge_request, transition) 13 20 notification.merge_mr(merge_request) 21 # Since MR can be merged via sidekiq 22 # to prevent event duplication do this check 23 return true if merge_request.merge_event 24 25 Event.create( 26 project: merge_request.target_project, 27 target_id: merge_request.id, 1 class MergeRequestObserver < BaseObserver 1 class MergeRequestObserver < ActivityObserver 2 observe :merge_request 3 2 4 def after_create(merge_request) 5 if merge_request.author_id 6 create_event(merge_request, Event.determine_action(merge_request)) 7 end 8 Created by: dzaporozhets
why not just
if merge_request.author_id create_event(merge_request, Event.determine_action(merge_request)) end
Why add extra variable?
By Administrator on 2013-07-30T20:19:35 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:35 (imported from GitLab)
3 3 .title 4 4 %i.icon-calendar 5 5 %span= day.stamp("28 Aug, 2010") 6 7 6 .pull-right 8 7 %small= pluralize(commits.count, 'commit') 9 %ul.well-list= render commits 8 %ul.well-list= render commits, project: @project 1 class AllowMergesForForks < ActiveRecord::Migration 2 3 def self.up 4 add_column :merge_requests, :target_project_id, :integer, :null => false 5 MergeRequest.update_all("target_project_id = project_id") 97 find("#merge_request_target_branch").value.should have_content "master" 98 find("#merge_request_title").value.should == "New Design" 99 verify_commit_link(".mr_target_commit",@project) 100 verify_commit_link(".mr_source_commit",@forked_project) 101 end 102 103 And 'I update the merge request title' do 104 fill_in "merge_request_title", with: "An Edited Forked Merge Request" 105 end 106 107 And 'I save the merge request' do 108 click_button "Save changes" 109 end 110 111 Then 'I should see the edited merge request' do 112 page.should have_content "An Edited Forked Merge Request" 113 @project.merge_requests.size.should >= 1 114 @merge_request = @project.merge_requests.last 115 current_path.should == project_merge_request_path(@project, @merge_request) 116 @merge_request.source_project.should == @forked_project 117 @merge_request.source_branch.should == "master" 118 @merge_request.target_branch.should == "stable" 119 page.should have_content @forked_project.path_with_namespace 120 page.should have_content @project.path_with_namespace 121 page.should have_content @merge_request.source_branch 122 page.should have_content @merge_request.target_branch 123 end 124 125 Then 'I should see last push widget' do 126 page.should have_content "You pushed to new_design" 127 page.should have_link "Create Merge Request" 128 end 16 # st_diffs :text(2147483647) 17 # milestone_id :integer 18 # state :string(255) 19 # merge_status :string(255) 19 20 # 20 21 21 22 require Rails.root.join("app/models/commit") 22 23 require Rails.root.join("lib/static_model") 23 24 24 25 class MergeRequest < ActiveRecord::Base 26 25 27 include Issuable 26 28 27 attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id, 28 :author_id_of_changes, :state_event 29 belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project" 96 117 source_branch "stable" # pretend bcf03b5d 97 118 st_commits do 98 119 [ 99 project.repository.commit('bcf03b5d').to_hash, 100 project.repository.commit('bcf03b5d~1').to_hash, 101 project.repository.commit('bcf03b5d~2').to_hash 120 source_project.repository.commit('bcf03b5d').to_hash, 121 source_project.repository.commit('bcf03b5d~1').to_hash, 122 source_project.repository.commit('bcf03b5d~2').to_hash - spec/lib/gitlab/satellite/action_spec.rb 0 → 100644
39 40 #verify it's clean 41 heads = repo.heads.map(&:name) 42 heads.size.should == 1 43 heads.include?(Gitlab::Satellite::Satellite::PARKING_BRANCH).should == true 44 remotes = repo.git.remote().split(' ') 45 remotes.size.should == 1 46 remotes.include?('origin').should == true 47 repo.config['user.name'].should ==user.name 48 repo.config['user.email'].should ==user.email 49 end 50 end 51 52 describe '#in_locked_and_timed_satellite' do 53 54 it 'should make use of a lockfile' do - spec/lib/gitlab/satellite/action_spec.rb 0 → 100644
1 require 'spec_helper' 2 3 describe 'Gitlab::Satellite::Action' do 4 let(:project) { create(:project_with_code) } 5 let(:user) { create(:user) } 6 7 describe '#prepare_satellite!' do 8 9 it 'create a repository with a parking branch and one remote: origin' do - spec/lib/gitlab/satellite/action_spec.rb 0 → 100644
1 require 'spec_helper' 2 3 describe 'Gitlab::Satellite::Action' do 4 let(:project) { create(:project_with_code) } 5 let(:user) { create(:user) } 137 149 end 138 150 139 151 def unmerged_diffs 140 project.repository.diffs_between(source_branch, target_branch) 152 if for_fork? 153 diffs = Gitlab::Satellite::MergeAction.new(author, self).diffs_between_satellite 154 else 155 diffs = target_project.repository.diffs_between(source_branch, target_branch) Created by: karlhungus
for non forks, move back to the old method, remove the forking check from the satellite
for non fork use origional, push repo reference into project.repostiory
By Administrator on 2013-07-30T20:19:35 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:35 (imported from GitLab)
Unable to load the diff Created by: karlhungus
for non forks, move back to the old method, remove the forking check from the satellite
for non fork use original, push repo reference into project.repostiory
By Administrator on 2013-07-30T20:19:35 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:35 (imported from GitLab)
62 62 def commit_author 63 63 @commit_author ||= 64 64 project.users.find_by_email(noteable.author_email) || 65 project.users.find_by_name(noteable.author_name) 65 project.users.find_by_name(noteable.author_name) Unable to load the diff Created by: karlhungus
change to: recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project) recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq
By Administrator on 2013-07-30T20:19:35 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:35 (imported from GitLab)
1 1 %p 2 2 = "Merge Request #{@merge_request.id} was closed by #{@updated_by.name}" 3 3 %p 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request) 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) 5 5 %p 6 Branches: #{@merge_request.source_branch} → #{@merge_request.target_branch} 6 != merge_path_description(@merge_request, '→') 1 1 = "Merge Request #{@merge_request.id} was closed by #{@updated_by.name}" 2 2 3 Merge Request url: #{project_merge_request_url(@merge_request.project, @merge_request)} 3 Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} 4 4 5 Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch} 5 = merge_path_description(@merge_request, 'to') 1 1 %p 2 2 = "Merge Request #{@merge_request.id} was merged" 3 3 %p 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request) 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) 5 5 %p 6 Branches: #{@merge_request.source_branch} → #{@merge_request.target_branch} 6 != merge_path_description(@merge_request, '→') 1 1 = "Merge Request #{@merge_request.id} was merged" 2 2 3 Merge Request Url: #{project_merge_request_url(@merge_request.project, @merge_request)} 3 Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} 4 4 5 Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch} 5 = merge_path_description(@merge_request, 'to') 1 1 %p 2 2 = "New Merge Request !#{@merge_request.id}" 3 3 %p 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request) 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) 5 5 %p 6 Branches: #{@merge_request.source_branch} → #{@merge_request.target_branch} 6 != merge_path_description(@merge_request, '→') 1 1 New Merge Request <%= @merge_request.id %> 2 2 3 <%= url_for(project_merge_request_url(@merge_request.project, @merge_request)) %> 4 3 <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> 5 4 6 Branches: <%= @merge_request.source_branch %> to <%= @merge_request.target_branch %> 5 <%= merge_path_description(@merge_request, 'to') %> 1 1 %li{ class: mr_css_classes(merge_request) } 2 2 .merge-request-title 3 3 %span.light= "##{merge_request.id}" 4 = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.project, merge_request), class: "row_title" 4 = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.target_project, merge_request), class: "row_title" 5 5 - if merge_request.merged? 6 6 %small.pull-right 7 7 %i.icon-ok 8 8 = "MERGED" 9 9 - else 10 10 %span.pull-right 11 %i.icon-angle-right 12 = merge_request.target_branch 11 - if merge_request.for_fork? 12 = "#{merge_request.source_project.path_with_namespace}/#{merge_request.source_branch}" 13 %i.icon-angle-right 1 1 %h3.page-title 2 2 = "Merge Request ##{@merge_request.id}:" 3 3 22 22 - @merge_requests.each do |merge_request| 23 23 %li 24 24 merge request: 25 = link_to [merge_request.project, merge_request] do 25 = link_to [merge_request.target_project, merge_request] do 26 26 %span ##{merge_request.id} 27 27 %strong.term 28 28 = truncate merge_request.title, length: 50 29 %span.light (#{merge_request.project.name_with_namespace}) 8 Scenario: I can visit the target projects commit for a forked merge request 9 Given I visit project "Forked Shop" merge requests page 10 And I click link "New Merge Request" 11 And I fill out a "Merge Request On Forked Project" merge request 12 And I follow the target commit link 13 Then I should see the commit under the forked from project 14 15 @javascript 16 Scenario: I submit new unassigned merge request to a forked project 17 Given I visit project "Forked Shop" merge requests page 18 And I click link "New Merge Request" 19 And I fill out a "Merge Request On Forked Project" merge request 20 And I submit the merge request 21 Then I should see merge request "Merge Request On Forked Project" 22 23 @javascript 27 Then I should see last push widget 28 And I click "Create Merge Request on fork" link 29 Then I see prefilled new Merge Request page for the forked project 30 31 @javascript 32 Scenario: I can edit a forked merge request 33 Given I visit project "Forked Shop" merge requests page 34 And I click link "New Merge Request" 35 And I fill out a "Merge Request On Forked Project" merge request 36 And I submit the merge request 37 And I should see merge request "Merge Request On Forked Project" 38 And I click link edit "Merge Request On Forked Project" 39 Then I see the edit page prefilled for "Merge Request On Forked Project" 40 And I update the merge request title 41 And I save the merge request 42 Then I should see the edited merge request Unable to load the diff Created by: karlhungus
how about
if target_project_id.nil? || target_project_id == user_project.id.to_s merge_request.target_project = user_project else if user_project.forked? && user_project.forked_from_project.id.to_s == target_project_id merge_request.target_project = Project.find_by_id(attrs[:target_project_id]) else render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400) end end
Not much better...I could extract some methods:
if !fork(target_project_id, user_project) merge_request.target_project = user_project else if target_matches_fork(target_project_id,user_project) merge_request.target_project = Project.find_by_id(attrs[:target_project_id]) else render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400) end end
any suggestions welcome
By Administrator on 2013-07-30T20:19:35 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:35 (imported from GitLab)
33 31 ensure 34 32 Gitlab::ShellEnv.reset_env 35 33 end 36 34 37 # * Clears the satellite 38 # * Updates the satellite from Gitolite 35 # * Recreates the satellite 39 36 # * Sets up Git variables for the user 40 37 # 41 38 # Note: use this within #in_locked_and_timed_satellite 42 39 def prepare_satellite!(repo) 43 40 project.satellite.clear_and_update! 44 41 45 repo.git.config({}, "user.name", user.name) 46 repo.git.config({}, "user.email", user.email) 42 repo.config['user.name'] = user.name 34 32 Gitlab::ShellEnv.reset_env 35 33 end 36 34 37 # * Clears the satellite 38 # * Updates the satellite from Gitolite 35 # * Recreates the satellite 39 36 # * Sets up Git variables for the user 40 37 # 41 38 # Note: use this within #in_locked_and_timed_satellite 42 39 def prepare_satellite!(repo) 43 40 project.satellite.clear_and_update! 44 41 45 repo.git.config({}, "user.name", user.name) 46 repo.git.config({}, "user.email", user.email) 42 repo.config['user.name'] = user.name 43 repo.config['user.email'] = user.email 120 def remove_remotes! 121 remotes = repo.git.remote.split(' ') 122 remotes.delete('origin') 123 remotes.each { |name| repo.git.remote(default_options,'rm', name)} 110 124 end 111 125 112 126 # Updates the satellite from Gitolite 113 127 # 114 128 # Note: this will only update remote branches (i.e. origin/*) 115 129 def update_from_source! 116 repo.git.fetch({timeout: true}, :origin) 130 repo.git.fetch(default_options, :origin) 131 end 132 133 def default_options(options = {}) 134 {raise: true, timeout: true}.merge(options) 41 it 'should raise exception -- not expected to be used by non forks' do 42 merge_request.target_branch = @one_after_stable[0] 43 merge_request.source_branch = @master[0] 44 expect {Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between}.to raise_error 45 46 merge_request.target_branch = @wiki_branch[0] 47 merge_request.source_branch = @master[0] 48 expect {Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between}.to raise_error 49 end 50 end 51 end 52 53 describe '#format_patch' do 54 let(:target_commit) {['artiom-config-examples','9edbac5ac88ffa1ec9dad0097226b51e29ebc9ac']} 55 let(:source_commit) {['metior', '313d96e42b313a0af5ab50fa233bf43e27118b3f']} 56 64 65 (patch.include? 'e74fae147abc7d2ffbf93d363dbbe45b87751f6f').should be_false 66 (patch.include? '86f76b11c670425bbab465087f25172378d76147').should be_false 67 end 68 69 context 'on fork' do 70 it 'should build a format patch' do 71 merge_request_fork.target_branch = target_commit[0] 72 merge_request_fork.source_branch = source_commit[0] 73 patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch 74 verify_content(patch) 75 end 76 end 77 78 context 'between branches' do 79 it 'should build a format patch' do 107 merge_request_fork.source_branch = @master[0] 108 diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request_fork).diff_in_satellite 109 110 is_a_matching_diff(diff, diffs) 111 end 112 end 113 114 context 'between branches' do 115 it 'should get proper diffs' do 116 merge_request.target_branch = @close_commit1[0] 117 merge_request.source_branch = @master[0] 118 expect{Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite}.to raise_error 119 end 120 end 121 end 122 71 72 describe '#for_fork?' do 73 it 'returns true if the merge request is for a fork' do 74 subject.source_project = create(:source_project) 75 subject.target_project = create(:target_project) 76 77 subject.for_fork?.should be_true 78 end 79 it 'returns false if is not for a fork' do 80 subject.source_project = create(:source_project) 81 subject.target_project = subject.source_project 82 subject.for_fork?.should be_false 83 end 84 end 85 86 describe '#allow_source_branch_removal?' do 78 Note.should_receive(:create_status_change_note).with(closed_assigned_mr, some_user, 'reopened') 80 Note.should_receive(:create_status_change_note).with(closed_assigned_mr, closed_assigned_mr.target_project, some_user, 'reopened') 79 81 80 82 closed_assigned_mr.reopen 81 83 end 82 84 83 85 it 'notification is delivered only to author if the merge request is being reopened' do 84 Note.should_receive(:create_status_change_note).with(closed_unassigned_mr, some_user, 'reopened') 86 Note.should_receive(:create_status_change_note).with(closed_unassigned_mr, closed_unassigned_mr.target_project, some_user, 'reopened') 85 87 86 88 closed_unassigned_mr.reopen 87 89 end 88 90 end 89 91 end 92 93 describe "Merge Request created" do 50 74 Gitlab::Satellite::Satellite.any_instance.stub( 51 75 exists?: true, 52 76 destroy: true, 53 create: true 77 create: true, 78 lock_files_dir: repos_path Unable to load the diff Created by: karlhungus
done (as well as reverting the pre-forked behavour for non-fork MR's)
def unmerged_commits if for_fork? commits = Gitlab::Satellite::MergeAction.new(self.author, self).commits_between else commits = self.project.repository.commits_between(self.target_branch, self.source_branch) end if commits.present? commits = Commit.decorate(commits). sort_by(&:created_at). reverse end commits end
By Administrator on 2013-07-30T20:19:35 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:35 (imported from GitLab)
15 33 16 34 def after_reopen(merge_request, transition) 17 Note.create_status_change_note(merge_request, current_user, merge_request.state) 35 create_event(merge_request, Event::REOPENED) 36 Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state) 18 37 end 19 38 20 39 def after_update(merge_request) 21 40 notification.reassigned_merge_request(merge_request, current_user) if merge_request.is_being_reassigned? 22 41 end 42 43 def create_event(record, status) 44 Event.create( 45 project: record.target_project, 46 target_id: record.id, 47 target_type: record.class.name, 7 Note.create_status_change_note(merge_request, current_user, merge_request.state) 13 create_event(merge_request, Event::CLOSED) 14 Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state) 8 15 9 16 notification.close_mr(merge_request, current_user) 10 17 end 11 18 12 19 def after_merge(merge_request, transition) 13 20 notification.merge_mr(merge_request) 21 # Since MR can be merged via sidekiq 22 # to prevent event duplication do this check 23 return true if merge_request.merge_event 24 25 Event.create( 26 project: merge_request.target_project, 27 target_id: merge_request.id, 1 class MergeRequestObserver < BaseObserver 1 class MergeRequestObserver < ActivityObserver 2 observe :merge_request 3 2 4 def after_create(merge_request) 5 if merge_request.author_id 6 create_event(merge_request, Event.determine_action(merge_request)) 7 end 8 3 3 .title 4 4 %i.icon-calendar 5 5 %span= day.stamp("28 Aug, 2010") 6 7 6 .pull-right 8 7 %small= pluralize(commits.count, 'commit') 9 %ul.well-list= render commits 8 %ul.well-list= render commits, project: @project 1 class AllowMergesForForks < ActiveRecord::Migration 2 3 def self.up 4 add_column :merge_requests, :target_project_id, :integer, :null => false 5 MergeRequest.update_all("target_project_id = project_id") 97 find("#merge_request_target_branch").value.should have_content "master" 98 find("#merge_request_title").value.should == "New Design" 99 verify_commit_link(".mr_target_commit",@project) 100 verify_commit_link(".mr_source_commit",@forked_project) 101 end 102 103 And 'I update the merge request title' do 104 fill_in "merge_request_title", with: "An Edited Forked Merge Request" 105 end 106 107 And 'I save the merge request' do 108 click_button "Save changes" 109 end 110 111 Then 'I should see the edited merge request' do 112 page.should have_content "An Edited Forked Merge Request" 113 @project.merge_requests.size.should >= 1 114 @merge_request = @project.merge_requests.last 115 current_path.should == project_merge_request_path(@project, @merge_request) 116 @merge_request.source_project.should == @forked_project 117 @merge_request.source_branch.should == "master" 118 @merge_request.target_branch.should == "stable" 119 page.should have_content @forked_project.path_with_namespace 120 page.should have_content @project.path_with_namespace 121 page.should have_content @merge_request.source_branch 122 page.should have_content @merge_request.target_branch 123 end 124 125 Then 'I should see last push widget' do 126 page.should have_content "You pushed to new_design" 127 page.should have_link "Create Merge Request" 128 end 16 # st_diffs :text(2147483647) 17 # milestone_id :integer 18 # state :string(255) 19 # merge_status :string(255) 19 20 # 20 21 21 22 require Rails.root.join("app/models/commit") 22 23 require Rails.root.join("lib/static_model") 23 24 24 25 class MergeRequest < ActiveRecord::Base 26 25 27 include Issuable 26 28 27 attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id, 28 :author_id_of_changes, :state_event 29 belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project" 96 117 source_branch "stable" # pretend bcf03b5d 97 118 st_commits do 98 119 [ 99 project.repository.commit('bcf03b5d').to_hash, 100 project.repository.commit('bcf03b5d~1').to_hash, 101 project.repository.commit('bcf03b5d~2').to_hash 120 source_project.repository.commit('bcf03b5d').to_hash, 121 source_project.repository.commit('bcf03b5d~1').to_hash, 122 source_project.repository.commit('bcf03b5d~2').to_hash - spec/lib/gitlab/satellite/action_spec.rb 0 → 100644
39 40 #verify it's clean 41 heads = repo.heads.map(&:name) 42 heads.size.should == 1 43 heads.include?(Gitlab::Satellite::Satellite::PARKING_BRANCH).should == true 44 remotes = repo.git.remote().split(' ') 45 remotes.size.should == 1 46 remotes.include?('origin').should == true 47 repo.config['user.name'].should ==user.name 48 repo.config['user.email'].should ==user.email 49 end 50 end 51 52 describe '#in_locked_and_timed_satellite' do 53 54 it 'should make use of a lockfile' do - spec/lib/gitlab/satellite/action_spec.rb 0 → 100644
1 require 'spec_helper' 2 3 describe 'Gitlab::Satellite::Action' do 4 let(:project) { create(:project_with_code) } 5 let(:user) { create(:user) } 6 7 describe '#prepare_satellite!' do 8 9 it 'create a repository with a parking branch and one remote: origin' do - spec/lib/gitlab/satellite/action_spec.rb 0 → 100644
1 require 'spec_helper' 2 3 describe 'Gitlab::Satellite::Action' do 4 let(:project) { create(:project_with_code) } 5 let(:user) { create(:user) } 137 149 end 138 150 139 151 def unmerged_diffs 140 project.repository.diffs_between(source_branch, target_branch) 152 if for_fork? 153 diffs = Gitlab::Satellite::MergeAction.new(author, self).diffs_between_satellite 154 else 155 diffs = target_project.repository.diffs_between(source_branch, target_branch) Created by: karlhungus
done
def unmerged_diffs if for_fork? diffs = Gitlab::Satellite::MergeAction.new(author, self).diffs_between_satellite else diffs = project.repository.diffs_between(source_branch, target_branch) end diffs ||= [] diffs end
By Administrator on 2013-07-30T20:19:36 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:36 (imported from GitLab)
Unable to load the diff Created by: karlhungus
done
def unmerged_commits if for_fork? commits = Gitlab::Satellite::MergeAction.new(self.author, self).commits_between else commits = self.project.repository.commits_between(self.target_branch, self.source_branch) end if commits.present? commits = Commit.decorate(commits). sort_by(&:created_at). reverse end commits end
By Administrator on 2013-07-30T20:19:36 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:36 (imported from GitLab)
62 62 def commit_author 63 63 @commit_author ||= 64 64 project.users.find_by_email(noteable.author_email) || 65 project.users.find_by_name(noteable.author_name) 65 project.users.find_by_name(noteable.author_name) 1 1 %li{ class: mr_css_classes(merge_request) } 2 2 .merge-request-title 3 3 %span.light= "##{merge_request.id}" 4 = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.project, merge_request), class: "row_title" 4 = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.target_project, merge_request), class: "row_title" 5 5 - if merge_request.merged? 6 6 %small.pull-right 7 7 %i.icon-ok 8 8 = "MERGED" 9 9 - else 10 10 %span.pull-right 11 %i.icon-angle-right 12 = merge_request.target_branch 11 - if merge_request.for_fork? 12 = "#{merge_request.source_project.path_with_namespace}/#{merge_request.source_branch}" 13 %i.icon-angle-right 22 22 - @merge_requests.each do |merge_request| 23 23 %li 24 24 merge request: 25 = link_to [merge_request.project, merge_request] do 25 = link_to [merge_request.target_project, merge_request] do 26 26 %span ##{merge_request.id} 27 27 %strong.term 28 28 = truncate merge_request.title, length: 50 29 %span.light (#{merge_request.project.name_with_namespace}) 8 Scenario: I can visit the target projects commit for a forked merge request 9 Given I visit project "Forked Shop" merge requests page 10 And I click link "New Merge Request" 11 And I fill out a "Merge Request On Forked Project" merge request 12 And I follow the target commit link 13 Then I should see the commit under the forked from project 14 15 @javascript 16 Scenario: I submit new unassigned merge request to a forked project 17 Given I visit project "Forked Shop" merge requests page 18 And I click link "New Merge Request" 19 And I fill out a "Merge Request On Forked Project" merge request 20 And I submit the merge request 21 Then I should see merge request "Merge Request On Forked Project" 22 23 @javascript 27 Then I should see last push widget 28 And I click "Create Merge Request on fork" link 29 Then I see prefilled new Merge Request page for the forked project 30 31 @javascript 32 Scenario: I can edit a forked merge request 33 Given I visit project "Forked Shop" merge requests page 34 And I click link "New Merge Request" 35 And I fill out a "Merge Request On Forked Project" merge request 36 And I submit the merge request 37 And I should see merge request "Merge Request On Forked Project" 38 And I click link edit "Merge Request On Forked Project" 39 Then I see the edit page prefilled for "Merge Request On Forked Project" 40 And I update the merge request title 41 And I save the merge request 42 Then I should see the edited merge request 33 31 ensure 34 32 Gitlab::ShellEnv.reset_env 35 33 end 36 34 37 # * Clears the satellite 38 # * Updates the satellite from Gitolite 35 # * Recreates the satellite 39 36 # * Sets up Git variables for the user 40 37 # 41 38 # Note: use this within #in_locked_and_timed_satellite 42 39 def prepare_satellite!(repo) 43 40 project.satellite.clear_and_update! 44 41 45 repo.git.config({}, "user.name", user.name) 46 repo.git.config({}, "user.email", user.email) 42 repo.config['user.name'] = user.name 34 32 Gitlab::ShellEnv.reset_env 35 33 end 36 34 37 # * Clears the satellite 38 # * Updates the satellite from Gitolite 35 # * Recreates the satellite 39 36 # * Sets up Git variables for the user 40 37 # 41 38 # Note: use this within #in_locked_and_timed_satellite 42 39 def prepare_satellite!(repo) 43 40 project.satellite.clear_and_update! 44 41 45 repo.git.config({}, "user.name", user.name) 46 repo.git.config({}, "user.email", user.email) 42 repo.config['user.name'] = user.name 43 repo.config['user.email'] = user.email 1 1 module Gitlab 2 class SatelliteNotExistError < StandardError; end 2 class SatelliteNotExistError < StandardError; end 24 24 def clear_and_update! 25 25 raise_no_satellite unless exists? 26 26 27 File.exists? path 28 @repo = nil 120 def remove_remotes! 121 remotes = repo.git.remote.split(' ') 122 remotes.delete('origin') 123 remotes.each { |name| repo.git.remote(default_options,'rm', name)} 110 124 end 111 125 112 126 # Updates the satellite from Gitolite 113 127 # 114 128 # Note: this will only update remote branches (i.e. origin/*) 115 129 def update_from_source! 116 repo.git.fetch({timeout: true}, :origin) 130 repo.git.fetch(default_options, :origin) 131 end 132 133 def default_options(options = {}) 134 {raise: true, timeout: true}.merge(options) 41 it 'should raise exception -- not expected to be used by non forks' do 42 merge_request.target_branch = @one_after_stable[0] 43 merge_request.source_branch = @master[0] 44 expect {Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between}.to raise_error 45 46 merge_request.target_branch = @wiki_branch[0] 47 merge_request.source_branch = @master[0] 48 expect {Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between}.to raise_error 49 end 50 end 51 end 52 53 describe '#format_patch' do 54 let(:target_commit) {['artiom-config-examples','9edbac5ac88ffa1ec9dad0097226b51e29ebc9ac']} 55 let(:source_commit) {['metior', '313d96e42b313a0af5ab50fa233bf43e27118b3f']} 56 64 65 (patch.include? 'e74fae147abc7d2ffbf93d363dbbe45b87751f6f').should be_false 66 (patch.include? '86f76b11c670425bbab465087f25172378d76147').should be_false 67 end 68 69 context 'on fork' do 70 it 'should build a format patch' do 71 merge_request_fork.target_branch = target_commit[0] 72 merge_request_fork.source_branch = source_commit[0] 73 patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch 74 verify_content(patch) 75 end 76 end 77 78 context 'between branches' do 79 it 'should build a format patch' do 107 merge_request_fork.source_branch = @master[0] 108 diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request_fork).diff_in_satellite 109 110 is_a_matching_diff(diff, diffs) 111 end 112 end 113 114 context 'between branches' do 115 it 'should get proper diffs' do 116 merge_request.target_branch = @close_commit1[0] 117 merge_request.source_branch = @master[0] 118 expect{Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite}.to raise_error 119 end 120 end 121 end 122 71 72 describe '#for_fork?' do 73 it 'returns true if the merge request is for a fork' do 74 subject.source_project = create(:source_project) 75 subject.target_project = create(:target_project) 76 77 subject.for_fork?.should be_true 78 end 79 it 'returns false if is not for a fork' do 80 subject.source_project = create(:source_project) 81 subject.target_project = subject.source_project 82 subject.for_fork?.should be_false 83 end 84 end 85 86 describe '#allow_source_branch_removal?' do 78 Note.should_receive(:create_status_change_note).with(closed_assigned_mr, some_user, 'reopened') 80 Note.should_receive(:create_status_change_note).with(closed_assigned_mr, closed_assigned_mr.target_project, some_user, 'reopened') 79 81 80 82 closed_assigned_mr.reopen 81 83 end 82 84 83 85 it 'notification is delivered only to author if the merge request is being reopened' do 84 Note.should_receive(:create_status_change_note).with(closed_unassigned_mr, some_user, 'reopened') 86 Note.should_receive(:create_status_change_note).with(closed_unassigned_mr, closed_unassigned_mr.target_project, some_user, 'reopened') 85 87 86 88 closed_unassigned_mr.reopen 87 89 end 88 90 end 89 91 end 92 93 describe "Merge Request created" do 50 74 Gitlab::Satellite::Satellite.any_instance.stub( 51 75 exists?: true, 52 76 destroy: true, 53 create: true 77 create: true, 78 lock_files_dir: repos_path 97 end 98 rescue Grit::Git::CommandFailed => ex 99 handle_exception(ex) 100 end 101 102 # Retrieve an array of commits between the source and the target 103 def commits_between 104 in_locked_and_timed_satellite do |merge_repo| 105 prepare_satellite!(merge_repo) 106 update_satellite_source_and_target!(merge_repo) 107 if (merge_request.for_fork?) 108 commits = merge_repo.commits_between("origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}") 109 else 110 raise "Attempt to determine commits between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]" 111 end 112 commits = commits.map { |commit| Gitlab::Git::Commit.new(commit, nil) } 64 65 # Only show what is new in the source branch compared to the target branch, not the other way around. 66 # The line below with merge_base is equivalent to diff with three dots (git diff branch1...branch2) 67 # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B" 68 def diffs_between_satellite 69 in_locked_and_timed_satellite do |merge_repo| 70 prepare_satellite!(merge_repo) 71 update_satellite_source_and_target!(merge_repo) 72 if merge_request.for_fork? 73 common_commit = merge_repo.git.native(:merge_base, default_options, ["origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}"]).strip 74 #this method doesn't take default options 75 diffs = merge_repo.diff(common_commit, "source/#{merge_request.source_branch}") 76 else 77 raise "Attempt to determine diffs between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]" 78 end 79 diffs = diffs.map { |diff| Gitlab::Git::Diff.new(diff) } Created by: coveralls
Coverage increased (+0%) when pulling b8a4a1da0d4f12e9b50944e125366d80b20ec740 on karlhungus:mr-on-fork into a6cfb54c on gitlabhq:master.
By Administrator on 2013-07-16T22:52:39 (imported from GitLab project)
By Administrator on 2013-07-16T22:52:39 (imported from GitLab)
Created by: karlhungus
@randx I think that last edit address the last of the code review changes, I've got one thing i want to test again, then rebase and we should be good.
By Administrator on 2013-07-17T21:42:46 (imported from GitLab project)
By Administrator on 2013-07-17T21:42:46 (imported from GitLab)
Created by: dzaporozhets
I got a problem with format-patch for MR on forks,
Source Commits: A, B Target Commits: A, D, E
MR Diff is
B
which is valid. Butformat-patch
returnD, E, B
which is notBy Administrator on 2013-07-30T11:04:26 (imported from GitLab project)
By Administrator on 2013-07-30T11:04:26 (imported from GitLab)
Created by: dzaporozhets
More info
→ git format-patch source/master...target/master commit-D commit-E commit-B → git diff source/master...target/master commit-B → git checkout source/master → git format-patch origin/master commit B
By Administrator on 2013-07-30T11:07:52 (imported from GitLab project)
By Administrator on 2013-07-30T11:07:52 (imported from GitLab)
Created by: dzaporozhets
Also I created a branch for this feature. See https://github.com/gitlabhq/gitlabhq/tree/karlhungus-mr-on-fork It makes sense if we continue to work there. Just send PR with improvements to
karlhungus-mr-on-fork
branch instead of master. When we make it ready - then it will be merged to masterBy Administrator on 2013-07-30T11:14:40 (imported from GitLab project)
By Administrator on 2013-07-30T11:14:40 (imported from GitLab)
Created by: karlhungus
@randx I created a test that i thought would reproduce this case:
# https://github.com/gitlabhq/gitlabhq/pull/4184#issuecomment-21783609 # should handle Source Commits: A, B, Target Commits: A, D, E returning B it 'Should only include commits that are new' do target_commit = ['artiom-config-examples','9edbac5ac88ffa1ec9dad0097226b51e29ebc9ac'] source_commit = ['metior', '313d96e42b313a0af5ab50fa233bf43e27118b3f'] merge_request_fork.target_branch = target_commit[0] merge_request_fork.source_branch = source_commit[0] patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch puts patch (patch.include? source_commit[1]).should be_true (patch.include? '635d3e09b72232b6e92a38de6cc184147e5bcb41').should be_true (patch.include? '2bb2dee057327c81978ed0aa99904bd7ff5e6105').should be_true (patch.include? '2e83de1924ad3429b812d17498b009a8b924795d').should be_true (patch.include? 'ee45a49c57a362305431cbf004e4590b713c910e').should be_true (patch.include? 'a6870dd08f8f274d9a6b899f638c0c26fefaa690').should be_true (patch.include? 'e74fae147abc7d2ffbf93d363dbbe45b87751f6f').should be_false (patch.include? '86f76b11c670425bbab465087f25172378d76147').should be_false end
Only problem is it doesn't fail, so obviously i've done something incorrect. Maybe you've got a repo you could run it on?
If you modify
format-patch
inmerge_action
:rescue Grit::Git::CommandFailed => ex puts ex ex.backtrace.each {|l|puts l} handle_exception(ex) end
It should print the command it runs, I'm a bit unsure how i could have buggered that up - unless i'm mangling branch names
By Administrator on 2013-07-30T13:28:45 (imported from GitLab project)
By Administrator on 2013-07-30T13:28:45 (imported from GitLab)
Created by: karlhungus
@randx Trying to reproduce your results; mind checking if i've basically got the right idea:
My test repo:
{11:50}~/tmp/foo:target ✓ ➭ git log --oneline --graph --decorate --all * e1d60d7 (target) E * 48c2bf9 D | * 12ff723 (HEAD, source, master) B |/ * 9fc3741 A
command line format-patches:
{11:52}~/tmp/foo:target ✓ ➭ git format-patch --stdout target...source|grep "From" From 12ff72339324c3cd6ad59f7085fa53d0f6a03b75 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From 48c2bf9bc4ee4c90dab2846e377428af4348b934 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From e1d60d701498fdd097e62c739add82781ad3e193 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> {11:52}~/tmp/foo:target ✓ ➭ git format-patch --stdout source...target|grep "From" From 12ff72339324c3cd6ad59f7085fa53d0f6a03b75 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From 48c2bf9bc4ee4c90dab2846e377428af4348b934 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From e1d60d701498fdd097e62c739add82781ad3e193 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> {11:52}~/tmp/foo:target ✓ ➭ git co source Switched to branch 'source' {11:52}~/tmp/foo:source ✓ ➭ git format-patch --stdout source...target|grep "From" From 12ff72339324c3cd6ad59f7085fa53d0f6a03b75 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From 48c2bf9bc4ee4c90dab2846e377428af4348b934 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From e1d60d701498fdd097e62c739add82781ad3e193 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> {11:52}~/tmp/foo:source ✓ ➭ git format-patch --stdout target...source|grep "From" From 12ff72339324c3cd6ad59f7085fa53d0f6a03b75 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From 48c2bf9bc4ee4c90dab2846e377428af4348b934 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> From e1d60d701498fdd097e62c739add82781ad3e193 Mon Sep 17 00:00:00 2001 From: Izaak Alpert <ialpert@blackberry.com> {11:52}~/tmp/foo:source ✓ ➭
It would be excellent if you had a failing test for this problem case since I can't seem to reproduce it.
I haven't done it with a remote, so this isn't a complete test, but i'm not seeing the same results as you are (I always get all commits between).
By Administrator on 2013-07-30T16:02:01 (imported from GitLab project)
By Administrator on 2013-07-30T16:02:01 (imported from GitLab)
79 diffs = diffs.map { |diff| Gitlab::Git::Diff.new(diff) } 80 return diffs 81 end 82 rescue Grit::Git::CommandFailed => ex 83 handle_exception(ex) 84 end 85 86 # Get commit as an email patch 87 def format_patch 88 in_locked_and_timed_satellite do |merge_repo| 89 prepare_satellite!(merge_repo) 90 update_satellite_source_and_target!(merge_repo) 91 if (merge_request.for_fork?) 92 patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}") 93 else 94 patch = merge_repo.git.format_patch(default_options({stdout: true}), "#{merge_request.target_branch}..#{merge_request.source_branch}") Created by: dzaporozhets
Should be
patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}")
instead of
patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}...source/#{merge_request.source_branch}")
Same for non-forks
patch = merge_repo.git.format_patch(default_options({stdout: true}), "#{merge_request.target_branch}..#{merge_request.source_branch}")
instead of
patch = merge_repo.git.format_patch(default_options({stdout: true}), "#{merge_request.target_branch}...#{merge_request.source_branch}")
By Administrator on 2013-07-30T20:19:36 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:36 (imported from GitLab)
79 diffs = diffs.map { |diff| Gitlab::Git::Diff.new(diff) } 80 return diffs 81 end 82 rescue Grit::Git::CommandFailed => ex 83 handle_exception(ex) 84 end 85 86 # Get commit as an email patch 87 def format_patch 88 in_locked_and_timed_satellite do |merge_repo| 89 prepare_satellite!(merge_repo) 90 update_satellite_source_and_target!(merge_repo) 91 if (merge_request.for_fork?) 92 patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}") 93 else 94 patch = merge_repo.git.format_patch(default_options({stdout: true}), "#{merge_request.target_branch}..#{merge_request.source_branch}") Created by: karlhungus
Went back and checked, i indeed introduced that extra
.
back in2a6797351c62be3c06c217bb2dcf35533d680cb3
, do you want me to fix and resubmit?By Administrator on 2013-07-30T20:19:36 (imported from GitLab project)
By Administrator on 2013-07-30T20:19:36 (imported from GitLab)
Created by: karlhungus
@randx Figured having the tests fixed as well made it worth me doing, i don't have committer access to karlhungus-mr-on-fork branch, or i would have just pushed it there -- guess you can cherry pick this one though.
My test isn't quite as good as I'd like it, In someways it'd be almost nice to have several sample simple repos to simulate these test cases... i guess at that point your kind of testing git though...
By Administrator on 2013-07-30T20:17:16 (imported from GitLab project)
By Administrator on 2013-07-30T20:17:16 (imported from GitLab)
Created by: dzaporozhets
I picked this 2 commits. Closing this PR. I made some improvements testing and merge it to master if everything is ok. @karlhungus Thank you! It was cool :)
By Administrator on 2013-08-08T09:15:17 (imported from GitLab project)
By Administrator on 2013-08-08T09:15:17 (imported from GitLab)
Created by: sankargorthi
On version
6.0.0
it doesn't seem possible to create merge requests from a forked repo to the fork.The original repo was created by a developer and then forked by the admin for production maintenance. It would make sense to allow merges from the developer repo into the admin repo.
Is there some way of reversing the forked->fork relationship?
By Administrator on 2013-11-06T22:44:17 (imported from GitLab project)
By Administrator on 2013-11-06T22:44:17 (imported from GitLab)
Created by: karlhungus
@sankargorthi I created a pull request https://github.com/gitlabhq/gitlabhq/pull/5384 just need to convince upstream this is useful for you.
By Administrator on 2013-11-06T23:47:28 (imported from GitLab project)
By Administrator on 2013-11-06T23:47:28 (imported from GitLab)
Created by: sankargorthi
@sankargorthi I created a pull request #5384 just need to convince upstream this is useful for you.
Thanks @karlhungus! Hope this goes in soon.
By Administrator on 2013-11-07T07:07:23 (imported from GitLab project)
By Administrator on 2013-11-07T07:07:23 (imported from GitLab)