jawshooah-overcommit 0.22.0
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/bin/overcommit +8 -0
- data/config/default.yml +275 -0
- data/config/starter.yml +31 -0
- data/lib/overcommit.rb +20 -0
- data/lib/overcommit/cli.rb +205 -0
- data/lib/overcommit/configuration.rb +183 -0
- data/lib/overcommit/configuration_loader.rb +49 -0
- data/lib/overcommit/configuration_validator.rb +40 -0
- data/lib/overcommit/constants.rb +8 -0
- data/lib/overcommit/exceptions.rb +35 -0
- data/lib/overcommit/git_repo.rb +147 -0
- data/lib/overcommit/hook/base.rb +174 -0
- data/lib/overcommit/hook/commit_msg/base.rb +11 -0
- data/lib/overcommit/hook/commit_msg/gerrit_change_id.rb +18 -0
- data/lib/overcommit/hook/commit_msg/hard_tabs.rb +13 -0
- data/lib/overcommit/hook/commit_msg/russian_novel.rb +14 -0
- data/lib/overcommit/hook/commit_msg/single_line_subject.rb +12 -0
- data/lib/overcommit/hook/commit_msg/text_width.rb +38 -0
- data/lib/overcommit/hook/commit_msg/trailing_period.rb +12 -0
- data/lib/overcommit/hook/post_checkout/base.rb +11 -0
- data/lib/overcommit/hook/post_checkout/index_tags.rb +26 -0
- data/lib/overcommit/hook/post_commit/base.rb +11 -0
- data/lib/overcommit/hook/post_commit/git_guilt.rb +9 -0
- data/lib/overcommit/hook/pre_commit/author_email.rb +18 -0
- data/lib/overcommit/hook/pre_commit/author_name.rb +17 -0
- data/lib/overcommit/hook/pre_commit/base.rb +70 -0
- data/lib/overcommit/hook/pre_commit/berksfile_check.rb +20 -0
- data/lib/overcommit/hook/pre_commit/brakeman.rb +12 -0
- data/lib/overcommit/hook/pre_commit/broken_symlinks.rb +15 -0
- data/lib/overcommit/hook/pre_commit/bundle_check.rb +25 -0
- data/lib/overcommit/hook/pre_commit/chamber_security.rb +11 -0
- data/lib/overcommit/hook/pre_commit/coffee_lint.rb +11 -0
- data/lib/overcommit/hook/pre_commit/css_lint.rb +11 -0
- data/lib/overcommit/hook/pre_commit/go_lint.rb +12 -0
- data/lib/overcommit/hook/pre_commit/haml_lint.rb +19 -0
- data/lib/overcommit/hook/pre_commit/hard_tabs.rb +14 -0
- data/lib/overcommit/hook/pre_commit/image_optim.rb +41 -0
- data/lib/overcommit/hook/pre_commit/js_hint.rb +13 -0
- data/lib/overcommit/hook/pre_commit/jscs.rb +22 -0
- data/lib/overcommit/hook/pre_commit/json_syntax.rb +22 -0
- data/lib/overcommit/hook/pre_commit/jsx_hint.rb +13 -0
- data/lib/overcommit/hook/pre_commit/jsxcs.rb +20 -0
- data/lib/overcommit/hook/pre_commit/local_paths_in_gemfile.rb +14 -0
- data/lib/overcommit/hook/pre_commit/merge_conflicts.rb +14 -0
- data/lib/overcommit/hook/pre_commit/pry_binding.rb +14 -0
- data/lib/overcommit/hook/pre_commit/python_flake8.rb +11 -0
- data/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +45 -0
- data/lib/overcommit/hook/pre_commit/reek.rb +22 -0
- data/lib/overcommit/hook/pre_commit/rubocop.rb +19 -0
- data/lib/overcommit/hook/pre_commit/scss_lint.rb +19 -0
- data/lib/overcommit/hook/pre_commit/shell_check.rb +19 -0
- data/lib/overcommit/hook/pre_commit/trailing_whitespace.rb +13 -0
- data/lib/overcommit/hook/pre_commit/travis_lint.rb +11 -0
- data/lib/overcommit/hook/pre_commit/yaml_syntax.rb +22 -0
- data/lib/overcommit/hook_context.rb +17 -0
- data/lib/overcommit/hook_context/base.rb +69 -0
- data/lib/overcommit/hook_context/commit_msg.rb +32 -0
- data/lib/overcommit/hook_context/post_checkout.rb +26 -0
- data/lib/overcommit/hook_context/post_commit.rb +19 -0
- data/lib/overcommit/hook_context/pre_commit.rb +148 -0
- data/lib/overcommit/hook_context/run_all.rb +39 -0
- data/lib/overcommit/hook_loader/base.rb +36 -0
- data/lib/overcommit/hook_loader/built_in_hook_loader.rb +12 -0
- data/lib/overcommit/hook_loader/plugin_hook_loader.rb +61 -0
- data/lib/overcommit/hook_runner.rb +129 -0
- data/lib/overcommit/hook_signer.rb +79 -0
- data/lib/overcommit/installer.rb +148 -0
- data/lib/overcommit/interrupt_handler.rb +87 -0
- data/lib/overcommit/logger.rb +79 -0
- data/lib/overcommit/message_processor.rb +132 -0
- data/lib/overcommit/printer.rb +116 -0
- data/lib/overcommit/subprocess.rb +46 -0
- data/lib/overcommit/utils.rb +163 -0
- data/lib/overcommit/version.rb +4 -0
- data/libexec/gerrit-change-id +174 -0
- data/libexec/index-tags +17 -0
- data/template-dir/hooks/commit-msg +81 -0
- data/template-dir/hooks/overcommit-hook +81 -0
- data/template-dir/hooks/post-checkout +81 -0
- data/template-dir/hooks/pre-commit +81 -0
- metadata +184 -0
@@ -0,0 +1,183 @@
|
|
1
|
+
module Overcommit
|
2
|
+
# Stores configuration for Overcommit and the hooks it runs.
|
3
|
+
class Configuration # rubocop:disable ClassLength
|
4
|
+
# Creates a configuration from the given hash.
|
5
|
+
def initialize(hash)
|
6
|
+
@hash = ConfigurationValidator.new.validate(hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
def ==(other)
|
10
|
+
super || @hash == other.hash
|
11
|
+
end
|
12
|
+
alias_method :eql?, :==
|
13
|
+
|
14
|
+
# Returns absolute path to the directory that external hook plugins should
|
15
|
+
# be loaded from.
|
16
|
+
def plugin_directory
|
17
|
+
File.join(Overcommit::Utils.repo_root, @hash['plugin_directory'] || '.githooks')
|
18
|
+
end
|
19
|
+
|
20
|
+
def verify_plugin_signatures?
|
21
|
+
@hash['verify_plugin_signatures'] != false
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns configuration for all hooks in each hook type.
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
27
|
+
def all_hook_configs
|
28
|
+
smart_merge(all_builtin_hook_configs, all_plugin_hook_configs)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns configuration for all built-in hooks in each hook type.
|
32
|
+
#
|
33
|
+
# @return [Hash]
|
34
|
+
def all_builtin_hook_configs
|
35
|
+
hook_configs = {}
|
36
|
+
|
37
|
+
Overcommit::Utils.supported_hook_type_classes.each do |hook_type|
|
38
|
+
hook_names = @hash[hook_type].keys.reject { |name| name == 'ALL' }
|
39
|
+
|
40
|
+
hook_configs[hook_type] = Hash[
|
41
|
+
hook_names.map do |hook_name|
|
42
|
+
[hook_name, for_hook(hook_name, hook_type)]
|
43
|
+
end
|
44
|
+
]
|
45
|
+
end
|
46
|
+
|
47
|
+
hook_configs
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns configuration for all plugin hooks in each hook type.
|
51
|
+
#
|
52
|
+
# @return [Hash]
|
53
|
+
def all_plugin_hook_configs
|
54
|
+
hook_configs = {}
|
55
|
+
|
56
|
+
Overcommit::Utils.supported_hook_types.each do |hook_type|
|
57
|
+
hook_type_class_name = Overcommit::Utils.camel_case(hook_type)
|
58
|
+
|
59
|
+
directory = File.join(plugin_directory, hook_type.gsub('-', '_'))
|
60
|
+
plugin_paths = Dir[File.join(directory, '*.rb')].sort
|
61
|
+
|
62
|
+
hook_names = plugin_paths.map do |path|
|
63
|
+
Overcommit::Utils.camel_case(File.basename(path, '.rb'))
|
64
|
+
end
|
65
|
+
|
66
|
+
hook_configs[hook_type_class_name] = Hash[
|
67
|
+
hook_names.map do |hook_name|
|
68
|
+
[hook_name, for_hook(hook_name, Overcommit::Utils.camel_case(hook_type))]
|
69
|
+
end
|
70
|
+
]
|
71
|
+
end
|
72
|
+
|
73
|
+
hook_configs
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the built-in hooks that have been enabled for a hook type.
|
77
|
+
def enabled_builtin_hooks(hook_context)
|
78
|
+
@hash[hook_context.hook_class_name].keys.
|
79
|
+
select { |hook_name| hook_name != 'ALL' }.
|
80
|
+
select { |hook_name| built_in_hook?(hook_context, hook_name) }.
|
81
|
+
select { |hook_name| hook_enabled?(hook_context, hook_name) }
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns a non-modifiable configuration for a hook.
|
85
|
+
def for_hook(hook, hook_type = nil)
|
86
|
+
unless hook_type
|
87
|
+
components = hook.class.name.split('::')
|
88
|
+
hook = components.last
|
89
|
+
hook_type = components[-2]
|
90
|
+
end
|
91
|
+
|
92
|
+
# Merge hook configuration with special 'ALL' config
|
93
|
+
hook_config = smart_merge(@hash[hook_type]['ALL'], @hash[hook_type][hook] || {})
|
94
|
+
|
95
|
+
# Need to specially handle `enabled` option since not setting it does not
|
96
|
+
# necessarily mean the hook is disabled
|
97
|
+
hook_config['enabled'] = hook_enabled?(hook_type, hook)
|
98
|
+
|
99
|
+
hook_config.freeze
|
100
|
+
end
|
101
|
+
|
102
|
+
# Merges the given configuration with this one, returning a new
|
103
|
+
# {Configuration}. The provided configuration will either add to or replace
|
104
|
+
# any options defined in this configuration.
|
105
|
+
def merge(config)
|
106
|
+
self.class.new(smart_merge(@hash, config.hash))
|
107
|
+
end
|
108
|
+
|
109
|
+
# Applies additional configuration settings based on the provided
|
110
|
+
# environment variables.
|
111
|
+
def apply_environment!(hook_context, env)
|
112
|
+
skipped_hooks = "#{env['SKIP']} #{env['SKIP_CHECKS']} #{env['SKIP_HOOKS']}".split(/[:, ]/)
|
113
|
+
hook_type = hook_context.hook_class_name
|
114
|
+
|
115
|
+
if skipped_hooks.include?('all') || skipped_hooks.include?('ALL')
|
116
|
+
@hash[hook_type]['ALL']['skip'] = true
|
117
|
+
else
|
118
|
+
skipped_hooks.select { |hook_name| hook_exists?(hook_context, hook_name) }.
|
119
|
+
map { |hook_name| Overcommit::Utils.camel_case(hook_name) }.
|
120
|
+
each do |hook_name|
|
121
|
+
@hash[hook_type][hook_name] ||= {}
|
122
|
+
@hash[hook_type][hook_name]['skip'] = true
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def plugin_hook?(hook_context_or_type, hook_name)
|
128
|
+
hook_type_name =
|
129
|
+
if hook_context_or_type.is_a?(String)
|
130
|
+
Overcommit::Utils.snake_case(hook_context_or_type)
|
131
|
+
else
|
132
|
+
hook_context_or_type.hook_type_name
|
133
|
+
end
|
134
|
+
hook_name = Overcommit::Utils.snake_case(hook_name)
|
135
|
+
|
136
|
+
File.exist?(File.join(plugin_directory, hook_type_name, "#{hook_name}.rb"))
|
137
|
+
end
|
138
|
+
|
139
|
+
protected
|
140
|
+
|
141
|
+
attr_reader :hash
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def built_in_hook?(hook_context, hook_name)
|
146
|
+
hook_name = Overcommit::Utils.snake_case(hook_name)
|
147
|
+
|
148
|
+
File.exist?(File.join(OVERCOMMIT_HOME, 'lib', 'overcommit', 'hook',
|
149
|
+
hook_context.hook_type_name, "#{hook_name}.rb"))
|
150
|
+
end
|
151
|
+
|
152
|
+
def hook_exists?(hook_context, hook_name)
|
153
|
+
built_in_hook?(hook_context, hook_name) ||
|
154
|
+
plugin_hook?(hook_context, hook_name)
|
155
|
+
end
|
156
|
+
|
157
|
+
def hook_enabled?(hook_context_or_type, hook_name)
|
158
|
+
hook_type = hook_context_or_type.is_a?(String) ? hook_context_or_type :
|
159
|
+
hook_context_or_type.hook_class_name
|
160
|
+
|
161
|
+
individual_enabled = @hash[hook_type].fetch(hook_name, {})['enabled']
|
162
|
+
return individual_enabled unless individual_enabled.nil?
|
163
|
+
|
164
|
+
all_enabled = @hash[hook_type]['ALL']['enabled']
|
165
|
+
return all_enabled unless all_enabled.nil?
|
166
|
+
|
167
|
+
true
|
168
|
+
end
|
169
|
+
|
170
|
+
def smart_merge(parent, child)
|
171
|
+
parent.merge(child) do |_key, old, new|
|
172
|
+
case old
|
173
|
+
when Array
|
174
|
+
old + Array(new)
|
175
|
+
when Hash
|
176
|
+
smart_merge(old, new)
|
177
|
+
else
|
178
|
+
new
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Overcommit
|
4
|
+
# Manages configuration file loading.
|
5
|
+
class ConfigurationLoader
|
6
|
+
DEFAULT_CONFIG_PATH = File.join(OVERCOMMIT_HOME, 'config', 'default.yml')
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def load_repo_config
|
10
|
+
overcommit_yml = File.join(Overcommit::Utils.repo_root,
|
11
|
+
OVERCOMMIT_CONFIG_FILE_NAME)
|
12
|
+
|
13
|
+
if File.exist?(overcommit_yml)
|
14
|
+
load_file(overcommit_yml)
|
15
|
+
else
|
16
|
+
default_configuration
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def default_configuration
|
21
|
+
@default_config ||= load_from_file(DEFAULT_CONFIG_PATH)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Loads a configuration, ensuring it extends the default configuration.
|
27
|
+
def load_file(file)
|
28
|
+
config = load_from_file(file)
|
29
|
+
|
30
|
+
default_configuration.merge(config)
|
31
|
+
rescue => error
|
32
|
+
raise Overcommit::Exceptions::ConfigurationError,
|
33
|
+
"Unable to load configuration from '#{file}': #{error}",
|
34
|
+
error.backtrace
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_from_file(file)
|
38
|
+
hash =
|
39
|
+
if yaml = YAML.load_file(file)
|
40
|
+
yaml.to_hash
|
41
|
+
else
|
42
|
+
{}
|
43
|
+
end
|
44
|
+
|
45
|
+
Overcommit::Configuration.new(hash)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Overcommit
|
2
|
+
# Validates and normalizes a configuration.
|
3
|
+
class ConfigurationValidator
|
4
|
+
# Validates hash for any invalid options, normalizing where possible.
|
5
|
+
def validate(hash)
|
6
|
+
hash = convert_nils_to_empty_hashes(hash)
|
7
|
+
ensure_hook_type_sections_exist(hash)
|
8
|
+
|
9
|
+
hash
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# Ensures that keys for all supported hook types exist (PreCommit,
|
15
|
+
# CommitMsg, etc.)
|
16
|
+
def ensure_hook_type_sections_exist(hash)
|
17
|
+
Overcommit::Utils.supported_hook_type_classes.each do |hook_type|
|
18
|
+
hash[hook_type] ||= {}
|
19
|
+
hash[hook_type]['ALL'] ||= {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Normalizes `nil` values to empty hashes.
|
24
|
+
#
|
25
|
+
# This is useful for when we want to merge two configuration hashes
|
26
|
+
# together, since it's easier to merge two hashes than to have to check if
|
27
|
+
# one of the values is nil.
|
28
|
+
def convert_nils_to_empty_hashes(hash)
|
29
|
+
hash.each_with_object({}) do |(key, value), h|
|
30
|
+
h[key] =
|
31
|
+
case value
|
32
|
+
when nil then {}
|
33
|
+
when Hash then convert_nils_to_empty_hashes(value)
|
34
|
+
else
|
35
|
+
value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Global application constants.
|
2
|
+
module Overcommit
|
3
|
+
OVERCOMMIT_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
4
|
+
OVERCOMMIT_CONFIG_FILE_NAME = '.overcommit.yml'
|
5
|
+
|
6
|
+
REPO_URL = 'https://github.com/causes/overcommit'
|
7
|
+
BUG_REPORT_URL = "#{REPO_URL}/issues"
|
8
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Overcommit::Exceptions
|
2
|
+
# Raised when a {Configuration} could not be loaded from a file.
|
3
|
+
class ConfigurationError < StandardError; end
|
4
|
+
|
5
|
+
# Raised when trying to read/write to/from the local repo git config fails.
|
6
|
+
class GitConfigError < StandardError; end
|
7
|
+
|
8
|
+
# Raised when a {HookContext} is unable to setup the environment before a run.
|
9
|
+
class HookSetupFailed < StandardError; end
|
10
|
+
|
11
|
+
# Raised when a {HookContext} is unable to clean the environment after a run.
|
12
|
+
class HookCleanupFailed < StandardError; end
|
13
|
+
|
14
|
+
# Raised when a hook run was cancelled by the user.
|
15
|
+
class HookCancelled < StandardError; end
|
16
|
+
|
17
|
+
# Raised when a hook could not be loaded by a {HookRunner}.
|
18
|
+
class HookLoadError < StandardError; end
|
19
|
+
|
20
|
+
# Raised when a {HookRunner} could not be loaded.
|
21
|
+
class HookContextLoadError < StandardError; end
|
22
|
+
|
23
|
+
# Raised when a pipe character is used in the `execute` helper, as this was
|
24
|
+
# likely used in error.
|
25
|
+
class InvalidCommandArgs < StandardError; end
|
26
|
+
|
27
|
+
# Raised when an installation target is not a valid git repository.
|
28
|
+
class InvalidGitRepo < StandardError; end
|
29
|
+
|
30
|
+
# Raised when one or more hook plugin signatures have changed.
|
31
|
+
class InvalidHookSignature < StandardError; end
|
32
|
+
|
33
|
+
# Raised when an installation target already contains non-Overcommit hooks.
|
34
|
+
class PreExistingHooks < StandardError; end
|
35
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module Overcommit
|
2
|
+
# Provide a set of utilities for certain interactions with `git`.
|
3
|
+
module GitRepo
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# Regular expression used to extract diff ranges from hunks of diff output.
|
7
|
+
DIFF_HUNK_REGEX = /
|
8
|
+
^@@\s
|
9
|
+
[^\s]+\s # Ignore old file range
|
10
|
+
\+(\d+)(?:,(\d+))? # Extract range of hunk containing start line and number of lines
|
11
|
+
\s@@.*$
|
12
|
+
/x
|
13
|
+
|
14
|
+
# Extract the set of modified lines from a given file.
|
15
|
+
#
|
16
|
+
# @param file_path [String]
|
17
|
+
# @param options [Hash]
|
18
|
+
# @return [Set] line numbers that have been modified in file
|
19
|
+
def extract_modified_lines(file_path, options)
|
20
|
+
lines = Set.new
|
21
|
+
|
22
|
+
flags = '--cached' if options[:staged]
|
23
|
+
refs = 'HEAD~ HEAD' if options[:last_commit]
|
24
|
+
|
25
|
+
`git diff --no-ext-diff -U0 #{flags} #{refs} -- #{file_path}`.
|
26
|
+
scan(DIFF_HUNK_REGEX) do |start_line, lines_added|
|
27
|
+
lines_added = (lines_added || 1).to_i # When blank, one line was added
|
28
|
+
cur_line = start_line.to_i
|
29
|
+
|
30
|
+
lines_added.times do
|
31
|
+
lines.add cur_line
|
32
|
+
cur_line += 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
lines
|
37
|
+
end
|
38
|
+
|
39
|
+
# Extract the set of modified lines from a given file.
|
40
|
+
#
|
41
|
+
# @param file_path [String]
|
42
|
+
# @param options [Hash]
|
43
|
+
# @return [Set] line numbers that have been modified in file
|
44
|
+
def extract_modified_lines_last_commit(file_path)
|
45
|
+
extract_modified_lines(file_path, last_commit: true)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the names of all files that have been modified from compared to
|
49
|
+
# HEAD.
|
50
|
+
#
|
51
|
+
# @param options [Hash]
|
52
|
+
# @return [Array<String>] list of absolute file paths
|
53
|
+
def modified_files(options)
|
54
|
+
flags = '--cached' if options[:staged]
|
55
|
+
refs = 'HEAD~ HEAD' if options[:last_commit]
|
56
|
+
|
57
|
+
`git diff --name-only -z --diff-filter=ACM --ignore-submodules=all #{flags} #{refs}`.
|
58
|
+
split("\0").
|
59
|
+
map { |relative_file| File.expand_path(relative_file) }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the names of all files that were modified in the last commit.
|
63
|
+
#
|
64
|
+
# @return [Array<String>] lsit of absolute file paths
|
65
|
+
def modified_files_last_commit
|
66
|
+
modified_files(last_commit: true)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the names of all files that are tracked by git.
|
70
|
+
#
|
71
|
+
# @return [Array<String>] list of absolute file paths
|
72
|
+
def all_files
|
73
|
+
`git ls-files`.
|
74
|
+
split(/\n/).
|
75
|
+
map { |relative_file| File.expand_path(relative_file) }
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns whether the current git branch is empty (has no commits).
|
79
|
+
# @return [true,false]
|
80
|
+
def initial_commit?
|
81
|
+
!Overcommit::Utils.execute(%w[git rev-parse HEAD]).success?
|
82
|
+
end
|
83
|
+
|
84
|
+
# Store any relevant files that are present when repo is in the middle of a
|
85
|
+
# merge.
|
86
|
+
#
|
87
|
+
# Restored via [#restore_merge_state].
|
88
|
+
def store_merge_state
|
89
|
+
merge_head = `git rev-parse MERGE_HEAD 2> /dev/null`.chomp
|
90
|
+
|
91
|
+
# Store the merge state if we're in the middle of resolving a merge
|
92
|
+
# conflict. This is necessary since stashing removes the merge state.
|
93
|
+
if merge_head != 'MERGE_HEAD'
|
94
|
+
@merge_head = merge_head
|
95
|
+
end
|
96
|
+
|
97
|
+
merge_msg_file = File.expand_path('MERGE_MSG', Overcommit::Utils.git_dir)
|
98
|
+
@merge_msg = File.open(merge_msg_file).read if File.exist?(merge_msg_file)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Store any relevant files that are present when repo is in the middle of a
|
102
|
+
# cherry-pick.
|
103
|
+
#
|
104
|
+
# Restored via [#restore_cherry_pick_state].
|
105
|
+
def store_cherry_pick_state
|
106
|
+
cherry_head = `git rev-parse CHERRY_PICK_HEAD 2> /dev/null`.chomp
|
107
|
+
|
108
|
+
# Store the merge state if we're in the middle of resolving a merge
|
109
|
+
# conflict. This is necessary since stashing removes the merge state.
|
110
|
+
if cherry_head != 'CHERRY_PICK_HEAD'
|
111
|
+
@cherry_head = cherry_head
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Restore any relevant files that were present when repo was in the middle
|
116
|
+
# of a merge.
|
117
|
+
def restore_merge_state
|
118
|
+
if @merge_head
|
119
|
+
FileUtils.touch(File.expand_path('MERGE_MODE', Overcommit::Utils.git_dir))
|
120
|
+
|
121
|
+
File.open(File.expand_path('MERGE_HEAD', Overcommit::Utils.git_dir), 'w') do |f|
|
122
|
+
f.write("#{@merge_head}\n")
|
123
|
+
end
|
124
|
+
@merge_head = nil
|
125
|
+
end
|
126
|
+
|
127
|
+
if @merge_msg
|
128
|
+
File.open(File.expand_path('MERGE_MSG', Overcommit::Utils.git_dir), 'w') do |f|
|
129
|
+
f.write("#{@merge_msg}\n")
|
130
|
+
end
|
131
|
+
@merge_msg = nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Restore any relevant files that were present when repo was in the middle
|
136
|
+
# of a cherry-pick.
|
137
|
+
def restore_cherry_pick_state
|
138
|
+
if @cherry_head
|
139
|
+
File.open(File.expand_path('CHERRY_PICK_HEAD',
|
140
|
+
Overcommit::Utils.git_dir), 'w') do |f|
|
141
|
+
f.write("#{@cherry_head}\n")
|
142
|
+
end
|
143
|
+
@cherry_head = nil
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|