git-contest 0.2.4 → 0.2.5
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 +8 -8
- data/.travis.yml +21 -3
- data/README.md +5 -0
- data/Rakefile +8 -0
- data/appveyor.yml +21 -0
- data/bin/git-contest +4 -33
- data/bin/git-contest-config +4 -241
- data/bin/git-contest-finish +4 -151
- data/bin/git-contest-init +4 -65
- data/bin/git-contest-list +4 -64
- data/bin/git-contest-rebase +4 -64
- data/bin/git-contest-start +4 -57
- data/bin/git-contest-submit +4 -183
- data/git-contest.gemspec +2 -1
- data/lib/contest/driver/base.rb +7 -4
- data/lib/git/contest/command_line.rb +10 -0
- data/lib/git/contest/command_line/command.rb +117 -0
- data/lib/git/contest/command_line/main_command.rb +56 -0
- data/lib/git/contest/command_line/sub_commands.rb +35 -0
- data/lib/git/contest/command_line/sub_commands/config_command.rb +258 -0
- data/lib/git/contest/command_line/sub_commands/finish_command.rb +161 -0
- data/lib/git/contest/command_line/sub_commands/init_command.rb +79 -0
- data/lib/git/contest/command_line/sub_commands/list_command.rb +89 -0
- data/lib/git/contest/command_line/sub_commands/rebase_command.rb +87 -0
- data/lib/git/contest/command_line/sub_commands/start_command.rb +77 -0
- data/lib/git/contest/command_line/sub_commands/submit_command.rb +220 -0
- data/lib/git/contest/common.rb +6 -6
- data/lib/git/contest/git.rb +160 -156
- data/lib/git/contest/version.rb +1 -1
- data/spec/command/t004_git_contest_submit_spec.rb +254 -0
- data/spec/command/t005_git_contest_branching_spec.rb +90 -0
- data/spec/command/t007_git_contest_start_spec.rb +95 -0
- data/spec/command/t008_git_contest_finish_spec.rb +171 -0
- data/spec/command/t009_git_contest_init_spec.rb +85 -0
- data/spec/command/t012_git_contest_list_spec.rb +123 -0
- data/spec/command/t013_git_contest_config_spec.rb +186 -0
- data/spec/{lib/contest/driver → contest_driver}/t001_aizu_online_judge_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t002_codeforces_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t003_uva_online_judge_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t010_kattis_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t011_utils_spec.rb +0 -0
- data/spec/spec_helper.rb +18 -12
- data/spec/t006_config_spec.rb +37 -31
- metadata +57 -33
- data/spec/bin/t004_git_contest_submit_spec.rb +0 -223
- data/spec/bin/t005_git_contest_branching_spec.rb +0 -70
- data/spec/bin/t007_git_contest_start_spec.rb +0 -88
- data/spec/bin/t008_git_contest_finish_spec.rb +0 -162
- data/spec/bin/t009_git_contest_init_spec.rb +0 -55
- data/spec/bin/t012_git_contest_list_spec.rb +0 -99
- data/spec/bin/t013_git_contest_config_spec.rb +0 -149
- data/spec/spec_list.txt +0 -1
@@ -0,0 +1,220 @@
|
|
1
|
+
#
|
2
|
+
# git-contest-submit
|
3
|
+
# https://github.com/sh19910711/git-contest
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2014 Hiroyuki Sano <sh19910711 at gmail.com>
|
6
|
+
# Licensed under the MIT-License.
|
7
|
+
#
|
8
|
+
|
9
|
+
module CommandLine
|
10
|
+
|
11
|
+
module SubCommands
|
12
|
+
|
13
|
+
class SubmitCommand < Command
|
14
|
+
|
15
|
+
def initialize(new_args, new_input_stream = STDIN)
|
16
|
+
super
|
17
|
+
|
18
|
+
# load sites
|
19
|
+
$config = get_config() || {}
|
20
|
+
$sites = {}
|
21
|
+
if $config.has_key? 'sites'
|
22
|
+
$sites = $config["sites"]
|
23
|
+
end
|
24
|
+
|
25
|
+
# load drivers
|
26
|
+
Contest::Driver::Utils.load_plugins
|
27
|
+
|
28
|
+
$drivers = {}
|
29
|
+
load_drivers
|
30
|
+
end
|
31
|
+
|
32
|
+
def define_options
|
33
|
+
opt_parser.on "-h", "--help", "help" do
|
34
|
+
usage
|
35
|
+
exit 0
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_default_options
|
40
|
+
end
|
41
|
+
|
42
|
+
def run
|
43
|
+
|
44
|
+
# check options
|
45
|
+
sub_commands = $sites.keys
|
46
|
+
|
47
|
+
# detect site
|
48
|
+
unless has_next_token?
|
49
|
+
usage
|
50
|
+
exit 0
|
51
|
+
end
|
52
|
+
|
53
|
+
site = next_token.strip
|
54
|
+
|
55
|
+
unless $sites.has_key?(site)
|
56
|
+
if site != ""
|
57
|
+
puts "site not found"
|
58
|
+
else
|
59
|
+
usage
|
60
|
+
end
|
61
|
+
exit 0
|
62
|
+
end
|
63
|
+
|
64
|
+
# detect driver
|
65
|
+
driver_name = $sites[site]["driver"]
|
66
|
+
|
67
|
+
unless $drivers.has_key?(driver_name)
|
68
|
+
puts "driver not found"
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Submit Start
|
74
|
+
#
|
75
|
+
driver = $drivers[driver_name].new(args)
|
76
|
+
|
77
|
+
$submit_info = {}
|
78
|
+
|
79
|
+
# set events
|
80
|
+
driver.on(
|
81
|
+
'start',
|
82
|
+
Proc.new do
|
83
|
+
puts "@start: submit"
|
84
|
+
end
|
85
|
+
)
|
86
|
+
|
87
|
+
driver.on(
|
88
|
+
'before_login',
|
89
|
+
Proc.new do
|
90
|
+
puts "@submit: logging in..."
|
91
|
+
end
|
92
|
+
)
|
93
|
+
|
94
|
+
driver.on(
|
95
|
+
'after_login',
|
96
|
+
Proc.new do
|
97
|
+
puts "@submit: login ok"
|
98
|
+
end
|
99
|
+
)
|
100
|
+
|
101
|
+
driver.on(
|
102
|
+
'before_submit',
|
103
|
+
Proc.new do |submit_info|
|
104
|
+
$submit_info = submit_info
|
105
|
+
puts "@submit: doing..."
|
106
|
+
end
|
107
|
+
)
|
108
|
+
|
109
|
+
driver.on(
|
110
|
+
'after_submit',
|
111
|
+
Proc.new do
|
112
|
+
puts "@submit: done"
|
113
|
+
end
|
114
|
+
)
|
115
|
+
|
116
|
+
driver.on(
|
117
|
+
'before_wait',
|
118
|
+
Proc.new do
|
119
|
+
print "@result: waiting..."
|
120
|
+
end
|
121
|
+
)
|
122
|
+
|
123
|
+
driver.on(
|
124
|
+
'retry',
|
125
|
+
Proc.new do
|
126
|
+
print "."
|
127
|
+
end
|
128
|
+
)
|
129
|
+
|
130
|
+
driver.on(
|
131
|
+
'after_wait',
|
132
|
+
Proc.new do |submission_info|
|
133
|
+
puts ""
|
134
|
+
next unless submission_info.is_a?(Hash)
|
135
|
+
puts ""
|
136
|
+
puts "@result: Submission Result"
|
137
|
+
puts " %s: %s" % ["submission id", "#{submission_info[:submission_id]}"]
|
138
|
+
puts " %s: %s" % ["status", "#{submission_info[:status]}"]
|
139
|
+
puts ""
|
140
|
+
if Git.contest_is_initialized
|
141
|
+
puts "@commit"
|
142
|
+
Git.do "add #{get_git_add_target($config["submit_rules"]["add"] || ".")}"
|
143
|
+
Git.do "commit --allow-empty -m \"#{submission_info[:result]}\""
|
144
|
+
end
|
145
|
+
end
|
146
|
+
)
|
147
|
+
|
148
|
+
driver.on(
|
149
|
+
'finish',
|
150
|
+
Proc.new do
|
151
|
+
puts "@finish"
|
152
|
+
end
|
153
|
+
)
|
154
|
+
|
155
|
+
# global config
|
156
|
+
$config["submit_rules"] ||= {}
|
157
|
+
$config["file"] ||= {}
|
158
|
+
|
159
|
+
# set config
|
160
|
+
driver.config = $sites[site]
|
161
|
+
driver.config.merge! $config
|
162
|
+
|
163
|
+
# parse driver options
|
164
|
+
driver.options = driver.get_opts()
|
165
|
+
|
166
|
+
result = driver.submit()
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
# Load Drivers
|
173
|
+
#
|
174
|
+
def load_drivers
|
175
|
+
driver_names = $sites.keys().map {|key| $sites[key]["driver"] }
|
176
|
+
driver_names.uniq.each do |driver_name|
|
177
|
+
class_name = driver_name.clone
|
178
|
+
class_name.gsub!(/^[a-z]/) {|c| c.upcase }
|
179
|
+
class_name.gsub!(/(_)([a-z])/) {|c, b| $2.upcase }
|
180
|
+
$drivers[driver_name] = Contest::Driver.const_get "#{class_name}Driver"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
#
|
185
|
+
# Command Utils
|
186
|
+
#
|
187
|
+
def usage
|
188
|
+
puts get_banner
|
189
|
+
return 0
|
190
|
+
end
|
191
|
+
|
192
|
+
def get_banner
|
193
|
+
res = ""
|
194
|
+
res += "usage: git contest submit <site>\n"
|
195
|
+
res += "\n"
|
196
|
+
res += "Available sites are:\n"
|
197
|
+
$sites.keys().each do |site|
|
198
|
+
if $drivers.has_key? $sites[site]["driver"]
|
199
|
+
driver = $drivers[$sites[site]["driver"]].new
|
200
|
+
res += " %-12s\t#{driver.get_desc}\n" % [site]
|
201
|
+
else
|
202
|
+
# TODO: driver not found
|
203
|
+
end
|
204
|
+
end
|
205
|
+
res += "\n"
|
206
|
+
res += "Try 'git contest submit <site> --help' for details.\n"
|
207
|
+
return res
|
208
|
+
end
|
209
|
+
|
210
|
+
def get_git_add_target rule
|
211
|
+
str = rule
|
212
|
+
str = str.gsub('${source}', $submit_info[:source])
|
213
|
+
str
|
214
|
+
end
|
215
|
+
|
216
|
+
end # SubmitCommand
|
217
|
+
|
218
|
+
end # SubCommands
|
219
|
+
|
220
|
+
end # CommandLine
|
data/lib/git/contest/common.rb
CHANGED
@@ -17,12 +17,12 @@ def init
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def init_global
|
20
|
-
$git_contest_home = File.expand_path(ENV['GIT_CONTEST_HOME'] || "
|
21
|
-
$git_contest_config = File.expand_path(ENV['GIT_CONTEST_CONFIG'] ||
|
22
|
-
if
|
23
|
-
$MASTER =
|
24
|
-
$PREFIX =
|
25
|
-
$ORIGIN =
|
20
|
+
$git_contest_home = File.expand_path(ENV['GIT_CONTEST_HOME'] || File.join("~", ".git-contest"))
|
21
|
+
$git_contest_config = File.expand_path(ENV['GIT_CONTEST_CONFIG'] || File.join($git_contest_home, "config.yml"))
|
22
|
+
if Git.do_no_echo 'branch'
|
23
|
+
$MASTER = Git.do 'config --get git.contest.branch.master'
|
24
|
+
$PREFIX = Git.do 'config --get git.contest.branch.prefix'
|
25
|
+
$ORIGIN = Git.do 'config --get git.contest.origin'
|
26
26
|
if $ORIGIN == ''
|
27
27
|
$ORIGIN = 'origin'
|
28
28
|
end
|
data/lib/git/contest/git.rb
CHANGED
@@ -5,185 +5,189 @@
|
|
5
5
|
# Licensed under the MIT-License.
|
6
6
|
#
|
7
7
|
|
8
|
-
|
9
|
-
puts "git #{args.join(' ')}" if ENV['GIT_CONTEST_DEBUG'] == 'ON'
|
10
|
-
return `git #{args.join(' ')} 2>&1`.strip
|
11
|
-
end
|
8
|
+
module Git
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
10
|
+
def self.do(*args)
|
11
|
+
puts "git #{args.join(' ')}" if ENV['GIT_CONTEST_DEBUG'] == 'ON'
|
12
|
+
`git #{args.join(' ')} 2>&1`.strip
|
13
|
+
end
|
18
14
|
|
19
|
-
#
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
def git_contest_has_master_configured
|
27
|
-
master = (git_do 'config --get git.contest.branch.master').strip
|
28
|
-
master != '' && git_local_branches().include?(master)
|
29
|
-
end
|
30
|
-
|
31
|
-
def git_contest_has_develop_configured
|
32
|
-
develop = (git_do 'config --get git.contest.branch.develop').strip
|
33
|
-
develop != '' && git_local_branches().include?(develop)
|
34
|
-
end
|
35
|
-
|
36
|
-
def git_contest_has_prefix_configured
|
37
|
-
git_do_no_echo 'config --get git.contest.branch.prefix'
|
38
|
-
end
|
39
|
-
|
40
|
-
def git_contest_resolve_nameprefix name, prefix
|
41
|
-
if git_local_branch_exists "#{prefix}/#{name}"
|
42
|
-
return name
|
43
|
-
end
|
44
|
-
branches = git_local_branches().select {|branch| branch.start_with? "#{prefix}/#{name}" }
|
45
|
-
if branches.size == 0
|
46
|
-
abort "No branch matches prefix '#{name}'"
|
47
|
-
else
|
48
|
-
if branches.size == 1
|
49
|
-
return branches[0][prefix.length..-1]
|
50
|
-
else
|
51
|
-
abort "Multiple branches match prefix '#{name}'"
|
52
|
-
end
|
15
|
+
# use return value
|
16
|
+
def self.do_no_echo(*args)
|
17
|
+
puts "git #{args.join(' ')}" if ENV['GIT_CONTEST_DEBUG'] == 'ON'
|
18
|
+
`git #{args.join(' ')} 2>&1`
|
19
|
+
$?.success?
|
53
20
|
end
|
54
|
-
end
|
55
21
|
|
56
|
-
#
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
git_local_branches().include?(branch_name)
|
63
|
-
end
|
64
|
-
|
65
|
-
def git_branch_exists(branch_name)
|
66
|
-
git_all_branches().include?(branch_name)
|
67
|
-
end
|
68
|
-
|
69
|
-
def git_remote_branches
|
70
|
-
cmd_ret = git_do 'branch -r --no-color'
|
71
|
-
cmd_ret.lines.map {|line|
|
72
|
-
line.gsub(/^[*]?\s*/, '').gsub(/\s*$/, '').strip
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
|
-
def git_local_branches
|
77
|
-
cmd_ret = git_do 'branch --no-color'
|
78
|
-
cmd_ret.lines.map {|line|
|
79
|
-
line.gsub(/^[*]?\s*/, '').gsub(/\s*$/, '').strip
|
80
|
-
}
|
81
|
-
end
|
82
|
-
|
83
|
-
def git_all_branches
|
84
|
-
cmd_ret1 = git_do 'branch --no-color'
|
85
|
-
cmd_ret2 = git_do 'branch -r --no-color'
|
86
|
-
lines = ( cmd_ret1 + cmd_ret2 ).lines
|
87
|
-
lines.map {|line|
|
88
|
-
line.gsub(/^[*]?\s*/, '').gsub(/\s*$/, '').strip
|
89
|
-
}
|
90
|
-
end
|
91
|
-
|
92
|
-
def git_current_branch
|
93
|
-
ret = git_do('branch --no-color').lines
|
94
|
-
ret = ret.grep /^\*/
|
95
|
-
ret[0].gsub(/^[* ] /, '').strip
|
96
|
-
end
|
97
|
-
|
98
|
-
def git_is_clean_working_tree
|
99
|
-
if ! git_do_no_echo 'diff --no-ext-diff --ignore-submodules --quiet --exit-code'
|
100
|
-
return 1
|
101
|
-
elsif ! git_do_no_echo 'diff-index --cached --quiet --ignore-submodules HEAD --'
|
102
|
-
return 2
|
103
|
-
else
|
104
|
-
return 0
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def git_repo_is_headless
|
109
|
-
! git_do_no_echo 'rev-parse --quiet --verify HEAD'
|
110
|
-
end
|
22
|
+
#
|
23
|
+
def self.contest_is_initialized
|
24
|
+
Git.contest_has_master_configured &&
|
25
|
+
Git.contest_has_prefix_configured &&
|
26
|
+
Git.do('config --get git.contest.branch.master') != Git.do('config --get git.contest.branch.develop')
|
27
|
+
end
|
111
28
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
29
|
+
def self.contest_has_master_configured
|
30
|
+
master = (Git.do 'config --get git.contest.branch.master').strip
|
31
|
+
master != '' && Git.local_branches().include?(master)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.contest_has_develop_configured
|
35
|
+
develop = (Git.do 'config --get git.contest.branch.develop').strip
|
36
|
+
develop != '' && Git.local_branches().include?(develop)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.contest_has_prefix_configured
|
40
|
+
Git.do_no_echo 'config --get git.contest.branch.prefix'
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.contest_resolve_nameprefix name, prefix
|
44
|
+
if Git.local_branch_exists "#{prefix}/#{name}"
|
45
|
+
return name
|
46
|
+
end
|
47
|
+
branches = Git.local_branches().select {|branch| branch.start_with? "#{prefix}/#{name}" }
|
48
|
+
if branches.size == 0
|
49
|
+
abort "No branch matches prefix '#{name}'"
|
125
50
|
else
|
126
|
-
|
127
|
-
|
128
|
-
return 1
|
129
|
-
elsif commit2 == base
|
130
|
-
return 2
|
51
|
+
if branches.size == 1
|
52
|
+
return branches[0][prefix.length..-1]
|
131
53
|
else
|
132
|
-
|
54
|
+
abort "Multiple branches match prefix '#{name}'"
|
133
55
|
end
|
134
56
|
end
|
135
|
-
else
|
136
|
-
return 0
|
137
57
|
end
|
138
|
-
end
|
139
58
|
|
140
|
-
|
141
|
-
|
142
|
-
|
59
|
+
#
|
60
|
+
def self.remote_branch_exists(branch_name)
|
61
|
+
Git.remote_branches().include?(branch_name)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.local_branch_exists(branch_name)
|
65
|
+
Git.local_branches().include?(branch_name)
|
143
66
|
end
|
144
|
-
end
|
145
67
|
|
146
|
-
def
|
147
|
-
|
148
|
-
abort "Branch #{branch} already exists. Pick another name."
|
68
|
+
def self.branch_exists(branch_name)
|
69
|
+
Git.all_branches().include?(branch_name)
|
149
70
|
end
|
150
|
-
end
|
151
71
|
|
152
|
-
def
|
153
|
-
|
154
|
-
|
155
|
-
|
72
|
+
def self.remote_branches
|
73
|
+
cmd_ret = Git.do 'branch -r --no-color'
|
74
|
+
cmd_ret.lines.map {|line|
|
75
|
+
line.gsub(/^[*]?\s*/, '').gsub(/\s*$/, '').strip
|
76
|
+
}
|
156
77
|
end
|
157
|
-
|
158
|
-
|
78
|
+
|
79
|
+
def self.local_branches
|
80
|
+
cmd_ret = Git.do 'branch --no-color'
|
81
|
+
cmd_ret.lines.map {|line|
|
82
|
+
line.gsub(/^[*]?\s*/, '').gsub(/\s*$/, '').strip
|
83
|
+
}
|
159
84
|
end
|
160
|
-
end
|
161
85
|
|
162
|
-
def
|
163
|
-
|
164
|
-
|
86
|
+
def self.all_branches
|
87
|
+
cmd_ret1 = Git.do 'branch --no-color'
|
88
|
+
cmd_ret2 = Git.do 'branch -r --no-color'
|
89
|
+
lines = ( cmd_ret1 + cmd_ret2 ).lines
|
90
|
+
lines.map {|line|
|
91
|
+
line.gsub(/^[*]?\s*/, '').gsub(/\s*$/, '').strip
|
92
|
+
}
|
165
93
|
end
|
166
|
-
end
|
167
94
|
|
168
|
-
def
|
169
|
-
|
170
|
-
|
95
|
+
def self.current_branch
|
96
|
+
ret = Git.do('branch --no-color').lines
|
97
|
+
ret = ret.grep /^\*/
|
98
|
+
ret[0].gsub(/^[* ] /, '').strip
|
171
99
|
end
|
172
|
-
end
|
173
100
|
|
174
|
-
def
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
puts "Branches '#{local}' and '#{remote}' have diverged."
|
180
|
-
if ret == 1
|
181
|
-
abort "And branch #{local} may be fast-forwarded."
|
182
|
-
elsif ret == 2
|
183
|
-
puts "And local branch #{local} is ahead of #{remote}"
|
101
|
+
def self.is_clean_working_tree
|
102
|
+
if ! Git.do_no_echo 'diff --no-ext-diff --ignore-submodules --quiet --exit-code'
|
103
|
+
return 1
|
104
|
+
elsif ! Git.do_no_echo 'diff-index --cached --quiet --ignore-submodules HEAD --'
|
105
|
+
return 2
|
184
106
|
else
|
185
|
-
|
107
|
+
return 0
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.repo_is_headless
|
112
|
+
! Git.do_no_echo 'rev-parse --quiet --verify HEAD'
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# 0: same
|
117
|
+
# 1: first branch needs ff
|
118
|
+
# 2: second branch needs ff
|
119
|
+
# 3: branch needs merge
|
120
|
+
# 4: there is no merge
|
121
|
+
#
|
122
|
+
def self.compare_branches first, second
|
123
|
+
commit1 = Git.do "rev-parse \"#{first}\""
|
124
|
+
commit2 = Git.do "rev-parse \"#{second}\""
|
125
|
+
if commit1 != commit2
|
126
|
+
if Git.do_no_echo("merge-base \"#{commit1}\" \"#{commit2}\"")
|
127
|
+
return 4
|
128
|
+
else
|
129
|
+
base = Git.do "merge-base \"#{commit1}\" \"#{commit2}\""
|
130
|
+
if commit1 == base
|
131
|
+
return 1
|
132
|
+
elsif commit2 == base
|
133
|
+
return 2
|
134
|
+
else
|
135
|
+
return 3
|
136
|
+
end
|
137
|
+
end
|
138
|
+
else
|
139
|
+
return 0
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.require_branch(branch)
|
144
|
+
if ! Git.all_branches().include?(branch)
|
145
|
+
abort "Branch #{branch} does not exist."
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.require_branch_absent(branch)
|
150
|
+
if Git.all_branches().include?(branch)
|
151
|
+
abort "Branch #{branch} already exists. Pick another name."
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.require_clean_working_tree
|
156
|
+
ret = Git.is_clean_working_tree
|
157
|
+
if ret == 1
|
158
|
+
abort "fatal: Working tree contains unstaged changes. Aborting."
|
159
|
+
end
|
160
|
+
if ret == 2
|
161
|
+
abort "fatal: Index contains uncommited changes. Aborting."
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.require_local_branch branch
|
166
|
+
if ! Git.local_branch_exists branch
|
167
|
+
abort "fatal: Local branch '#{branch}' does not exist and is required."
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.require_remote_branch branch
|
172
|
+
if ! Git.remote_branch_exists branch
|
173
|
+
abort "fatal: Remote branch '#{branch}' does not exist and is required."
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.require_branches_equal local, remote
|
178
|
+
Git.require_local_branch local
|
179
|
+
Git.require_remote_branch remote
|
180
|
+
ret = Git.compare_branches local, remote
|
181
|
+
if ret > 0
|
182
|
+
puts "Branches '#{local}' and '#{remote}' have diverged."
|
183
|
+
if ret == 1
|
184
|
+
abort "And branch #{local} may be fast-forwarded."
|
185
|
+
elsif ret == 2
|
186
|
+
puts "And local branch #{local} is ahead of #{remote}"
|
187
|
+
else
|
188
|
+
abort "Branches need merging first."
|
189
|
+
end
|
186
190
|
end
|
187
191
|
end
|
188
|
-
end
|
189
192
|
|
193
|
+
end # Git
|