jawshooah-overcommit 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|