daq_flow 1.0.4
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 +11 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +62 -0
- data/LICENSE.txt +22 -0
- data/README.md +165 -0
- data/Rakefile +10 -0
- data/bin/daq_flow +23 -0
- data/flash_flow.gemspec +28 -0
- data/flash_flow.yml.erb.example +42 -0
- data/lib/flash_flow.rb +7 -0
- data/lib/flash_flow/branch_merger.rb +55 -0
- data/lib/flash_flow/cmd_runner.rb +54 -0
- data/lib/flash_flow/config.rb +84 -0
- data/lib/flash_flow/data.rb +6 -0
- data/lib/flash_flow/data/base.rb +89 -0
- data/lib/flash_flow/data/bitbucket.rb +152 -0
- data/lib/flash_flow/data/branch.rb +124 -0
- data/lib/flash_flow/data/collection.rb +211 -0
- data/lib/flash_flow/data/github.rb +140 -0
- data/lib/flash_flow/data/store.rb +44 -0
- data/lib/flash_flow/git.rb +267 -0
- data/lib/flash_flow/install.rb +19 -0
- data/lib/flash_flow/lock.rb +23 -0
- data/lib/flash_flow/merge.rb +6 -0
- data/lib/flash_flow/merge/acceptance.rb +154 -0
- data/lib/flash_flow/merge/base.rb +116 -0
- data/lib/flash_flow/merge_order.rb +27 -0
- data/lib/flash_flow/notifier.rb +23 -0
- data/lib/flash_flow/options.rb +34 -0
- data/lib/flash_flow/resolve.rb +143 -0
- data/lib/flash_flow/shadow_repo.rb +44 -0
- data/lib/flash_flow/time_helper.rb +32 -0
- data/lib/flash_flow/version.rb +4 -0
- data/log/.keep +0 -0
- data/test/lib/data/test_base.rb +10 -0
- data/test/lib/data/test_branch.rb +206 -0
- data/test/lib/data/test_collection.rb +308 -0
- data/test/lib/data/test_store.rb +70 -0
- data/test/lib/lock/test_github.rb +74 -0
- data/test/lib/merge/test_acceptance.rb +230 -0
- data/test/lib/test_branch_merger.rb +78 -0
- data/test/lib/test_config.rb +63 -0
- data/test/lib/test_git.rb +73 -0
- data/test/lib/test_merge_order.rb +71 -0
- data/test/lib/test_notifier.rb +33 -0
- data/test/lib/test_resolve.rb +69 -0
- data/test/minitest_helper.rb +41 -0
- data/update_gem.sh +5 -0
- metadata +192 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module FlashFlow
|
4
|
+
class Install
|
5
|
+
def self.install
|
6
|
+
FileUtils.mkdir 'config' unless Dir.exists?('config')
|
7
|
+
dest_file = 'config/flash_flow.yml.erb'
|
8
|
+
|
9
|
+
FileUtils.cp example_file, dest_file
|
10
|
+
|
11
|
+
puts "Flash flow config file is in #{dest_file}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.example_file
|
15
|
+
"#{File.dirname(__FILE__)}/../../flash_flow.yml.erb.example"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module FlashFlow
|
2
|
+
module Lock
|
3
|
+
class Error < RuntimeError; end
|
4
|
+
|
5
|
+
class Base
|
6
|
+
def initialize(config=nil)
|
7
|
+
lock_class_name = config && config['class'] && config['class']['name']
|
8
|
+
return unless lock_class_name
|
9
|
+
|
10
|
+
lock_class = Object.const_get(lock_class_name)
|
11
|
+
@lock = lock_class.new(config['class'])
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_lock(&block)
|
15
|
+
if @lock
|
16
|
+
@lock.with_lock(&block)
|
17
|
+
else
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'flash_flow/merge/base'
|
2
|
+
require 'flash_flow/time_helper'
|
3
|
+
|
4
|
+
module FlashFlow
|
5
|
+
module Merge
|
6
|
+
class Acceptance < Base
|
7
|
+
|
8
|
+
def initialize(opts={})
|
9
|
+
super(opts)
|
10
|
+
|
11
|
+
@data = Data::Base.new(Config.configuration.branches, Config.configuration.branch_info_file, @git, logger: logger)
|
12
|
+
|
13
|
+
@do_not_merge = opts[:do_not_merge]
|
14
|
+
@force = opts[:force]
|
15
|
+
@rerere_forget = opts[:rerere_forget]
|
16
|
+
@stories = [opts[:stories]].flatten.compact
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
# check_version
|
21
|
+
check_git_version
|
22
|
+
check_repo
|
23
|
+
puts "Building #{@local_git.merge_branch}... Log can be found in #{FlashFlow::Config.configuration.log_file}"
|
24
|
+
logger.info "\n\n### Beginning #{@local_git.merge_branch} merge ###\n\n"
|
25
|
+
|
26
|
+
begin
|
27
|
+
open_pull_request
|
28
|
+
|
29
|
+
@lock.with_lock do
|
30
|
+
@git.in_original_merge_branch do
|
31
|
+
@git.initialize_rerere(@local_git.working_dir)
|
32
|
+
end
|
33
|
+
|
34
|
+
@git.reset_temp_merge_branch
|
35
|
+
@git.in_temp_merge_branch do
|
36
|
+
merge_branches(@data.mergeable) do |branch, merger|
|
37
|
+
# Do not merge the master branch or the merge branch
|
38
|
+
next if [@git.merge_branch, @git.master_branch].include?(branch.ref)
|
39
|
+
process_result(branch, merger)
|
40
|
+
end
|
41
|
+
commit_branch_info
|
42
|
+
commit_rerere
|
43
|
+
end
|
44
|
+
|
45
|
+
@git.copy_temp_to_branch(@git.merge_branch, commit_message)
|
46
|
+
@git.delete_temp_merge_branch
|
47
|
+
@git.push(@git.merge_branch)
|
48
|
+
end
|
49
|
+
|
50
|
+
raise OutOfSyncWithRemote.new("#{@git.merge_branch} is out of sync with the remote.") unless @git.last_success?
|
51
|
+
print_errors
|
52
|
+
logger.info "### Finished #{@local_git.merge_branch} merge ###"
|
53
|
+
rescue Lock::Error, OutOfSyncWithRemote => e
|
54
|
+
puts 'Failure!'
|
55
|
+
puts e.message
|
56
|
+
ensure
|
57
|
+
@local_git.run("checkout #{@local_git.working_branch}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def commit_branch_info
|
62
|
+
@stories.each do |story_id|
|
63
|
+
@data.add_story(@git.working_branch, story_id)
|
64
|
+
end
|
65
|
+
@data.save!
|
66
|
+
end
|
67
|
+
|
68
|
+
def commit_rerere
|
69
|
+
current_branches = @data.to_a.select { |branch| !@git.master_branch_contains?(branch.sha) && (Time.now - branch.updated_at < TimeHelper.two_weeks) }
|
70
|
+
current_rereres = current_branches.map { |branch| branch.resolutions.to_h.values }.flatten
|
71
|
+
|
72
|
+
@git.commit_rerere(current_rereres)
|
73
|
+
end
|
74
|
+
|
75
|
+
def process_result(branch, merger)
|
76
|
+
case merger.result
|
77
|
+
when :deleted
|
78
|
+
@data.mark_deleted(branch)
|
79
|
+
@notifier.deleted_branch(branch) unless is_working_branch(branch)
|
80
|
+
|
81
|
+
when :success
|
82
|
+
branch.sha = merger.sha
|
83
|
+
@data.mark_success(branch)
|
84
|
+
@data.set_resolutions(branch, merger.resolutions)
|
85
|
+
|
86
|
+
when :conflict
|
87
|
+
if is_working_branch(branch)
|
88
|
+
@data.mark_failure(branch, merger.conflict_sha)
|
89
|
+
else
|
90
|
+
@data.mark_failure(branch, nil)
|
91
|
+
@notifier.merge_conflict(branch)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def is_working_branch(branch)
|
97
|
+
branch.ref == @git.working_branch
|
98
|
+
end
|
99
|
+
|
100
|
+
def open_pull_request
|
101
|
+
return false if [@local_git.master_branch, @local_git.merge_branch].include?(@local_git.working_branch)
|
102
|
+
|
103
|
+
@local_git.push(@local_git.working_branch, @force)
|
104
|
+
raise OutOfSyncWithRemote.new("Your branch is out of sync with the remote. If you want to force push, run 'flash_flow -f'") unless @local_git.last_success?
|
105
|
+
|
106
|
+
if @do_not_merge
|
107
|
+
@data.remove_from_merge(@local_git.working_branch)
|
108
|
+
else
|
109
|
+
@data.add_to_merge(@local_git.working_branch)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def print_errors
|
114
|
+
puts format_errors
|
115
|
+
end
|
116
|
+
|
117
|
+
def format_errors
|
118
|
+
errors = []
|
119
|
+
branch_not_merged = nil
|
120
|
+
@data.failures.each do |branch|
|
121
|
+
if branch.ref == @local_git.working_branch
|
122
|
+
branch_not_merged = "ERROR: Your branch did not merge to #{@local_git.merge_branch}. Run 'flash_flow --resolve', fix the merge conflict(s) and then re-run this script\n"
|
123
|
+
else
|
124
|
+
errors << "WARNING: Unable to merge branch #{@local_git.remote}/#{branch.ref} to #{@local_git.merge_branch} due to conflicts."
|
125
|
+
end
|
126
|
+
end
|
127
|
+
errors << branch_not_merged if branch_not_merged
|
128
|
+
|
129
|
+
if errors.empty?
|
130
|
+
"Success!"
|
131
|
+
else
|
132
|
+
errors.join("\n")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def commit_message
|
137
|
+
message =<<-EOS
|
138
|
+
Flash Flow run from branch: #{@local_git.working_branch}
|
139
|
+
|
140
|
+
Merged branches:
|
141
|
+
#{@data.successes.empty? ? 'None' : @data.successes.sort_by(&:merge_order).map(&:ref).join("\n")}
|
142
|
+
|
143
|
+
Failed branches:
|
144
|
+
#{@data.failures.empty? ? 'None' : @data.failures.map(&:ref).join("\n")}
|
145
|
+
|
146
|
+
Removed branches:
|
147
|
+
#{@data.removals.empty? ? 'None' : @data.removals.map(&:ref).join("\n")}
|
148
|
+
EOS
|
149
|
+
message.gsub(/'/, '')
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'flash_flow/git'
|
4
|
+
require 'flash_flow/data'
|
5
|
+
require 'flash_flow/lock'
|
6
|
+
require 'flash_flow/notifier'
|
7
|
+
require 'flash_flow/branch_merger'
|
8
|
+
require 'flash_flow/merge_order'
|
9
|
+
require 'flash_flow/shadow_repo'
|
10
|
+
|
11
|
+
module FlashFlow
|
12
|
+
module Merge
|
13
|
+
class Base
|
14
|
+
|
15
|
+
class VersionError < RuntimeError; end
|
16
|
+
class OutOfSyncWithRemote < RuntimeError; end
|
17
|
+
class UnmergeableBranch < RuntimeError; end
|
18
|
+
class NothingToMergeError < RuntimeError; end
|
19
|
+
|
20
|
+
def initialize(opts={})
|
21
|
+
@local_git = Git.new(Config.configuration.git, logger)
|
22
|
+
@git = ShadowGit.new(Config.configuration.git, logger)
|
23
|
+
@lock = Lock::Base.new(Config.configuration.lock)
|
24
|
+
@notifier = Notifier::Base.new(Config.configuration.notifier)
|
25
|
+
end
|
26
|
+
|
27
|
+
def logger
|
28
|
+
@logger ||= FlashFlow::Config.configuration.logger
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_repo
|
32
|
+
if @local_git.staged_and_working_dir_files.any?
|
33
|
+
raise RuntimeError.new('You have changes in your working directory. Please stash and try again')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_version
|
38
|
+
data_version = @data.version
|
39
|
+
return if data_version.nil?
|
40
|
+
|
41
|
+
written_version = data_version.split(".").map(&:to_i)
|
42
|
+
running_version = FlashFlow::VERSION.split(".").map(&:to_i)
|
43
|
+
|
44
|
+
unless written_version[0] < running_version[0] ||
|
45
|
+
(written_version[0] == running_version[0] && written_version[1] <= running_version[1]) # Ignore the point release number
|
46
|
+
raise RuntimeError.new("Your version of flash flow (#{FlashFlow::VERSION}) is behind the version that was last used (#{data_version}) by a member of your team. Please upgrade to at least #{written_version[0]}.#{written_version[1]}.0 and try again.")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def check_git_version
|
51
|
+
git_version = @local_git.version
|
52
|
+
return if git_version.nil?
|
53
|
+
|
54
|
+
running_version = git_version.split(".").map(&:to_i)
|
55
|
+
expected_version = FlashFlow::GIT_VERSION.split(".").map(&:to_i)
|
56
|
+
|
57
|
+
if running_version[0] < expected_version[0] ||
|
58
|
+
(running_version[0] == expected_version[0] && running_version[1] < expected_version[1]) # Ignore the point release number
|
59
|
+
puts "Warning: Your version of git (#{git_version}) is behind the version that is tested (#{FlashFlow::GIT_VERSION}). We recommend to upgrade to at least #{expected_version[0]}.#{expected_version[1]}.0"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def merge_branches(branches)
|
64
|
+
ordered_branches = MergeOrder.new(@git, branches).get_order
|
65
|
+
ordered_branches.each_with_index do |branch, index|
|
66
|
+
branch.merge_order = index + 1
|
67
|
+
|
68
|
+
merger = git_merge(branch)
|
69
|
+
|
70
|
+
yield(branch, merger)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def git_merge(branch)
|
75
|
+
merger = BranchMerger.new(@git, branch)
|
76
|
+
forget_rerere = is_working_branch(branch) && @rerere_forget
|
77
|
+
|
78
|
+
merger.do_merge(forget_rerere)
|
79
|
+
|
80
|
+
merger
|
81
|
+
end
|
82
|
+
|
83
|
+
def is_working_branch(branch)
|
84
|
+
branch.ref == @git.working_branch
|
85
|
+
end
|
86
|
+
|
87
|
+
def pending_release
|
88
|
+
@data.pending_release
|
89
|
+
end
|
90
|
+
|
91
|
+
def ready_to_merge_release
|
92
|
+
@data.ready_to_merge_release
|
93
|
+
end
|
94
|
+
|
95
|
+
def release_ahead_of_master?
|
96
|
+
@git.ahead_of_master?("#{@git.remote}/#{@git.release_branch}")
|
97
|
+
end
|
98
|
+
|
99
|
+
def write_data(commit_msg)
|
100
|
+
@git.in_temp_merge_branch do
|
101
|
+
@git.run("reset --hard #{@git.remote}/#{@git.merge_branch}")
|
102
|
+
end
|
103
|
+
@git.in_merge_branch do
|
104
|
+
@git.run("reset --hard #{@git.remote}/#{@git.merge_branch}")
|
105
|
+
end
|
106
|
+
|
107
|
+
@data.save!
|
108
|
+
|
109
|
+
@git.copy_temp_to_branch(@git.merge_branch, commit_msg)
|
110
|
+
@git.delete_temp_merge_branch
|
111
|
+
@git.push(@git.merge_branch, false)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module FlashFlow
|
2
|
+
class MergeOrder
|
3
|
+
|
4
|
+
def initialize(git, branches)
|
5
|
+
@git = git
|
6
|
+
@branches = branches
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_order
|
10
|
+
new_branches, old_branches = @branches.partition { |branch| branch.merge_order.nil? }
|
11
|
+
branches = old_branches.sort_by(&:merge_order) + new_branches
|
12
|
+
|
13
|
+
unchanged, changed = branches.partition { |branch| current_sha(branch) == branch.sha }
|
14
|
+
my_branch_index = changed.find_index { |branch| branch.ref == @git.working_branch }
|
15
|
+
my_branch_changed = my_branch_index ? changed.delete_at(my_branch_index) : nil
|
16
|
+
|
17
|
+
[unchanged, changed, my_branch_changed].flatten.compact
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def current_sha(branch)
|
23
|
+
@git.get_sha("#{@git.remote}/#{branch.ref}")
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'flash_flow/data'
|
2
|
+
|
3
|
+
module FlashFlow
|
4
|
+
module Notifier
|
5
|
+
class Base
|
6
|
+
def initialize(config=nil)
|
7
|
+
notifier_class_name = config && config['class'] && config['class']['name']
|
8
|
+
return unless notifier_class_name
|
9
|
+
|
10
|
+
@notifier_class = Object.const_get(notifier_class_name)
|
11
|
+
@notifier = @notifier_class.new(config['class'])
|
12
|
+
end
|
13
|
+
|
14
|
+
def merge_conflict(branch)
|
15
|
+
@notifier.merge_conflict(branch) if @notifier.respond_to?(:merge_conflict)
|
16
|
+
end
|
17
|
+
|
18
|
+
def deleted_branch(branch)
|
19
|
+
@notifier.deleted_branch(branch) if @notifier.respond_to?(:deleted_branch)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module FlashFlow
|
4
|
+
class Options
|
5
|
+
def self.parse
|
6
|
+
options = {}
|
7
|
+
opt_parser = OptionParser.new do |opts|
|
8
|
+
opts.banner = 'Usage: flash_flow [options]'
|
9
|
+
opts.separator ''
|
10
|
+
|
11
|
+
opts.on('--install', 'Copy flash_flow.yml.erb to your repo and exit') { |v| options[:install] = true }
|
12
|
+
opts.on('-v', '--version', 'Print the current version of flash flow and exit') { |v| options[:version] = true }
|
13
|
+
opts.on('-n', '--no-merge', 'Run flash flow, but do not merge this branch') { |v| options[:do_not_merge] = true }
|
14
|
+
opts.on('--rerere-forget', 'Delete the saved patch for this branch and let the merge fail if there is a conflict') { |v| options[:rerere_forget] = true }
|
15
|
+
opts.on('-f', '--force-push', 'Force push your branch') { |v| options[:force] = v }
|
16
|
+
opts.on('-c', '--config-file FILE_PATH', 'The path to your config file. Defaults to config/flash_flow.yml.erb') { |v| options[:config_file] = v }
|
17
|
+
opts.on('--resolve', 'Launch a bash shell to save your conflict resolutions') { |v| options[:resolve] = true }
|
18
|
+
opts.on('--resolve-manual', 'Print instructions to use git to resolve conflicts') { |v| options[:resolve_manual] = true }
|
19
|
+
|
20
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
21
|
+
puts opts
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
opt_parser.parse!
|
27
|
+
|
28
|
+
options[:stories] ||= []
|
29
|
+
options[:config_file] ||= './config/flash_flow.yml.erb'
|
30
|
+
|
31
|
+
options
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'flash_flow/git'
|
4
|
+
require 'flash_flow/data'
|
5
|
+
|
6
|
+
module FlashFlow
|
7
|
+
class Resolve
|
8
|
+
|
9
|
+
class NothingToResolve < StandardError; end
|
10
|
+
|
11
|
+
def initialize(git_config, branch_info_file, opts={})
|
12
|
+
@logger = opts[:logger]
|
13
|
+
@branch_info_file = branch_info_file
|
14
|
+
@cmd_runner = CmdRunner.new(logger: @logger)
|
15
|
+
@git = ShadowGit.new(git_config, @logger)
|
16
|
+
end
|
17
|
+
|
18
|
+
def manual_instructions
|
19
|
+
check_for_conflict
|
20
|
+
puts manual_not_merged_instructions
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
check_for_conflict
|
25
|
+
|
26
|
+
in_working_branch do
|
27
|
+
merge_conflicted
|
28
|
+
|
29
|
+
if unresolved_conflicts.empty?
|
30
|
+
puts "You have already resolved all conflicts."
|
31
|
+
else
|
32
|
+
launch_bash
|
33
|
+
|
34
|
+
rerere
|
35
|
+
|
36
|
+
unless unresolved_conflicts.empty?
|
37
|
+
puts "There are still unresolved conflicts in these files:\n#{unresolved_conflicts.join("\n")}\n\n"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
git_reset
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def unresolved_conflicts
|
46
|
+
@git.unresolved_conflicts
|
47
|
+
end
|
48
|
+
|
49
|
+
def merge_conflicted
|
50
|
+
@git.run("checkout #{branch.conflict_sha}")
|
51
|
+
@git.run("merge #{@git.remote}/#{working_branch}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def git_reset
|
55
|
+
@git.run("reset --hard HEAD")
|
56
|
+
end
|
57
|
+
|
58
|
+
def rerere
|
59
|
+
@git.run("rerere")
|
60
|
+
end
|
61
|
+
|
62
|
+
def bash_message
|
63
|
+
puts "\nNote: You are in a special flash_flow directory (#{Dir.pwd}). The files still open in your editor will not reflect the merge conflicts, open them from this shell to get the conflicted versions.\n\nPlease fix the following conflicts and then 'exit':\n#{unresolved_conflicts.join("\n")}\n\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
def launch_bash
|
67
|
+
bash_message
|
68
|
+
|
69
|
+
with_init_file do |file|
|
70
|
+
system("bash --init-file #{file} -i")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def with_init_file
|
75
|
+
filename = '.flash_flow_init'
|
76
|
+
File.open(filename, 'w') do |f|
|
77
|
+
f.puts(init_file_contents)
|
78
|
+
end
|
79
|
+
|
80
|
+
yield filename
|
81
|
+
|
82
|
+
File.delete(filename)
|
83
|
+
end
|
84
|
+
|
85
|
+
def manual_not_merged_instructions
|
86
|
+
<<-EOS
|
87
|
+
|
88
|
+
Run the following commands to fix the merge conflict and then re-run flash_flow:
|
89
|
+
pushd #{flash_flow_directory}
|
90
|
+
git checkout #{branch.conflict_sha}
|
91
|
+
git merge #{working_branch}
|
92
|
+
# Resolve the conflicts
|
93
|
+
git add <conflicted files>
|
94
|
+
git commit --no-edit
|
95
|
+
popd
|
96
|
+
|
97
|
+
EOS
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def data
|
103
|
+
@data ||= Data::Base.new({}, @branch_info_file, @git, logger: @logger)
|
104
|
+
end
|
105
|
+
|
106
|
+
def branch
|
107
|
+
@branch ||= data.saved_branches.detect { |branch| branch.ref == working_branch }
|
108
|
+
end
|
109
|
+
|
110
|
+
def working_branch
|
111
|
+
@git.working_branch
|
112
|
+
end
|
113
|
+
|
114
|
+
def in_working_branch
|
115
|
+
@git.in_dir do
|
116
|
+
@git.in_branch(working_branch) do
|
117
|
+
yield
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def flash_flow_directory
|
123
|
+
@git.flash_flow_dir
|
124
|
+
end
|
125
|
+
|
126
|
+
def init_file_contents
|
127
|
+
<<-EOS
|
128
|
+
# Commented this one out because it was causing lots of spurious "saving session..." type messages
|
129
|
+
# [[ -s /etc/profile ]] && source /etc/profile
|
130
|
+
[[ -s ~/.bash_profile ]] && source ~/.bash_profile
|
131
|
+
[[ -s ~/.bash_login ]] && source ~/.bash_login
|
132
|
+
[[ -s ~/.profile ]] && source ~/.profile
|
133
|
+
[[ -s ~/.bashrc ]] && source ~/.bashrc
|
134
|
+
|
135
|
+
PS1='flash_flow resolve: (type "exit" after your conflicts are resolved)$ '
|
136
|
+
EOS
|
137
|
+
end
|
138
|
+
|
139
|
+
def check_for_conflict
|
140
|
+
raise NothingToResolve.new("The current branch (#{working_branch}) does not appear to be in conflict.") unless branch.conflict_sha
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|