gitx 2.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CONTRIBUTING.md +67 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +87 -0
- data/Rakefile +5 -0
- data/bin/git-buildtag +6 -0
- data/bin/git-cleanup +7 -0
- data/bin/git-integrate +6 -0
- data/bin/git-nuke +6 -0
- data/bin/git-release +6 -0
- data/bin/git-review +6 -0
- data/bin/git-share +6 -0
- data/bin/git-start +6 -0
- data/bin/git-track +6 -0
- data/bin/git-update +6 -0
- data/gitx.gemspec +37 -0
- data/lib/gitx.rb +8 -0
- data/lib/gitx/cli/base_command.rb +56 -0
- data/lib/gitx/cli/buildtag_command.rb +39 -0
- data/lib/gitx/cli/cleanup_command.rb +45 -0
- data/lib/gitx/cli/integrate_command.rb +94 -0
- data/lib/gitx/cli/nuke_command.rb +62 -0
- data/lib/gitx/cli/release_command.rb +40 -0
- data/lib/gitx/cli/review_command.rb +93 -0
- data/lib/gitx/cli/share_command.rb +15 -0
- data/lib/gitx/cli/start_command.rb +37 -0
- data/lib/gitx/cli/track_command.rb +14 -0
- data/lib/gitx/cli/update_command.rb +35 -0
- data/lib/gitx/configuration.rb +44 -0
- data/lib/gitx/extensions/string.rb +12 -0
- data/lib/gitx/extensions/thor.rb +39 -0
- data/lib/gitx/github.rb +178 -0
- data/lib/gitx/version.rb +3 -0
- data/spec/fixtures/vcr_cassettes/pull_request_does_exist_with_failure_status.yml +135 -0
- data/spec/fixtures/vcr_cassettes/pull_request_does_exist_with_success_status.yml +149 -0
- data/spec/fixtures/vcr_cassettes/pull_request_does_not_exist.yml +133 -0
- data/spec/gitx/cli/base_command_spec.rb +41 -0
- data/spec/gitx/cli/buildtag_command_spec.rb +70 -0
- data/spec/gitx/cli/cleanup_command_spec.rb +37 -0
- data/spec/gitx/cli/integrate_command_spec.rb +290 -0
- data/spec/gitx/cli/nuke_command_spec.rb +165 -0
- data/spec/gitx/cli/release_command_spec.rb +172 -0
- data/spec/gitx/cli/review_command_spec.rb +356 -0
- data/spec/gitx/cli/share_command_spec.rb +32 -0
- data/spec/gitx/cli/start_command_spec.rb +96 -0
- data/spec/gitx/cli/track_command_spec.rb +31 -0
- data/spec/gitx/cli/update_command_spec.rb +79 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/support/global_config.rb +26 -0
- data/spec/support/home_env.rb +11 -0
- data/spec/support/matchers/meet_expectations_matcher.rb +7 -0
- data/spec/support/pry.rb +1 -0
- data/spec/support/stub_execution.rb +14 -0
- data/spec/support/timecop.rb +9 -0
- data/spec/support/vcr.rb +6 -0
- data/spec/support/webmock.rb +1 -0
- metadata +348 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Gitx
|
6
|
+
module Cli
|
7
|
+
class CleanupCommand < BaseCommand
|
8
|
+
desc 'cleanup', 'Cleanup branches that have been merged into master from the repo'
|
9
|
+
def cleanup
|
10
|
+
checkout_branch Gitx::BASE_BRANCH
|
11
|
+
run_cmd 'git pull'
|
12
|
+
run_cmd 'git remote prune origin'
|
13
|
+
|
14
|
+
say 'Deleting local and remote branches that have been merged into '
|
15
|
+
say Gitx::BASE_BRANCH, :green
|
16
|
+
merged_branches(remote: true).each do |branch|
|
17
|
+
run_cmd "git push origin --delete #{branch}"
|
18
|
+
end
|
19
|
+
merged_branches(remote: false).each do |branch|
|
20
|
+
run_cmd "git branch -d #{branch}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# @return list of branches that have been merged
|
27
|
+
def merged_branches(options = {})
|
28
|
+
args = []
|
29
|
+
args << '-r' if options[:remote]
|
30
|
+
args << '--merged'
|
31
|
+
output = run_cmd("git branch #{args.join(' ')}").split("\n")
|
32
|
+
branches = output.map do |branch|
|
33
|
+
branch = branch.gsub(/\*/, '').strip.split(' ').first
|
34
|
+
branch = branch.split('/').last if options[:remote]
|
35
|
+
branch
|
36
|
+
end
|
37
|
+
branches.uniq!
|
38
|
+
branches -= config.reserved_branches
|
39
|
+
branches.reject! { |b| config.aggregate_branch?(b) }
|
40
|
+
|
41
|
+
branches
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
require 'gitx/cli/update_command'
|
5
|
+
require 'gitx/github'
|
6
|
+
|
7
|
+
module Gitx
|
8
|
+
module Cli
|
9
|
+
class IntegrateCommand < BaseCommand
|
10
|
+
include Gitx::Github
|
11
|
+
desc 'integrate', 'integrate the current branch into one of the aggregate development branches (default = staging)'
|
12
|
+
method_option :resume, :type => :string, :aliases => '-r', :desc => 'resume merging of feature-branch'
|
13
|
+
method_option :comment, :type => :boolean, :aliases => '-c', :desc => 'add a comment to the pull request for this branch. Creates a new PR if none exists.'
|
14
|
+
def integrate(integration_branch = 'staging')
|
15
|
+
assert_aggregate_branch!(integration_branch)
|
16
|
+
|
17
|
+
branch = feature_branch_name
|
18
|
+
print_message(branch, integration_branch)
|
19
|
+
|
20
|
+
begin
|
21
|
+
execute_command(UpdateCommand, :update)
|
22
|
+
rescue
|
23
|
+
fail MergeError, 'Merge Conflict Occurred. Please Merge Conflict Occurred. Please fix merge conflict and rerun the integrate command'
|
24
|
+
end
|
25
|
+
|
26
|
+
integrate_branch(branch, integration_branch) unless options[:resume]
|
27
|
+
checkout_branch branch
|
28
|
+
|
29
|
+
create_integrate_comment(branch) if options[:comment] && !config.reserved_branch?(branch)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def print_message(branch, integration_branch)
|
35
|
+
message = options[:resume] ? 'Resuming integration of' : 'Integrating'
|
36
|
+
say "#{message} "
|
37
|
+
say "#{branch} ", :green
|
38
|
+
say 'into '
|
39
|
+
say integration_branch, :green
|
40
|
+
end
|
41
|
+
|
42
|
+
def integrate_branch(branch, integration_branch)
|
43
|
+
fetch_remote_branch(integration_branch)
|
44
|
+
begin
|
45
|
+
run_cmd "git merge #{branch}"
|
46
|
+
rescue
|
47
|
+
fail MergeError, "Merge Conflict Occurred. Please fix merge conflict and rerun command with --resume #{branch} flag"
|
48
|
+
end
|
49
|
+
run_cmd 'git push origin HEAD'
|
50
|
+
end
|
51
|
+
|
52
|
+
def feature_branch_name
|
53
|
+
@feature_branch ||= begin
|
54
|
+
feature_branch = options[:resume] || current_branch.name
|
55
|
+
until local_branch_exists?(feature_branch)
|
56
|
+
feature_branch = ask("#{feature_branch} does not exist. Please select one of the available local branches: #{local_branches}")
|
57
|
+
end
|
58
|
+
feature_branch
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# nuke local branch and pull fresh version from remote repo
|
63
|
+
def fetch_remote_branch(target_branch)
|
64
|
+
create_remote_branch(target_branch) unless remote_branch_exists?(target_branch)
|
65
|
+
run_cmd 'git fetch origin'
|
66
|
+
run_cmd "git branch -D #{target_branch}", :allow_failure => true
|
67
|
+
checkout_branch target_branch
|
68
|
+
end
|
69
|
+
|
70
|
+
def local_branch_exists?(branch)
|
71
|
+
local_branches.include?(branch)
|
72
|
+
end
|
73
|
+
|
74
|
+
def local_branches
|
75
|
+
@local_branches ||= repo.branches.each_name(:local)
|
76
|
+
end
|
77
|
+
|
78
|
+
def remote_branch_exists?(target_branch)
|
79
|
+
repo.branches.each_name(:remote).include?("origin/#{target_branch}")
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_remote_branch(target_branch)
|
83
|
+
repo.create_branch(target_branch, Gitx::BASE_BRANCH)
|
84
|
+
run_cmd "git push origin #{target_branch}:#{target_branch}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_integrate_comment(branch)
|
88
|
+
pull_request = find_or_create_pull_request(branch)
|
89
|
+
comment = '[gitx] integrated into staging :twisted_rightwards_arrows:'
|
90
|
+
github_client.add_comment(github_slug, pull_request.number, comment)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Gitx
|
6
|
+
module Cli
|
7
|
+
class NukeCommand < BaseCommand
|
8
|
+
desc 'nuke', 'nuke the specified aggregate branch and reset it to a known good state'
|
9
|
+
method_option :destination, :type => :string, :aliases => '-d', :desc => 'destination branch to reset to'
|
10
|
+
def nuke(bad_branch)
|
11
|
+
good_branch = options[:destination] || ask("What branch do you want to reset #{bad_branch} to? (default: #{bad_branch})")
|
12
|
+
good_branch = bad_branch if good_branch.length == 0
|
13
|
+
|
14
|
+
last_known_good_tag = current_build_tag(good_branch)
|
15
|
+
return unless yes?("Reset #{bad_branch} to #{last_known_good_tag}? (y/n)", :green)
|
16
|
+
assert_aggregate_branch!(bad_branch)
|
17
|
+
return if migrations_need_to_be_reverted?(bad_branch, last_known_good_tag)
|
18
|
+
|
19
|
+
say 'Resetting '
|
20
|
+
say "#{bad_branch} ", :green
|
21
|
+
say 'branch to '
|
22
|
+
say last_known_good_tag, :green
|
23
|
+
|
24
|
+
checkout_branch Gitx::BASE_BRANCH
|
25
|
+
run_cmd "git branch -D #{bad_branch}", :allow_failure => true
|
26
|
+
run_cmd "git push origin --delete #{bad_branch}", :allow_failure => true
|
27
|
+
run_cmd "git checkout -b #{bad_branch} #{last_known_good_tag}"
|
28
|
+
run_cmd "git push origin #{bad_branch}"
|
29
|
+
run_cmd "git branch --set-upstream-to origin/#{bad_branch}"
|
30
|
+
checkout_branch Gitx::BASE_BRANCH
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def migrations_need_to_be_reverted?(bad_branch, last_known_good_tag)
|
36
|
+
return false unless File.exist?('db/migrate')
|
37
|
+
outdated_migrations = run_cmd("git diff #{last_known_good_tag}...#{bad_branch} --name-only db/migrate").split
|
38
|
+
return false if outdated_migrations.empty?
|
39
|
+
|
40
|
+
say "#{bad_branch} contains migrations that may need to be reverted. Ensure any reversable migrations are reverted on affected databases before nuking.", :red
|
41
|
+
say 'Example commands to revert outdated migrations:'
|
42
|
+
outdated_migrations.reverse.each do |migration|
|
43
|
+
version = File.basename(migration).split('_').first
|
44
|
+
say "rake db:migrate:down VERSION=#{version}"
|
45
|
+
end
|
46
|
+
!yes?("Are you sure you want to nuke #{bad_branch}? (y/n) ", :green)
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_build_tag(branch)
|
50
|
+
last_build_tag = build_tags_for_branch(branch).last
|
51
|
+
raise "No known good tag found for branch: #{branch}. Verify tag exists via `git tag -l 'build-#{branch}-*'`" unless last_build_tag
|
52
|
+
last_build_tag
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_tags_for_branch(branch)
|
56
|
+
run_cmd 'git fetch --tags'
|
57
|
+
build_tags = run_cmd("git tag -l 'build-#{branch}-*'").split
|
58
|
+
build_tags.sort
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
require 'gitx/cli/update_command'
|
5
|
+
require 'gitx/cli/integrate_command'
|
6
|
+
require 'gitx/cli/cleanup_command'
|
7
|
+
require 'gitx/github'
|
8
|
+
|
9
|
+
module Gitx
|
10
|
+
module Cli
|
11
|
+
class ReleaseCommand < BaseCommand
|
12
|
+
include Gitx::Github
|
13
|
+
|
14
|
+
desc 'release', 'release the current branch to production'
|
15
|
+
method_option :cleanup, :type => :boolean, :desc => 'cleanup merged branches after release'
|
16
|
+
def release(branch = nil)
|
17
|
+
return unless yes?("Release #{current_branch.name} to production? (y/n)", :green)
|
18
|
+
|
19
|
+
branch ||= current_branch.name
|
20
|
+
assert_not_protected_branch!(branch, 'release')
|
21
|
+
checkout_branch(branch)
|
22
|
+
execute_command(UpdateCommand, :update)
|
23
|
+
|
24
|
+
find_or_create_pull_request(branch)
|
25
|
+
status = branch_status(branch)
|
26
|
+
if status != 'success'
|
27
|
+
return unless yes?("Branch status is currently: #{status}. Proceed with release? (y/n)", :red)
|
28
|
+
end
|
29
|
+
|
30
|
+
checkout_branch Gitx::BASE_BRANCH
|
31
|
+
run_cmd "git pull origin #{Gitx::BASE_BRANCH}"
|
32
|
+
run_cmd "git merge --no-ff #{branch}"
|
33
|
+
run_cmd 'git push origin HEAD'
|
34
|
+
|
35
|
+
execute_command(IntegrateCommand, :integrate, 'staging')
|
36
|
+
execute_command(CleanupCommand, :cleanup) if options[:cleanup]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
require 'gitx/github'
|
5
|
+
|
6
|
+
module Gitx
|
7
|
+
module Cli
|
8
|
+
class ReviewCommand < BaseCommand
|
9
|
+
include Gitx::Github
|
10
|
+
|
11
|
+
BUMP_COMMENT_PREFIX = '[gitx] review bump :tada:'
|
12
|
+
BUMP_COMMENT_FOOTER = <<-EOS.dedent
|
13
|
+
# Bump comments should include:
|
14
|
+
# * summary of what changed
|
15
|
+
#
|
16
|
+
# This footer will automatically be stripped from the created comment
|
17
|
+
EOS
|
18
|
+
APPROVAL_COMMENT_PREFIX = '[gitx] review approved :shipit:'
|
19
|
+
APPROVAL_COMMENT_FOOTER = <<-EOS.dedent
|
20
|
+
# Approval comments can include:
|
21
|
+
# * feedback
|
22
|
+
# * post-release follow-up items
|
23
|
+
#
|
24
|
+
# This footer will automatically be stripped from the created comment
|
25
|
+
EOS
|
26
|
+
REJECTION_COMMENT_PREFIX = '[gitx] review rejected'
|
27
|
+
REJECTION_COMMENT_FOOTER = <<-EOS.dedent
|
28
|
+
# Rejection comments should include:
|
29
|
+
# * feedback for fixes required before approved
|
30
|
+
#
|
31
|
+
# This footer will automatically be stripped from the created comment
|
32
|
+
EOS
|
33
|
+
|
34
|
+
desc 'review', 'Create or update a pull request on github'
|
35
|
+
method_option :description, :type => :string, :aliases => '-d', :desc => 'pull request description'
|
36
|
+
method_option :assignee, :type => :string, :aliases => '-a', :desc => 'pull request assignee'
|
37
|
+
method_option :open, :type => :boolean, :aliases => '-o', :desc => 'open the pull request in a web browser'
|
38
|
+
method_option :bump, :type => :boolean, :aliases => '-b', :desc => 'bump an existing pull request by posting a comment to re-review new changes'
|
39
|
+
method_option :approve, :type => :boolean, :desc => 'approve the pull request an post comment on pull request'
|
40
|
+
method_option :reject, :type => :boolean, :desc => 'reject the pull request an post comment on pull request'
|
41
|
+
# @see http://developer.github.com/v3/pulls/
|
42
|
+
def review(branch = nil)
|
43
|
+
fail 'Github authorization token not found' unless authorization_token
|
44
|
+
|
45
|
+
branch ||= current_branch.name
|
46
|
+
pull_request = find_or_create_pull_request(branch)
|
47
|
+
bump_pull_request(pull_request) if options[:bump]
|
48
|
+
approve_pull_request(pull_request) if options[:approve]
|
49
|
+
reject_pull_request(pull_request) if options[:reject]
|
50
|
+
assign_pull_request(pull_request) if options[:assignee]
|
51
|
+
|
52
|
+
run_cmd "open #{pull_request.html_url}" if options[:open]
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def assign_pull_request(pull_request)
|
58
|
+
assignee = options[:assignee]
|
59
|
+
say 'Assigning pull request to '
|
60
|
+
say assignee, :green
|
61
|
+
|
62
|
+
title = pull_request.title
|
63
|
+
body = pull_request.body
|
64
|
+
options = {
|
65
|
+
assignee: assignee
|
66
|
+
}
|
67
|
+
github_client.update_issue(github_slug, pull_request.number, title, body, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def bump_pull_request(pull_request)
|
71
|
+
comment = comment_from_template(pull_request, BUMP_COMMENT_PREFIX, BUMP_COMMENT_FOOTER)
|
72
|
+
update_review_status(pull_request, 'pending', 'Peer review in progress')
|
73
|
+
end
|
74
|
+
|
75
|
+
def reject_pull_request(pull_request)
|
76
|
+
comment = comment_from_template(pull_request, REJECTION_COMMENT_PREFIX, REJECTION_COMMENT_FOOTER)
|
77
|
+
update_review_status(pull_request, 'failure', 'Peer review rejected')
|
78
|
+
end
|
79
|
+
|
80
|
+
def approve_pull_request(pull_request)
|
81
|
+
comment = comment_from_template(pull_request, APPROVAL_COMMENT_PREFIX, APPROVAL_COMMENT_FOOTER)
|
82
|
+
update_review_status(pull_request, 'success', 'Peer review approved')
|
83
|
+
end
|
84
|
+
|
85
|
+
def comment_from_template(pull_request, prefix, footer)
|
86
|
+
text = ask_editor("\n\n#{footer}", repo.config['core.editor'])
|
87
|
+
comment = [prefix, text].join("\n\n")
|
88
|
+
comment = comment.gsub(footer, '').chomp.strip
|
89
|
+
github_client.add_comment(github_slug, pull_request.number, comment)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Gitx
|
6
|
+
module Cli
|
7
|
+
class ShareCommand < BaseCommand
|
8
|
+
desc 'share', 'Share the current branch in the remote repository'
|
9
|
+
def share
|
10
|
+
run_cmd "git push origin #{current_branch.name}"
|
11
|
+
run_cmd "git branch --set-upstream-to origin/#{current_branch.name}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Gitx
|
6
|
+
module Cli
|
7
|
+
class StartCommand < BaseCommand
|
8
|
+
EXAMPLE_BRANCH_NAMES = %w( api-fix-invalid-auth desktop-cleanup-avatar-markup share-form-add-edit-link )
|
9
|
+
VALID_BRANCH_NAME_REGEX = /^[A-Za-z0-9\-_]+$/
|
10
|
+
|
11
|
+
desc 'start', 'start a new git branch with latest changes from master'
|
12
|
+
def start(branch_name = nil)
|
13
|
+
until valid_new_branch_name?(branch_name)
|
14
|
+
branch_name = ask("What would you like to name your branch? (ex: #{EXAMPLE_BRANCH_NAMES.sample})")
|
15
|
+
end
|
16
|
+
|
17
|
+
checkout_branch Gitx::BASE_BRANCH
|
18
|
+
run_cmd 'git pull'
|
19
|
+
repo.create_branch branch_name, Gitx::BASE_BRANCH
|
20
|
+
checkout_branch branch_name
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def valid_new_branch_name?(branch)
|
26
|
+
return false if repo_branches.include?(branch)
|
27
|
+
branch =~ VALID_BRANCH_NAME_REGEX
|
28
|
+
end
|
29
|
+
|
30
|
+
def repo_branches
|
31
|
+
@branch_names ||= repo.branches.each_name.map do |branch|
|
32
|
+
branch.split('/').last
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Gitx
|
6
|
+
module Cli
|
7
|
+
class TrackCommand < BaseCommand
|
8
|
+
desc 'track', 'set the current branch to track the remote branch with the same name'
|
9
|
+
def track
|
10
|
+
run_cmd "git branch --set-upstream-to origin/#{current_branch.name}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitx'
|
3
|
+
require 'gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Gitx
|
6
|
+
module Cli
|
7
|
+
class UpdateCommand < BaseCommand
|
8
|
+
desc 'update', 'Update the current branch with latest changes from the remote feature branch and master'
|
9
|
+
def update
|
10
|
+
say 'Updating '
|
11
|
+
say "#{current_branch.name} ", :green
|
12
|
+
say 'with latest changes from '
|
13
|
+
say Gitx::BASE_BRANCH, :green
|
14
|
+
|
15
|
+
update_branch(current_branch.name) if remote_branch_exists?(current_branch.name)
|
16
|
+
update_branch(Gitx::BASE_BRANCH)
|
17
|
+
run_cmd 'git push origin HEAD'
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def update_branch(branch)
|
23
|
+
begin
|
24
|
+
run_cmd "git pull origin #{branch}"
|
25
|
+
rescue
|
26
|
+
fail MergeError, 'Merge Conflict Occurred. Please fix merge conflict and rerun the update command'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def remote_branch_exists?(branch)
|
31
|
+
repo.branches.each_name(:remote).include?("origin/#{branch}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Gitx
|
4
|
+
class Configuration
|
5
|
+
DEFAULT_CONFIG = {
|
6
|
+
'aggregate_branches' => %w( staging prototype ),
|
7
|
+
'reserved_branches' => %w( HEAD master next_release staging prototype ),
|
8
|
+
'taggable_branches' => %w( master staging )
|
9
|
+
}
|
10
|
+
CONFIG_FILE = '.gitx.yml'
|
11
|
+
|
12
|
+
attr_reader :config
|
13
|
+
|
14
|
+
def initialize(root_dir)
|
15
|
+
@config = Thor::CoreExt::HashWithIndifferentAccess.new(DEFAULT_CONFIG)
|
16
|
+
config_file_path = File.join(root_dir, CONFIG_FILE)
|
17
|
+
@config.merge!(::YAML.load_file(config_file_path)) if File.exist?(config_file_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def aggregate_branches
|
21
|
+
config[:aggregate_branches]
|
22
|
+
end
|
23
|
+
|
24
|
+
def aggregate_branch?(branch)
|
25
|
+
aggregate_branches.include?(branch)
|
26
|
+
end
|
27
|
+
|
28
|
+
def reserved_branches
|
29
|
+
config[:reserved_branches]
|
30
|
+
end
|
31
|
+
|
32
|
+
def reserved_branch?(branch)
|
33
|
+
reserved_branches.include?(branch)
|
34
|
+
end
|
35
|
+
|
36
|
+
def taggable_branches
|
37
|
+
config[:taggable_branches]
|
38
|
+
end
|
39
|
+
|
40
|
+
def taggable_branch?(branch)
|
41
|
+
taggable_branches.include?(branch)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|