Class: Overcommit::HookContext::PreCommit
- Defined in:
- lib/overcommit/hook_context/pre_commit.rb
Overview
Contains helpers related to contextual information used by pre-commit hooks.
This includes staged files, which lines of those files have been modified, etc. It is also responsible for saving/restoring the state of the repo so hooks only inspect staged changes.
Instance Method Summary collapse
-
#amendment? ⇒ Boolean
Returns whether this hook run was triggered by ‘git commit –amend`.
-
#cleanup_environment ⇒ Object
Restore unstaged changes and reset file modification times so it appears as if nothing ever changed.
-
#initial_commit? ⇒ Boolean
Returns whether the current git branch is empty (has no commits).
-
#modified_files ⇒ Object
Get a list of added, copied, or modified files that have been staged.
-
#modified_lines_in_file(file) ⇒ Object
Returns the set of line numbers corresponding to the lines that were changed in a specified file.
-
#setup_environment ⇒ Object
Stash unstaged contents of files so hooks don’t see changes that aren’t about to be committed.
Methods inherited from Base
#all_files, #execute_hook, #hook_class_name, #hook_script_name, #hook_type_name, #initialize, #input_lines, #input_string, #post_fail_message
Constructor Details
This class inherits a constructor from Overcommit::HookContext::Base
Instance Method Details
#amendment? ⇒ Boolean
Returns whether this hook run was triggered by ‘git commit –amend`
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/overcommit/hook_context/pre_commit.rb', line 14 def amendment? return @amendment unless @amendment.nil? cmd = Overcommit::Utils.parent_command return unless cmd amend_pattern = 'commit(\s.*)?\s--amend(\s|$)' # Since the ps command can return invalid byte sequences for commands # containing unicode characters, we replace the offending characters, # since the pattern we're looking for will consist of ASCII characters unless cmd.valid_encoding? cmd = Overcommit::Utils.parent_command.encode('UTF-16be', invalid: :replace, replace: '?'). encode('UTF-8') end return @amendment if # True if the command is a commit with the --amend flag @amendment = !(/\s#{amend_pattern}/ =~ cmd).nil? # Check for git aliases that call `commit --amend` `git config --get-regexp "^alias\\." "#{amend_pattern}"`. scan(/alias\.([-\w]+)/). # Extract the alias each do |match| return @amendment if # True if the command uses a git alias for `commit --amend` @amendment = !(/git(\.exe)?\s+#{match[0]}/ =~ cmd).nil? end @amendment end |
#cleanup_environment ⇒ Object
Restore unstaged changes and reset file modification times so it appears as if nothing ever changed.
We want to restore the modification times for each of the files after every step to ensure as little time as possible has passed while the modification time on the file was newer. This helps us play more nicely with file watchers.
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/overcommit/hook_context/pre_commit.rb', line 70 def cleanup_environment if @changes_stashed clear_working_tree restore_working_tree restore_modified_times end Overcommit::GitRepo.restore_merge_state Overcommit::GitRepo.restore_cherry_pick_state end |
#initial_commit? ⇒ Boolean
Returns whether the current git branch is empty (has no commits).
117 118 119 120 |
# File 'lib/overcommit/hook_context/pre_commit.rb', line 117 def initial_commit? return @initial_commit unless @initial_commit.nil? @initial_commit = Overcommit::GitRepo.initial_commit? end |
#modified_files ⇒ Object
Get a list of added, copied, or modified files that have been staged. Renames and deletions are ignored, since there should be nothing to check.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/overcommit/hook_context/pre_commit.rb', line 83 def modified_files unless @modified_files currently_staged = Overcommit::GitRepo.modified_files(staged: true) @modified_files = currently_staged # Include files modified in last commit if amending if amendment? subcmd = 'show --format=%n' previously_modified = Overcommit::GitRepo.modified_files(subcmd: subcmd) @modified_files |= filter_modified_files(previously_modified) end end @modified_files end |
#modified_lines_in_file(file) ⇒ Object
Returns the set of line numbers corresponding to the lines that were changed in a specified file.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/overcommit/hook_context/pre_commit.rb', line 100 def modified_lines_in_file(file) @modified_lines ||= {} unless @modified_lines[file] @modified_lines[file] = Overcommit::GitRepo.extract_modified_lines(file, staged: true) # Include lines modified in last commit if amending if amendment? subcmd = 'show --format=%n' @modified_lines[file] += Overcommit::GitRepo.extract_modified_lines(file, subcmd: subcmd) end end @modified_lines[file] end |
#setup_environment ⇒ Object
Stash unstaged contents of files so hooks don’t see changes that aren’t about to be committed.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/overcommit/hook_context/pre_commit.rb', line 47 def setup_environment store_modified_times Overcommit::GitRepo.store_merge_state Overcommit::GitRepo.store_cherry_pick_state # Don't attempt to stash changes if all changes are staged, as this # prevents us from modifying files at all, which plays better with # editors/tools which watch for file changes. if !initial_commit? && unstaged_changes? stash_changes # While running hooks make it appear as if nothing changed restore_modified_times end end |