overcommit 0.23.0 → 0.24.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 +4 -4
- data/bin/overcommit +1 -1
- data/config/default.yml +154 -18
- data/config/starter.yml +3 -3
- data/lib/overcommit.rb +2 -1
- data/lib/overcommit/cli.rb +11 -8
- data/lib/overcommit/configuration.rb +18 -4
- data/lib/overcommit/configuration_loader.rb +45 -28
- data/lib/overcommit/configuration_validator.rb +33 -1
- data/lib/overcommit/constants.rb +5 -3
- data/lib/overcommit/exceptions.rb +3 -0
- data/lib/overcommit/git_repo.rb +116 -0
- data/lib/overcommit/git_version.rb +15 -0
- data/lib/overcommit/hook/base.rb +42 -5
- data/lib/overcommit/hook/commit_msg/capitalized_subject.rb +13 -0
- data/lib/overcommit/hook/commit_msg/spell_check.rb +41 -0
- data/lib/overcommit/hook/post_checkout/submodule_status.rb +30 -0
- data/lib/overcommit/hook/post_commit/submodule_status.rb +30 -0
- data/lib/overcommit/hook/post_merge/submodule_status.rb +30 -0
- data/lib/overcommit/hook/post_rewrite/submodule_status.rb +30 -0
- data/lib/overcommit/hook/pre_commit/base.rb +2 -2
- data/lib/overcommit/hook/pre_commit/bundle_check.rb +1 -1
- data/lib/overcommit/hook/pre_commit/case_conflicts.rb +20 -0
- data/lib/overcommit/hook/pre_commit/coffee_lint.rb +29 -2
- data/lib/overcommit/hook/pre_commit/css_lint.rb +1 -8
- data/lib/overcommit/hook/pre_commit/go_lint.rb +8 -2
- data/lib/overcommit/hook/pre_commit/go_vet.rb +20 -0
- data/lib/overcommit/hook/pre_commit/html_tidy.rb +1 -10
- data/lib/overcommit/hook/pre_commit/image_optim.rb +11 -28
- data/lib/overcommit/hook/pre_commit/js_lint.rb +18 -0
- data/lib/overcommit/hook/pre_commit/jsl.rb +24 -0
- data/lib/overcommit/hook/pre_commit/json_syntax.rb +4 -7
- data/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +1 -1
- data/lib/overcommit/hook/pre_commit/ruby_lint.rb +19 -0
- data/lib/overcommit/hook/pre_commit/scss_lint.rb +8 -1
- data/lib/overcommit/hook/pre_commit/w3c_css.rb +4 -18
- data/lib/overcommit/hook/pre_commit/w3c_html.rb +4 -18
- data/lib/overcommit/hook/pre_commit/xml_syntax.rb +19 -0
- data/lib/overcommit/hook/pre_commit/yaml_syntax.rb +4 -8
- data/lib/overcommit/hook/pre_push/base.rb +10 -0
- data/lib/overcommit/hook/pre_push/protected_branches.rb +27 -0
- data/lib/overcommit/hook/pre_push/r_spec.rb +12 -0
- data/lib/overcommit/hook/pre_rebase/base.rb +11 -0
- data/lib/overcommit/hook_context.rb +2 -2
- data/lib/overcommit/hook_context/base.rb +5 -7
- data/lib/overcommit/hook_context/pre_commit.rb +66 -16
- data/lib/overcommit/hook_context/pre_push.rb +44 -0
- data/lib/overcommit/hook_context/pre_rebase.rb +36 -0
- data/lib/overcommit/hook_runner.rb +27 -7
- data/lib/overcommit/installer.rb +46 -7
- data/lib/overcommit/message_processor.rb +3 -0
- data/lib/overcommit/printer.rb +8 -12
- data/lib/overcommit/subprocess.rb +11 -0
- data/lib/overcommit/utils.rb +28 -6
- data/lib/overcommit/version.rb +1 -1
- data/template-dir/hooks/commit-msg +2 -2
- data/template-dir/hooks/overcommit-hook +2 -2
- data/template-dir/hooks/post-checkout +2 -2
- data/template-dir/hooks/post-commit +2 -2
- data/template-dir/hooks/post-merge +2 -2
- data/template-dir/hooks/post-rewrite +2 -2
- data/template-dir/hooks/pre-commit +2 -2
- data/template-dir/hooks/pre-push +81 -0
- data/template-dir/hooks/pre-rebase +81 -0
- metadata +33 -13
- data/lib/overcommit/hook/pre_commit/pry_binding.rb +0 -14
@@ -2,40 +2,23 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Checks for images that can be optimized with `image_optim`.
|
3
3
|
class ImageOptim < Base
|
4
4
|
def run
|
5
|
-
|
6
|
-
|
7
|
-
rescue LoadError
|
8
|
-
return :fail, 'image_optim not installed -- run `gem install image_optim`'
|
9
|
-
end
|
5
|
+
result = execute(command + applicable_files)
|
6
|
+
return [:fail, result.stdout + result.stderr] unless result.success?
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
optimize_images(applicable_files)
|
14
|
-
rescue ::ImageOptim::BinResolver::BinNotFound => e
|
15
|
-
return :fail, "#{e.message}. The image_optim gem is dependendent on this binary."
|
16
|
-
end
|
8
|
+
optimized_files = extract_optimized_files(result.stdout)
|
9
|
+
return :pass if optimized_files.empty?
|
17
10
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
"\n\nOptimize them by running:\n" \
|
22
|
-
" image_optim --skip-missing-workers #{optimized_images.join(' ')}"
|
23
|
-
end
|
24
|
-
|
25
|
-
:pass
|
11
|
+
output = "The following images are optimizable:\n#{optimized_files.join("\n")}"
|
12
|
+
output += "\n\nOptimize them by running `#{command.join(' ')} #{optimized_files.join(' ')}`"
|
13
|
+
[:fail, output]
|
26
14
|
end
|
27
15
|
|
28
16
|
private
|
29
17
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
image_optim.optimize_images(image_paths) do |path, optimized|
|
35
|
-
path if optimized
|
36
|
-
end
|
37
|
-
|
38
|
-
optimized_images.compact
|
18
|
+
def extract_optimized_files(output)
|
19
|
+
output.split("\n").
|
20
|
+
select { |line| line =~ /^\d+/ }.
|
21
|
+
map { |line| line.split(/\s+/).last }
|
39
22
|
end
|
40
23
|
end
|
41
24
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Overcommit::Hook::PreCommit
|
2
|
+
# Runs `jslint` against any modified JavaScript files.
|
3
|
+
class JsLint < Base
|
4
|
+
MESSAGE_REGEX = /(?<file>[^:]+):(?<line>\d+)/
|
5
|
+
|
6
|
+
def run
|
7
|
+
result = execute(command + applicable_files)
|
8
|
+
return :pass if result.success?
|
9
|
+
|
10
|
+
# example message:
|
11
|
+
# path/to/file.js:1:1: Error message
|
12
|
+
extract_messages(
|
13
|
+
result.stdout.split("\n").grep(MESSAGE_REGEX),
|
14
|
+
MESSAGE_REGEX
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Overcommit::Hook::PreCommit
|
2
|
+
# Runs `jsl` against any modified JavaScript files.
|
3
|
+
class Jsl < Base
|
4
|
+
MESSAGE_REGEX = /(?<file>.+)\((?<line>\d+)\):(?<type>[^:]+)/
|
5
|
+
|
6
|
+
MESSAGE_TYPE_CATEGORIZER = lambda do |type|
|
7
|
+
type =~ /warning/ ? :warning : :error
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
file_flags = applicable_files.map { |file| ['-process', file] }
|
12
|
+
result = execute(command + file_flags.flatten)
|
13
|
+
return :pass if result.success?
|
14
|
+
|
15
|
+
# example message:
|
16
|
+
# path/to/file.js(1): lint warning: Error message
|
17
|
+
extract_messages(
|
18
|
+
result.stdout.split("\n").grep(MESSAGE_REGEX),
|
19
|
+
MESSAGE_REGEX,
|
20
|
+
MESSAGE_TYPE_CATEGORIZER
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,22 +1,19 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
1
|
module Overcommit::Hook::PreCommit
|
4
2
|
# Checks the syntax of any modified JSON files.
|
5
3
|
class JsonSyntax < Base
|
6
4
|
def run
|
7
|
-
|
5
|
+
messages = []
|
8
6
|
|
9
7
|
applicable_files.each do |file|
|
10
8
|
begin
|
11
9
|
JSON.parse(IO.read(file))
|
12
10
|
rescue JSON::ParserError => e
|
13
|
-
|
11
|
+
error = "#{e.message} parsing #{file}"
|
12
|
+
messages << Overcommit::Hook::Message.new(:error, file, nil, error)
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
[:fail, output]
|
16
|
+
messages
|
20
17
|
end
|
21
18
|
end
|
22
19
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Overcommit::Hook::PreCommit
|
2
|
+
# Runs `ruby-lint` against any modified Ruby files.
|
3
|
+
class RubyLint < Base
|
4
|
+
MESSAGE_TYPE_CATEGORIZER = lambda do |type|
|
5
|
+
type.include?('W') ? :warning : :error
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
result = execute(command + applicable_files)
|
10
|
+
return :pass if result.success?
|
11
|
+
|
12
|
+
extract_messages(
|
13
|
+
result.stdout.split("\n"),
|
14
|
+
/^(?<file>[^:]+):(?<type>[^:]+):(?<line>\d+)/,
|
15
|
+
MESSAGE_TYPE_CATEGORIZER
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -7,7 +7,14 @@ module Overcommit::Hook::PreCommit
|
|
7
7
|
|
8
8
|
def run
|
9
9
|
result = execute(command + applicable_files)
|
10
|
-
|
10
|
+
|
11
|
+
# Status code 81 indicates the applicable files were all filtered by
|
12
|
+
# exclusions defined by the configuration. In this case, we're happy to
|
13
|
+
# return success since there were technically no lints.
|
14
|
+
return :pass if [0, 81].include?(result.status)
|
15
|
+
|
16
|
+
# Any status that isn't indicating lint warnings or errors indicates failure
|
17
|
+
return :fail, result.stdout unless [1, 2].include?(result.status)
|
11
18
|
|
12
19
|
extract_messages(
|
13
20
|
result.stdout.split("\n"),
|
@@ -2,24 +2,10 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `w3c_validators` against any modified CSS files.
|
3
3
|
class W3cCss < Base
|
4
4
|
def run
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
result_messages =
|
12
|
-
begin
|
13
|
-
collect_messages
|
14
|
-
rescue W3CValidators::ValidatorUnavailable => e
|
15
|
-
return :fail, e.message
|
16
|
-
rescue W3CValidators::ParsingError => e
|
17
|
-
return :fail, e.message
|
18
|
-
end
|
19
|
-
|
20
|
-
return :pass if result_messages.empty?
|
21
|
-
|
22
|
-
result_messages
|
5
|
+
collect_messages
|
6
|
+
rescue W3CValidators::ParsingError,
|
7
|
+
W3CValidators::ValidatorUnavailable => e
|
8
|
+
[:fail, e.message]
|
23
9
|
end
|
24
10
|
|
25
11
|
private
|
@@ -2,24 +2,10 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `w3c_validators` against any modified HTML files.
|
3
3
|
class W3cHtml < Base
|
4
4
|
def run
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
result_messages =
|
12
|
-
begin
|
13
|
-
collect_messages
|
14
|
-
rescue W3CValidators::ValidatorUnavailable => e
|
15
|
-
return :fail, e.message
|
16
|
-
rescue W3CValidators::ParsingError => e
|
17
|
-
return :fail, e.message
|
18
|
-
end
|
19
|
-
|
20
|
-
return :pass if result_messages.empty?
|
21
|
-
|
22
|
-
result_messages
|
5
|
+
collect_messages
|
6
|
+
rescue W3CValidators::ParsingError,
|
7
|
+
W3CValidators::ValidatorUnavailable => e
|
8
|
+
[:fail, e.message]
|
23
9
|
end
|
24
10
|
|
25
11
|
private
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Overcommit::Hook::PreCommit
|
2
|
+
# Checks the syntax of any modified XML files.
|
3
|
+
class XmlSyntax < Base
|
4
|
+
def run
|
5
|
+
messages = []
|
6
|
+
|
7
|
+
applicable_files.each do |file|
|
8
|
+
begin
|
9
|
+
REXML::Document.new(IO.read(file))
|
10
|
+
rescue REXML::ParseException => e
|
11
|
+
error = "Error parsing #{file}: #{e.message}"
|
12
|
+
messages << Overcommit::Hook::Message.new(:error, file, nil, error)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
messages
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,22 +1,18 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
1
|
module Overcommit::Hook::PreCommit
|
4
2
|
# Checks the syntax of any modified YAML files.
|
5
3
|
class YamlSyntax < Base
|
6
4
|
def run
|
7
|
-
|
5
|
+
messages = []
|
8
6
|
|
9
7
|
applicable_files.each do |file|
|
10
8
|
begin
|
11
9
|
YAML.load_file(file)
|
12
|
-
rescue ArgumentError => e
|
13
|
-
|
10
|
+
rescue ArgumentError, Psych::SyntaxError => e
|
11
|
+
messages << Overcommit::Hook::Message.new(:error, file, nil, e.message)
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
[:fail, output]
|
15
|
+
messages
|
20
16
|
end
|
21
17
|
end
|
22
18
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Overcommit::Hook::PrePush
|
2
|
+
# Prevents destructive updates to specified branches.
|
3
|
+
class ProtectedBranches < Base
|
4
|
+
def run
|
5
|
+
return :pass unless illegal_pushes.any?
|
6
|
+
|
7
|
+
messages = illegal_pushes.map do |pushed_ref|
|
8
|
+
"Deleting or force-pushing to #{pushed_ref.remote_ref} is not allowed."
|
9
|
+
end
|
10
|
+
|
11
|
+
[:fail, messages.join("\n")]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def branches
|
17
|
+
@branches ||= config['branches']
|
18
|
+
end
|
19
|
+
|
20
|
+
def illegal_pushes
|
21
|
+
@illegal_pushes ||= pushed_refs.select do |pushed_ref|
|
22
|
+
(pushed_ref.deleted? || pushed_ref.forced?) &&
|
23
|
+
branches.any? { |branch| pushed_ref.remote_ref == "refs/heads/#{branch}" }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Overcommit::Hook::PreRebase
|
4
|
+
# Functionality common to all pre-rebase hooks.
|
5
|
+
class Base < Overcommit::Hook::Base
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@context,
|
9
|
+
:upstream_branch, :rebased_branch, :fast_forward?, :rebased_commits
|
10
|
+
end
|
11
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# Utility module which manages the creation of {HookContext}s.
|
2
2
|
module Overcommit::HookContext
|
3
|
-
def self.create(hook_type, config, args)
|
3
|
+
def self.create(hook_type, config, args, input)
|
4
4
|
hook_type_class = Overcommit::Utils.camel_case(hook_type)
|
5
5
|
underscored_hook_type = Overcommit::Utils.snake_case(hook_type)
|
6
6
|
|
7
7
|
require "overcommit/hook_context/#{underscored_hook_type}"
|
8
8
|
|
9
|
-
Overcommit::HookContext.const_get(hook_type_class).new(config, args)
|
9
|
+
Overcommit::HookContext.const_get(hook_type_class).new(config, args, input)
|
10
10
|
rescue LoadError, NameError => error
|
11
11
|
# Could happen when a symlink was created for a hook type Overcommit does
|
12
12
|
# not yet support.
|
@@ -13,9 +13,10 @@ module Overcommit::HookContext
|
|
13
13
|
class Base
|
14
14
|
# @param config [Overcommit::Configuration]
|
15
15
|
# @param args [Array<String>]
|
16
|
-
def initialize(config, args)
|
16
|
+
def initialize(config, args, input)
|
17
17
|
@config = config
|
18
18
|
@args = args
|
19
|
+
@input = input
|
19
20
|
end
|
20
21
|
|
21
22
|
# Returns the camel-cased type of this hook (e.g. PreCommit)
|
@@ -58,12 +59,9 @@ module Overcommit::HookContext
|
|
58
59
|
[]
|
59
60
|
end
|
60
61
|
|
61
|
-
# Returns
|
62
|
-
|
63
|
-
|
64
|
-
# there is a concept of files changing for the type of hook being run.
|
65
|
-
def modified_lines(_file)
|
66
|
-
Set.new
|
62
|
+
# Returns an array of lines passed to the hook via STDIN.
|
63
|
+
def input_lines
|
64
|
+
@input_lines ||= @input.read.split("\n")
|
67
65
|
end
|
68
66
|
end
|
69
67
|
end
|
@@ -7,7 +7,30 @@ module Overcommit::HookContext
|
|
7
7
|
# This includes staged files, which lines of those files have been modified,
|
8
8
|
# etc. It is also responsible for saving/restoring the state of the repo so
|
9
9
|
# hooks only inspect staged changes.
|
10
|
-
class PreCommit < Base
|
10
|
+
class PreCommit < Base # rubocop:disable ClassLength
|
11
|
+
# Returns whether this hook run was triggered by `git commit --amend`
|
12
|
+
def amendment?
|
13
|
+
return @amendment unless @amendment.nil?
|
14
|
+
|
15
|
+
cmd = Overcommit::Utils.parent_command
|
16
|
+
amend_pattern = 'commit(\s.*)?\s--amend(\s|$)'
|
17
|
+
|
18
|
+
return @amendment if
|
19
|
+
# True if the command is a commit with the --amend flag
|
20
|
+
@amendment = !(/\s#{amend_pattern}/ =~ cmd).nil?
|
21
|
+
|
22
|
+
# Check for git aliases that call `commit --amend`
|
23
|
+
`git config --get-regexp '^alias\\.' '#{amend_pattern}'`.
|
24
|
+
scan(/alias\.([-\w]+)/). # Extract the alias
|
25
|
+
each do |match|
|
26
|
+
return @amendment if
|
27
|
+
# True if the command uses a git alias for `commit --amend`
|
28
|
+
@amendment = !(/git\s+#{match[0]}/ =~ cmd).nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
@amendment
|
32
|
+
end
|
33
|
+
|
11
34
|
# Stash unstaged contents of files so hooks don't see changes that aren't
|
12
35
|
# about to be committed.
|
13
36
|
def setup_environment
|
@@ -18,9 +41,9 @@ module Overcommit::HookContext
|
|
18
41
|
if !initial_commit? && any_changes?
|
19
42
|
@stash_attempted = true
|
20
43
|
|
44
|
+
stash_message = "Overcommit: Stash of repo state before hook run at #{Time.now}"
|
21
45
|
result = Overcommit::Utils.execute(
|
22
|
-
%w[git stash save --keep-index --quiet] +
|
23
|
-
["Overcommit: Stash of repo state before hook run at #{Time.now}"]
|
46
|
+
%w[git stash save --keep-index --quiet] + [stash_message]
|
24
47
|
)
|
25
48
|
|
26
49
|
unless result.success?
|
@@ -31,7 +54,7 @@ module Overcommit::HookContext
|
|
31
54
|
"\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
|
32
55
|
end
|
33
56
|
|
34
|
-
@changes_stashed =
|
57
|
+
@changes_stashed = `git stash list -1`.include?(stash_message)
|
35
58
|
end
|
36
59
|
|
37
60
|
# While running the hooks make it appear as if nothing changed
|
@@ -64,34 +87,58 @@ module Overcommit::HookContext
|
|
64
87
|
# Get a list of added, copied, or modified files that have been staged.
|
65
88
|
# Renames and deletions are ignored, since there should be nothing to check.
|
66
89
|
def modified_files
|
67
|
-
@modified_files
|
68
|
-
|
90
|
+
unless @modified_files
|
91
|
+
@modified_files = Overcommit::GitRepo.modified_files(staged: true)
|
69
92
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
93
|
+
# Include files modified in last commit if amending
|
94
|
+
if amendment?
|
95
|
+
subcmd = 'show --format=%n'
|
96
|
+
@modified_files += Overcommit::GitRepo.modified_files(subcmd: subcmd)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
@modified_files
|
75
100
|
end
|
76
101
|
|
77
102
|
# Returns the set of line numbers corresponding to the lines that were
|
78
103
|
# changed in a specified file.
|
79
104
|
def modified_lines_in_file(file)
|
80
105
|
@modified_lines ||= {}
|
81
|
-
@modified_lines[file]
|
82
|
-
|
106
|
+
unless @modified_lines[file]
|
107
|
+
@modified_lines[file] =
|
108
|
+
Overcommit::GitRepo.extract_modified_lines(file, staged: true)
|
109
|
+
|
110
|
+
# Include lines modified in last commit if amending
|
111
|
+
if amendment?
|
112
|
+
subcmd = 'show --format=%n'
|
113
|
+
@modified_lines[file] +=
|
114
|
+
Overcommit::GitRepo.extract_modified_lines(file, subcmd: subcmd)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
@modified_lines[file]
|
83
118
|
end
|
84
119
|
|
85
120
|
private
|
86
121
|
|
87
122
|
# Clears the working tree so that the stash can be applied.
|
88
123
|
def clear_working_tree
|
124
|
+
removed_submodules = Overcommit::GitRepo.staged_submodule_removals
|
125
|
+
|
89
126
|
result = Overcommit::Utils.execute(%w[git reset --hard])
|
90
127
|
unless result.success?
|
91
128
|
raise Overcommit::Exceptions::HookCleanupFailed,
|
92
129
|
"Unable to cleanup working tree after #{hook_script_name} hooks run:" \
|
93
130
|
"\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
|
94
131
|
end
|
132
|
+
|
133
|
+
# Hard-resetting a staged submodule removal results in the index being
|
134
|
+
# reset but the submodule being restored as an empty directory. This empty
|
135
|
+
# directory prevents us from stashing on a subsequent run if a hook fails.
|
136
|
+
#
|
137
|
+
# Work around this by removing these empty submodule directories as there
|
138
|
+
# doesn't appear any reason to keep them around.
|
139
|
+
removed_submodules.each do |submodule|
|
140
|
+
FileUtils.rmdir(submodule.path)
|
141
|
+
end
|
95
142
|
end
|
96
143
|
|
97
144
|
# Applies the stash to the working tree to restore the user's state.
|
@@ -128,8 +175,12 @@ module Overcommit::HookContext
|
|
128
175
|
def store_modified_times
|
129
176
|
@modified_times = {}
|
130
177
|
|
131
|
-
|
178
|
+
staged_files = modified_files
|
179
|
+
unstaged_files = Overcommit::GitRepo.modified_files(staged: false)
|
180
|
+
|
181
|
+
(staged_files + unstaged_files).each do |file|
|
132
182
|
next if Overcommit::Utils.broken_symlink?(file)
|
183
|
+
next unless File.exist?(file) # Ignore renamed files (old file no longer exists)
|
133
184
|
@modified_times[file] = File.mtime(file)
|
134
185
|
end
|
135
186
|
end
|
@@ -137,10 +188,9 @@ module Overcommit::HookContext
|
|
137
188
|
# Restores the file modification times for all modified files to make it
|
138
189
|
# appear like they never changed.
|
139
190
|
def restore_modified_times
|
140
|
-
|
191
|
+
@modified_times.each do |file, time|
|
141
192
|
next if Overcommit::Utils.broken_symlink?(file)
|
142
193
|
next unless File.exist?(file)
|
143
|
-
time = @modified_times[file]
|
144
194
|
File.utime(time, time, file)
|
145
195
|
end
|
146
196
|
end
|