├── README.md └── gitlab-merge-request /README.md: -------------------------------------------------------------------------------- 1 | # gitlab-merge-request 2 | 3 | Create a merge request on Gitlab for the current branch from command-line. 4 | 5 | Opens `$EDITOR` for entering a title for the merge request. 6 | 7 | After creation, outputs a clickable URL to open it in browser. 8 | 9 | ## setup 10 | 11 | ```sh 12 | $ curl https://raw.githubusercontent.com/raine/gitlab-merge-request/master/gitlab-merge-request > ~/bin 13 | $ chmod +x ~/bin/gitlab-merge-request 14 | $ gem install git gitlab 15 | $ export GITLAB_API_ENDPOINT=https://gitlab.yourcompany.com/api/v3 16 | $ export GITLAB_API_PRIVATE_TOKEN= 17 | ``` 18 | 19 | Get the private token from https://gitlab.yourcompany.com/profile/account 20 | 21 | ## usage 22 | 23 | ```sh 24 | $ gitlab-merge-request 25 | ``` 26 | -------------------------------------------------------------------------------- /gitlab-merge-request: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # setup: gem install gitlab git 4 | # usage: gitlab-merge-request 5 | # makes a merge request for the current branch that has already been pushed 6 | # to origin 7 | 8 | require "gitlab" 9 | require "git" 10 | require "tempfile" 11 | 12 | GITLAB_BASE_URL = ENV['GITLAB_API_ENDPOINT'].sub '/api/v3', '' 13 | @git = Git.open(Dir.pwd) 14 | 15 | def parse_remote_url(url) 16 | m = url.match(%r{:(.*)/(.*)\.git}) 17 | { namespace: m[1], path: m[2] } 18 | end 19 | 20 | def find_gitlab_project(namespace, path) 21 | 22 | #look for a group corresponding to namespace 23 | groups = Gitlab.group_search(namespace) 24 | 25 | if groups.any? 26 | #we find a group corresponding to "group" var 27 | projects = Gitlab.group_projects(groups[0].id, {per_page: 1000}) 28 | else 29 | #fallback: looking for projects with corresponding namespace 30 | projects = Gitlab.projects({'search': namespace}) 31 | 32 | if not projects.any? 33 | raise sprintf("Unable find project with namespace '%s' and path '%s'", namespace, path) 34 | end 35 | end 36 | 37 | path_with_namespace = namespace + '/' + path 38 | 39 | #only return the right one (same namespace and path) 40 | projects.detect { |proj| proj.path_with_namespace == path_with_namespace } 41 | end 42 | 43 | def cwd_gitlab_project 44 | project = parse_remote_url @git.config['remote.origin.url'] 45 | find_gitlab_project project[:namespace], project[:path] 46 | end 47 | 48 | def write_merge_request_message 49 | last_commit_message = @git.object('HEAD').message 50 | Tempfile.open "merge-request-message" do |f| 51 | f << last_commit_message 52 | f.close 53 | system "#{ENV['EDITOR']} #{f.path}" 54 | f.open 55 | f.read 56 | end 57 | end 58 | 59 | def format_url(*args) 60 | "#{GITLAB_BASE_URL}/#{args.join '/'}" 61 | end 62 | 63 | current_branch = @git.branches.find(&:current).name 64 | project = cwd_gitlab_project 65 | 66 | merge_request = Gitlab.create_merge_request project.id, write_merge_request_message, 67 | :source_branch => current_branch, :target_branch => project.default_branch 68 | 69 | puts format_url project.path_with_namespace, 'merge_requests' , merge_request.iid 70 | --------------------------------------------------------------------------------