overcommit-jeygeethanmedia 0.53.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/overcommit +50 -0
- data/config/default.yml +1356 -0
- data/config/starter.yml +33 -0
- data/lib/overcommit.rb +26 -0
- data/lib/overcommit/cli.rb +223 -0
- data/lib/overcommit/command_splitter.rb +146 -0
- data/lib/overcommit/configuration.rb +350 -0
- data/lib/overcommit/configuration_loader.rb +96 -0
- data/lib/overcommit/configuration_validator.rb +186 -0
- data/lib/overcommit/constants.rb +12 -0
- data/lib/overcommit/exceptions.rb +52 -0
- data/lib/overcommit/git_config.rb +22 -0
- data/lib/overcommit/git_repo.rb +286 -0
- data/lib/overcommit/git_version.rb +17 -0
- data/lib/overcommit/hook/base.rb +294 -0
- data/lib/overcommit/hook/commit_msg/base.rb +14 -0
- data/lib/overcommit/hook/commit_msg/capitalized_subject.rb +25 -0
- data/lib/overcommit/hook/commit_msg/empty_message.rb +12 -0
- data/lib/overcommit/hook/commit_msg/gerrit_change_id.rb +22 -0
- data/lib/overcommit/hook/commit_msg/hard_tabs.rb +17 -0
- data/lib/overcommit/hook/commit_msg/message_format.rb +31 -0
- data/lib/overcommit/hook/commit_msg/russian_novel.rb +16 -0
- data/lib/overcommit/hook/commit_msg/single_line_subject.rb +16 -0
- data/lib/overcommit/hook/commit_msg/spell_check.rb +45 -0
- data/lib/overcommit/hook/commit_msg/text_width.rb +56 -0
- data/lib/overcommit/hook/commit_msg/trailing_period.rb +16 -0
- data/lib/overcommit/hook/post_checkout/base.rb +22 -0
- data/lib/overcommit/hook/post_checkout/bower_install.rb +13 -0
- data/lib/overcommit/hook/post_checkout/bundle_install.rb +13 -0
- data/lib/overcommit/hook/post_checkout/composer_install.rb +13 -0
- data/lib/overcommit/hook/post_checkout/index_tags.rb +12 -0
- data/lib/overcommit/hook/post_checkout/npm_install.rb +13 -0
- data/lib/overcommit/hook/post_checkout/submodule_status.rb +12 -0
- data/lib/overcommit/hook/post_checkout/yarn_install.rb +13 -0
- data/lib/overcommit/hook/post_commit/base.rb +12 -0
- data/lib/overcommit/hook/post_commit/bower_install.rb +13 -0
- data/lib/overcommit/hook/post_commit/bundle_install.rb +13 -0
- data/lib/overcommit/hook/post_commit/commitplease.rb +16 -0
- data/lib/overcommit/hook/post_commit/composer_install.rb +13 -0
- data/lib/overcommit/hook/post_commit/git_guilt.rb +43 -0
- data/lib/overcommit/hook/post_commit/index_tags.rb +12 -0
- data/lib/overcommit/hook/post_commit/npm_install.rb +13 -0
- data/lib/overcommit/hook/post_commit/submodule_status.rb +12 -0
- data/lib/overcommit/hook/post_commit/yarn_install.rb +13 -0
- data/lib/overcommit/hook/post_merge/base.rb +12 -0
- data/lib/overcommit/hook/post_merge/bower_install.rb +13 -0
- data/lib/overcommit/hook/post_merge/bundle_install.rb +13 -0
- data/lib/overcommit/hook/post_merge/composer_install.rb +13 -0
- data/lib/overcommit/hook/post_merge/index_tags.rb +12 -0
- data/lib/overcommit/hook/post_merge/npm_install.rb +13 -0
- data/lib/overcommit/hook/post_merge/submodule_status.rb +12 -0
- data/lib/overcommit/hook/post_merge/yarn_install.rb +13 -0
- data/lib/overcommit/hook/post_rewrite/base.rb +12 -0
- data/lib/overcommit/hook/post_rewrite/bower_install.rb +13 -0
- data/lib/overcommit/hook/post_rewrite/bundle_install.rb +13 -0
- data/lib/overcommit/hook/post_rewrite/composer_install.rb +13 -0
- data/lib/overcommit/hook/post_rewrite/index_tags.rb +19 -0
- data/lib/overcommit/hook/post_rewrite/npm_install.rb +13 -0
- data/lib/overcommit/hook/post_rewrite/submodule_status.rb +12 -0
- data/lib/overcommit/hook/post_rewrite/yarn_install.rb +13 -0
- data/lib/overcommit/hook/pre_commit/author_email.rb +26 -0
- data/lib/overcommit/hook/pre_commit/author_name.rb +25 -0
- data/lib/overcommit/hook/pre_commit/base.rb +19 -0
- data/lib/overcommit/hook/pre_commit/berksfile_check.rb +24 -0
- data/lib/overcommit/hook/pre_commit/broken_symlinks.rb +17 -0
- data/lib/overcommit/hook/pre_commit/bundle_audit.rb +24 -0
- data/lib/overcommit/hook/pre_commit/bundle_check.rb +32 -0
- data/lib/overcommit/hook/pre_commit/bundle_outdated.rb +25 -0
- data/lib/overcommit/hook/pre_commit/case_conflicts.rb +27 -0
- data/lib/overcommit/hook/pre_commit/chamber_compare.rb +43 -0
- data/lib/overcommit/hook/pre_commit/chamber_security.rb +15 -0
- data/lib/overcommit/hook/pre_commit/chamber_verification.rb +36 -0
- data/lib/overcommit/hook/pre_commit/code_spell_check.rb +36 -0
- data/lib/overcommit/hook/pre_commit/coffee_lint.rb +35 -0
- data/lib/overcommit/hook/pre_commit/cook_style.rb +35 -0
- data/lib/overcommit/hook/pre_commit/credo.rb +27 -0
- data/lib/overcommit/hook/pre_commit/css_lint.rb +26 -0
- data/lib/overcommit/hook/pre_commit/dogma.rb +33 -0
- data/lib/overcommit/hook/pre_commit/es_lint.rb +38 -0
- data/lib/overcommit/hook/pre_commit/execute_permissions.rb +76 -0
- data/lib/overcommit/hook/pre_commit/fasterer.rb +25 -0
- data/lib/overcommit/hook/pre_commit/file_size.rb +47 -0
- data/lib/overcommit/hook/pre_commit/fix_me.rb +17 -0
- data/lib/overcommit/hook/pre_commit/flay.rb +38 -0
- data/lib/overcommit/hook/pre_commit/foodcritic.rb +149 -0
- data/lib/overcommit/hook/pre_commit/forbidden_branches.rb +26 -0
- data/lib/overcommit/hook/pre_commit/ginkgo_focus.rb +23 -0
- data/lib/overcommit/hook/pre_commit/go_fmt.rb +17 -0
- data/lib/overcommit/hook/pre_commit/go_lint.rb +29 -0
- data/lib/overcommit/hook/pre_commit/go_vet.rb +24 -0
- data/lib/overcommit/hook/pre_commit/golangci_lint.rb +21 -0
- data/lib/overcommit/hook/pre_commit/hadolint.rb +27 -0
- data/lib/overcommit/hook/pre_commit/haml_lint.rb +23 -0
- data/lib/overcommit/hook/pre_commit/hard_tabs.rb +15 -0
- data/lib/overcommit/hook/pre_commit/hlint.rb +34 -0
- data/lib/overcommit/hook/pre_commit/html_hint.rb +23 -0
- data/lib/overcommit/hook/pre_commit/html_tidy.rb +30 -0
- data/lib/overcommit/hook/pre_commit/image_optim.rb +28 -0
- data/lib/overcommit/hook/pre_commit/java_checkstyle.rb +27 -0
- data/lib/overcommit/hook/pre_commit/js_hint.rb +23 -0
- data/lib/overcommit/hook/pre_commit/js_lint.rb +22 -0
- data/lib/overcommit/hook/pre_commit/jscs.rb +27 -0
- data/lib/overcommit/hook/pre_commit/jsl.rb +28 -0
- data/lib/overcommit/hook/pre_commit/json_syntax.rb +21 -0
- data/lib/overcommit/hook/pre_commit/kt_lint.rb +19 -0
- data/lib/overcommit/hook/pre_commit/license_finder.rb +14 -0
- data/lib/overcommit/hook/pre_commit/license_header.rb +48 -0
- data/lib/overcommit/hook/pre_commit/line_endings.rb +77 -0
- data/lib/overcommit/hook/pre_commit/local_paths_in_gemfile.rb +16 -0
- data/lib/overcommit/hook/pre_commit/mdl.rb +29 -0
- data/lib/overcommit/hook/pre_commit/merge_conflicts.rb +16 -0
- data/lib/overcommit/hook/pre_commit/nginx_test.rb +26 -0
- data/lib/overcommit/hook/pre_commit/pep257.rb +23 -0
- data/lib/overcommit/hook/pre_commit/pep8.rb +23 -0
- data/lib/overcommit/hook/pre_commit/php_cs.rb +43 -0
- data/lib/overcommit/hook/pre_commit/php_cs_fixer.rb +57 -0
- data/lib/overcommit/hook/pre_commit/php_lint.rb +44 -0
- data/lib/overcommit/hook/pre_commit/php_stan.rb +30 -0
- data/lib/overcommit/hook/pre_commit/pronto.rb +12 -0
- data/lib/overcommit/hook/pre_commit/puppet_lint.rb +26 -0
- data/lib/overcommit/hook/pre_commit/puppet_metadata_json_lint.rb +29 -0
- data/lib/overcommit/hook/pre_commit/pycodestyle.rb +23 -0
- data/lib/overcommit/hook/pre_commit/pydocstyle.rb +23 -0
- data/lib/overcommit/hook/pre_commit/pyflakes.rb +32 -0
- data/lib/overcommit/hook/pre_commit/pylint.rb +32 -0
- data/lib/overcommit/hook/pre_commit/python_flake8.rb +32 -0
- data/lib/overcommit/hook/pre_commit/rails_best_practices.rb +34 -0
- data/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +58 -0
- data/lib/overcommit/hook/pre_commit/rake_target.rb +12 -0
- data/lib/overcommit/hook/pre_commit/reek.rb +26 -0
- data/lib/overcommit/hook/pre_commit/rst_lint.rb +27 -0
- data/lib/overcommit/hook/pre_commit/rubo_cop.rb +35 -0
- data/lib/overcommit/hook/pre_commit/ruby_lint.rb +23 -0
- data/lib/overcommit/hook/pre_commit/ruby_syntax.rb +27 -0
- data/lib/overcommit/hook/pre_commit/scalariform.rb +22 -0
- data/lib/overcommit/hook/pre_commit/scalastyle.rb +31 -0
- data/lib/overcommit/hook/pre_commit/scss_lint.rb +43 -0
- data/lib/overcommit/hook/pre_commit/semi_standard.rb +23 -0
- data/lib/overcommit/hook/pre_commit/shell_check.rb +23 -0
- data/lib/overcommit/hook/pre_commit/slim_lint.rb +23 -0
- data/lib/overcommit/hook/pre_commit/sqlint.rb +26 -0
- data/lib/overcommit/hook/pre_commit/standard.rb +23 -0
- data/lib/overcommit/hook/pre_commit/stylelint.rb +23 -0
- data/lib/overcommit/hook/pre_commit/swift_lint.rb +19 -0
- data/lib/overcommit/hook/pre_commit/terraform_format.rb +19 -0
- data/lib/overcommit/hook/pre_commit/trailing_whitespace.rb +15 -0
- data/lib/overcommit/hook/pre_commit/travis_lint.rb +15 -0
- data/lib/overcommit/hook/pre_commit/ts_lint.rb +28 -0
- data/lib/overcommit/hook/pre_commit/vint.rb +22 -0
- data/lib/overcommit/hook/pre_commit/w3c_css.rb +67 -0
- data/lib/overcommit/hook/pre_commit/w3c_html.rb +64 -0
- data/lib/overcommit/hook/pre_commit/xml_lint.rb +24 -0
- data/lib/overcommit/hook/pre_commit/xml_syntax.rb +21 -0
- data/lib/overcommit/hook/pre_commit/yaml_lint.rb +18 -0
- data/lib/overcommit/hook/pre_commit/yaml_syntax.rb +20 -0
- data/lib/overcommit/hook/pre_commit/yard_coverage.rb +90 -0
- data/lib/overcommit/hook/pre_commit/yarn_check.rb +37 -0
- data/lib/overcommit/hook/pre_push/base.rb +33 -0
- data/lib/overcommit/hook/pre_push/brakeman.rb +15 -0
- data/lib/overcommit/hook/pre_push/cargo_test.rb +12 -0
- data/lib/overcommit/hook/pre_push/go_test.rb +14 -0
- data/lib/overcommit/hook/pre_push/golangci_lint.rb +16 -0
- data/lib/overcommit/hook/pre_push/minitest.rb +20 -0
- data/lib/overcommit/hook/pre_push/php_unit.rb +16 -0
- data/lib/overcommit/hook/pre_push/pronto.rb +12 -0
- data/lib/overcommit/hook/pre_push/protected_branches.rb +74 -0
- data/lib/overcommit/hook/pre_push/pytest.rb +16 -0
- data/lib/overcommit/hook/pre_push/python_nose.rb +16 -0
- data/lib/overcommit/hook/pre_push/r_spec.rb +16 -0
- data/lib/overcommit/hook/pre_push/rake_target.rb +12 -0
- data/lib/overcommit/hook/pre_push/test_unit.rb +16 -0
- data/lib/overcommit/hook/pre_rebase/base.rb +14 -0
- data/lib/overcommit/hook/pre_rebase/merged_commits.rb +31 -0
- data/lib/overcommit/hook/prepare_commit_msg/base.rb +25 -0
- data/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb +57 -0
- data/lib/overcommit/hook/shared/bower_install.rb +15 -0
- data/lib/overcommit/hook/shared/bundle_install.rb +15 -0
- data/lib/overcommit/hook/shared/composer_install.rb +15 -0
- data/lib/overcommit/hook/shared/index_tags.rb +14 -0
- data/lib/overcommit/hook/shared/npm_install.rb +15 -0
- data/lib/overcommit/hook/shared/pronto.rb +21 -0
- data/lib/overcommit/hook/shared/rake_target.rb +26 -0
- data/lib/overcommit/hook/shared/submodule_status.rb +32 -0
- data/lib/overcommit/hook/shared/yarn_install.rb +15 -0
- data/lib/overcommit/hook_context.rb +19 -0
- data/lib/overcommit/hook_context/base.rb +139 -0
- data/lib/overcommit/hook_context/commit_msg.rb +48 -0
- data/lib/overcommit/hook_context/post_checkout.rb +36 -0
- data/lib/overcommit/hook_context/post_commit.rb +33 -0
- data/lib/overcommit/hook_context/post_merge.rb +37 -0
- data/lib/overcommit/hook_context/post_rewrite.rb +49 -0
- data/lib/overcommit/hook_context/pre_commit.rb +212 -0
- data/lib/overcommit/hook_context/pre_push.rb +89 -0
- data/lib/overcommit/hook_context/pre_rebase.rb +38 -0
- data/lib/overcommit/hook_context/prepare_commit_msg.rb +34 -0
- data/lib/overcommit/hook_context/run_all.rb +48 -0
- data/lib/overcommit/hook_loader/base.rb +48 -0
- data/lib/overcommit/hook_loader/built_in_hook_loader.rb +14 -0
- data/lib/overcommit/hook_loader/plugin_hook_loader.rb +102 -0
- data/lib/overcommit/hook_runner.rb +219 -0
- data/lib/overcommit/hook_signer.rb +123 -0
- data/lib/overcommit/installer.rb +193 -0
- data/lib/overcommit/interrupt_handler.rb +91 -0
- data/lib/overcommit/logger.rb +92 -0
- data/lib/overcommit/message_processor.rb +148 -0
- data/lib/overcommit/os.rb +38 -0
- data/lib/overcommit/printer.rb +145 -0
- data/lib/overcommit/subprocess.rb +98 -0
- data/lib/overcommit/utils.rb +309 -0
- data/lib/overcommit/utils/file_utils.rb +71 -0
- data/lib/overcommit/utils/messages_utils.rb +77 -0
- data/lib/overcommit/version.rb +6 -0
- data/libexec/gerrit-change-id +174 -0
- data/libexec/index-tags +17 -0
- data/template-dir/hooks/commit-msg +116 -0
- data/template-dir/hooks/overcommit-hook +116 -0
- data/template-dir/hooks/post-checkout +116 -0
- data/template-dir/hooks/post-commit +116 -0
- data/template-dir/hooks/post-merge +116 -0
- data/template-dir/hooks/post-rewrite +116 -0
- data/template-dir/hooks/pre-commit +116 -0
- data/template-dir/hooks/pre-push +116 -0
- data/template-dir/hooks/pre-rebase +116 -0
- data/template-dir/hooks/prepare-commit-msg +116 -0
- metadata +303 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Overcommit::HookContext
|
4
|
+
# Contains helpers related to contextual information used by post-merge
|
5
|
+
# hooks.
|
6
|
+
class PostMerge < Base
|
7
|
+
attr_accessor :args
|
8
|
+
# Get a list of files that were added, copied, or modified in the merge
|
9
|
+
# commit. Renames and deletions are ignored, since there should be nothing
|
10
|
+
# to check.
|
11
|
+
def modified_files
|
12
|
+
staged = squash?
|
13
|
+
refs = 'HEAD^ HEAD' if merge_commit?
|
14
|
+
@modified_files ||= Overcommit::GitRepo.modified_files(staged: staged, refs: refs)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the set of line numbers corresponding to the lines that were
|
18
|
+
# changed in a specified file.
|
19
|
+
def modified_lines_in_file(file)
|
20
|
+
staged = squash?
|
21
|
+
refs = 'HEAD^ HEAD' if merge_commit?
|
22
|
+
@modified_lines ||= {}
|
23
|
+
@modified_lines[file] ||=
|
24
|
+
Overcommit::GitRepo.extract_modified_lines(file, staged: staged, refs: refs)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns whether this merge was made using --squash
|
28
|
+
def squash?
|
29
|
+
@args[0].to_i == 1
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns whether this merge was made without --squash
|
33
|
+
def merge_commit?
|
34
|
+
!squash?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Overcommit::HookContext
|
4
|
+
# Contains helpers for contextual information used by post-rewrite hooks.
|
5
|
+
class PostRewrite < Base
|
6
|
+
# Returns whether this post-rewrite was triggered by `git commit --amend`.
|
7
|
+
#
|
8
|
+
# @return [true,false]
|
9
|
+
def amend?
|
10
|
+
@args[0] == 'amend'
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns whether this post-rewrite was triggered by `git rebase`.
|
14
|
+
#
|
15
|
+
# @return [true,false]
|
16
|
+
def rebase?
|
17
|
+
@args[0] == 'rebase'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the list of commits rewritten by the action that triggered this
|
21
|
+
# hook run.
|
22
|
+
#
|
23
|
+
# @return [Array<RewrittenCommit>]
|
24
|
+
def rewritten_commits
|
25
|
+
@rewritten_commits ||= input_lines.map do |line|
|
26
|
+
RewrittenCommit.new(*line.split(' '))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get a list of files that have been added or modified as part of a
|
31
|
+
# rewritten commit. Renames and deletions are ignored, since there should be
|
32
|
+
# nothing to check.
|
33
|
+
def modified_files
|
34
|
+
@modified_files ||= begin
|
35
|
+
@modified_files = []
|
36
|
+
|
37
|
+
rewritten_commits.each do |rewritten_commit|
|
38
|
+
refs = "#{rewritten_commit.old_hash} #{rewritten_commit.new_hash}"
|
39
|
+
@modified_files |= Overcommit::GitRepo.modified_files(refs: refs)
|
40
|
+
end
|
41
|
+
|
42
|
+
filter_modified_files(@modified_files)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Struct encapsulating the old and new SHA1 hashes of a rewritten commit
|
47
|
+
RewrittenCommit = Struct.new(:old_hash, :new_hash)
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
module Overcommit::HookContext
|
7
|
+
# Contains helpers related to contextual information used by pre-commit hooks.
|
8
|
+
#
|
9
|
+
# This includes staged files, which lines of those files have been modified,
|
10
|
+
# etc. It is also responsible for saving/restoring the state of the repo so
|
11
|
+
# hooks only inspect staged changes.
|
12
|
+
class PreCommit < Base # rubocop:disable ClassLength
|
13
|
+
# Returns whether this hook run was triggered by `git commit --amend`
|
14
|
+
def amendment?
|
15
|
+
return @amendment unless @amendment.nil?
|
16
|
+
|
17
|
+
cmd = Overcommit::Utils.parent_command
|
18
|
+
return unless cmd
|
19
|
+
amend_pattern = 'commit(\s.*)?\s--amend(\s|$)'
|
20
|
+
|
21
|
+
# Since the ps command can return invalid byte sequences for commands
|
22
|
+
# containing unicode characters, we replace the offending characters,
|
23
|
+
# since the pattern we're looking for will consist of ASCII characters
|
24
|
+
unless cmd.valid_encoding?
|
25
|
+
cmd = Overcommit::Utils.parent_command.encode('UTF-16be', invalid: :replace, replace: '?').
|
26
|
+
encode('UTF-8')
|
27
|
+
end
|
28
|
+
|
29
|
+
return @amendment if
|
30
|
+
# True if the command is a commit with the --amend flag
|
31
|
+
@amendment = !(/\s#{amend_pattern}/ =~ cmd).nil?
|
32
|
+
|
33
|
+
# Check for git aliases that call `commit --amend`
|
34
|
+
`git config --get-regexp "^alias\\." "#{amend_pattern}"`.
|
35
|
+
scan(/alias\.([-\w]+)/). # Extract the alias
|
36
|
+
each do |match|
|
37
|
+
return @amendment if
|
38
|
+
# True if the command uses a git alias for `commit --amend`
|
39
|
+
@amendment = !(/git(\.exe)?\s+#{match[0]}/ =~ cmd).nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
@amendment
|
43
|
+
end
|
44
|
+
|
45
|
+
# Stash unstaged contents of files so hooks don't see changes that aren't
|
46
|
+
# about to be committed.
|
47
|
+
def setup_environment
|
48
|
+
store_modified_times
|
49
|
+
Overcommit::GitRepo.store_merge_state
|
50
|
+
Overcommit::GitRepo.store_cherry_pick_state
|
51
|
+
|
52
|
+
# Don't attempt to stash changes if all changes are staged, as this
|
53
|
+
# prevents us from modifying files at all, which plays better with
|
54
|
+
# editors/tools which watch for file changes.
|
55
|
+
if !initial_commit? && unstaged_changes?
|
56
|
+
stash_changes
|
57
|
+
|
58
|
+
# While running hooks make it appear as if nothing changed
|
59
|
+
restore_modified_times
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Restore unstaged changes and reset file modification times so it appears
|
64
|
+
# as if nothing ever changed.
|
65
|
+
#
|
66
|
+
# We want to restore the modification times for each of the files after
|
67
|
+
# every step to ensure as little time as possible has passed while the
|
68
|
+
# modification time on the file was newer. This helps us play more nicely
|
69
|
+
# with file watchers.
|
70
|
+
def cleanup_environment
|
71
|
+
if @changes_stashed
|
72
|
+
clear_working_tree
|
73
|
+
restore_working_tree
|
74
|
+
restore_modified_times
|
75
|
+
end
|
76
|
+
|
77
|
+
Overcommit::GitRepo.restore_merge_state
|
78
|
+
Overcommit::GitRepo.restore_cherry_pick_state
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get a list of added, copied, or modified files that have been staged.
|
82
|
+
# Renames and deletions are ignored, since there should be nothing to check.
|
83
|
+
def modified_files
|
84
|
+
unless @modified_files
|
85
|
+
currently_staged = Overcommit::GitRepo.modified_files(staged: true)
|
86
|
+
@modified_files = currently_staged
|
87
|
+
|
88
|
+
# Include files modified in last commit if amending
|
89
|
+
if amendment?
|
90
|
+
subcmd = 'show --format=%n'
|
91
|
+
previously_modified = Overcommit::GitRepo.modified_files(subcmd: subcmd)
|
92
|
+
@modified_files |= filter_modified_files(previously_modified)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
@modified_files
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns the set of line numbers corresponding to the lines that were
|
99
|
+
# changed in a specified file.
|
100
|
+
def modified_lines_in_file(file)
|
101
|
+
@modified_lines ||= {}
|
102
|
+
unless @modified_lines[file]
|
103
|
+
@modified_lines[file] =
|
104
|
+
Overcommit::GitRepo.extract_modified_lines(file, staged: true)
|
105
|
+
|
106
|
+
# Include lines modified in last commit if amending
|
107
|
+
if amendment?
|
108
|
+
subcmd = 'show --format=%n'
|
109
|
+
@modified_lines[file] +=
|
110
|
+
Overcommit::GitRepo.extract_modified_lines(file, subcmd: subcmd)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
@modified_lines[file]
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns whether the current git branch is empty (has no commits).
|
117
|
+
def initial_commit?
|
118
|
+
return @initial_commit unless @initial_commit.nil?
|
119
|
+
@initial_commit = Overcommit::GitRepo.initial_commit?
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def stash_changes
|
125
|
+
@stash_attempted = true
|
126
|
+
|
127
|
+
stash_message = "Overcommit: Stash of repo state before hook run at #{Time.now}"
|
128
|
+
result = Overcommit::Utils.with_environment('GIT_LITERAL_PATHSPECS' => '0') do
|
129
|
+
Overcommit::Utils.execute(
|
130
|
+
%w[git -c commit.gpgsign=false stash save --keep-index --quiet] + [stash_message]
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
unless result.success?
|
135
|
+
# Failure to stash in this case is likely due to a configuration
|
136
|
+
# issue (e.g. author/email not set or GPG signing key incorrect)
|
137
|
+
raise Overcommit::Exceptions::HookSetupFailed,
|
138
|
+
"Unable to setup environment for #{hook_script_name} hook run:" \
|
139
|
+
"\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
|
140
|
+
end
|
141
|
+
|
142
|
+
@changes_stashed = `git stash list -1`.include?(stash_message)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Clears the working tree so that the stash can be applied.
|
146
|
+
def clear_working_tree
|
147
|
+
removed_submodules = Overcommit::GitRepo.staged_submodule_removals
|
148
|
+
|
149
|
+
result = Overcommit::Utils.execute(%w[git reset --hard])
|
150
|
+
unless result.success?
|
151
|
+
raise Overcommit::Exceptions::HookCleanupFailed,
|
152
|
+
"Unable to cleanup working tree after #{hook_script_name} hooks run:" \
|
153
|
+
"\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
|
154
|
+
end
|
155
|
+
|
156
|
+
# Hard-resetting a staged submodule removal results in the index being
|
157
|
+
# reset but the submodule being restored as an empty directory. This empty
|
158
|
+
# directory prevents us from stashing on a subsequent run if a hook fails.
|
159
|
+
#
|
160
|
+
# Work around this by removing these empty submodule directories as there
|
161
|
+
# doesn't appear any reason to keep them around.
|
162
|
+
removed_submodules.each do |submodule|
|
163
|
+
FileUtils.rmdir(submodule.path)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Applies the stash to the working tree to restore the user's state.
|
168
|
+
def restore_working_tree
|
169
|
+
result = Overcommit::Utils.execute(%w[git stash pop --index --quiet])
|
170
|
+
unless result.success?
|
171
|
+
raise Overcommit::Exceptions::HookCleanupFailed,
|
172
|
+
"Unable to restore working tree after #{hook_script_name} hooks run:" \
|
173
|
+
"\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Returns whether there are any changes to tracked files which have not yet
|
178
|
+
# been staged.
|
179
|
+
def unstaged_changes?
|
180
|
+
result = Overcommit::Utils.execute(%w[git --no-pager diff --quiet])
|
181
|
+
!result.success?
|
182
|
+
end
|
183
|
+
|
184
|
+
# Stores the modification times for all modified files to make it appear like
|
185
|
+
# they never changed.
|
186
|
+
#
|
187
|
+
# This prevents (some) editors from complaining about files changing when we
|
188
|
+
# stash changes before running the hooks.
|
189
|
+
def store_modified_times
|
190
|
+
@modified_times = {}
|
191
|
+
|
192
|
+
staged_files = modified_files
|
193
|
+
unstaged_files = Overcommit::GitRepo.modified_files(staged: false)
|
194
|
+
|
195
|
+
(staged_files + unstaged_files).each do |file|
|
196
|
+
next if Overcommit::Utils.broken_symlink?(file)
|
197
|
+
next unless File.exist?(file) # Ignore renamed files (old file no longer exists)
|
198
|
+
@modified_times[file] = File.mtime(file)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Restores the file modification times for all modified files to make it
|
203
|
+
# appear like they never changed.
|
204
|
+
def restore_modified_times
|
205
|
+
@modified_times.each do |file, time|
|
206
|
+
next if Overcommit::Utils.broken_symlink?(file)
|
207
|
+
next unless File.exist?(file)
|
208
|
+
File.utime(time, time, file)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Overcommit::HookContext
|
4
|
+
# Contains helpers related to contextual information used by pre-push hooks.
|
5
|
+
class PrePush < Base
|
6
|
+
attr_accessor :args
|
7
|
+
|
8
|
+
def remote_name
|
9
|
+
@args[0]
|
10
|
+
end
|
11
|
+
|
12
|
+
def remote_url
|
13
|
+
@args[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def remote_ref_deletion?
|
17
|
+
return @remote_ref_deletion if defined?(@remote_ref_deletion)
|
18
|
+
|
19
|
+
@remote_ref_deletion ||= input_lines.
|
20
|
+
first&.
|
21
|
+
split(' ')&.
|
22
|
+
first == '(deleted)'
|
23
|
+
end
|
24
|
+
|
25
|
+
def pushed_refs
|
26
|
+
input_lines.map do |line|
|
27
|
+
PushedRef.new(*line.split(' '))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def modified_files
|
32
|
+
@modified_files ||= pushed_refs.map(&:modified_files).flatten.uniq
|
33
|
+
end
|
34
|
+
|
35
|
+
def modified_lines_in_file(file)
|
36
|
+
@modified_lines ||= {}
|
37
|
+
@modified_lines[file] = pushed_refs.each_with_object(Set.new) do |pushed_ref, set|
|
38
|
+
set.merge(pushed_ref.modified_lines_in_file(file))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
PushedRef = Struct.new(:local_ref, :local_sha1, :remote_ref, :remote_sha1) do
|
43
|
+
def forced?
|
44
|
+
!(created? || deleted? || overwritten_commits.empty?)
|
45
|
+
end
|
46
|
+
|
47
|
+
def created?
|
48
|
+
remote_sha1 == '0' * 40
|
49
|
+
end
|
50
|
+
|
51
|
+
def deleted?
|
52
|
+
local_sha1 == '0' * 40
|
53
|
+
end
|
54
|
+
|
55
|
+
def destructive?
|
56
|
+
deleted? || forced?
|
57
|
+
end
|
58
|
+
|
59
|
+
def modified_files
|
60
|
+
Overcommit::GitRepo.modified_files(refs: ref_range)
|
61
|
+
end
|
62
|
+
|
63
|
+
def modified_lines_in_file(file)
|
64
|
+
Overcommit::GitRepo.extract_modified_lines(file, refs: ref_range)
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_s
|
68
|
+
"#{local_ref} #{local_sha1} #{remote_ref} #{remote_sha1}"
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def ref_range
|
74
|
+
"#{remote_sha1}..#{local_sha1}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def overwritten_commits
|
78
|
+
return @overwritten_commits if defined? @overwritten_commits
|
79
|
+
result = Overcommit::Subprocess.spawn(%W[git rev-list #{remote_sha1} ^#{local_sha1}])
|
80
|
+
if result.success?
|
81
|
+
result.stdout.split("\n")
|
82
|
+
else
|
83
|
+
raise Overcommit::Exceptions::GitRevListError,
|
84
|
+
"Unable to check if commits on the remote ref will be overwritten: #{result.stderr}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Overcommit::HookContext
|
4
|
+
# Contains helpers related to contextual information used by pre-rebase
|
5
|
+
# hooks.
|
6
|
+
class PreRebase < Base
|
7
|
+
# Returns the name of the branch we are rebasing onto.
|
8
|
+
def upstream_branch
|
9
|
+
@args[0]
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the name of the branch being rebased. Empty if rebasing a
|
13
|
+
# detached HEAD.
|
14
|
+
def rebased_branch
|
15
|
+
@rebased_branch ||=
|
16
|
+
@args[1] || `git symbolic-ref --short --quiet HEAD`.chomp
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns whether we are rebasing a detached HEAD rather than a branch
|
20
|
+
def detached_head?
|
21
|
+
rebased_branch.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns whether this rebase is a fast-forward
|
25
|
+
def fast_forward?
|
26
|
+
rebased_commits.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the SHA1-sums of the series of commits to be rebased
|
30
|
+
# in reverse topological order.
|
31
|
+
def rebased_commits
|
32
|
+
rebased_ref = detached_head? ? 'HEAD' : rebased_branch
|
33
|
+
@rebased_commits ||=
|
34
|
+
`git rev-list --topo-order --reverse #{upstream_branch}..#{rebased_ref}`.
|
35
|
+
split("\n")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Overcommit::HookContext
|
4
|
+
# Contains helpers related to contextual information used by prepare-commit-msg
|
5
|
+
# hooks.
|
6
|
+
class PrepareCommitMsg < Base
|
7
|
+
# Returns the name of the file that contains the commit log message
|
8
|
+
def commit_message_filename
|
9
|
+
@args[0]
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the source of the commit message, and can be: message (if a -m or
|
13
|
+
# -F option was given); template (if a -t option was given or the
|
14
|
+
# configuration option commit.template is set); merge (if the commit is a
|
15
|
+
# merge or a .git/MERGE_MSG file exists); squash (if a .git/SQUASH_MSG file
|
16
|
+
# exists); or commit, followed by a commit SHA-1 (if a -c, -C or --amend
|
17
|
+
# option was given)
|
18
|
+
def commit_message_source
|
19
|
+
@args[1]&.to_sym
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the commit's SHA-1.
|
23
|
+
# If commit_message_source is :commit, it's passed through the command-line.
|
24
|
+
def commit_message_source_ref
|
25
|
+
@args[2] || `git rev-parse HEAD`
|
26
|
+
end
|
27
|
+
|
28
|
+
# Lock for the pre_commit_message file. Should be shared by all
|
29
|
+
# prepare-commit-message hooks
|
30
|
+
def lock
|
31
|
+
@lock ||= Monitor.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|