Class: Overcommit::HookContext::PreCommit

Inherits:
Base
  • Object
show all
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

Methods inherited from Base

#hook_class_name, #hook_script_name, #hook_type_name, #initialize

Constructor Details

This class inherits a constructor from Overcommit::HookContext::Base

Instance Method Details

#cleanup_environmentObject

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.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/overcommit/hook_context/pre_commit.rb', line 48

def cleanup_environment
  unless initial_commit? || (@stash_attempted && !@changes_stashed)
    clear_working_tree # Ensure working tree is clean before restoring it
    restore_modified_times
  end

  if @changes_stashed
    restore_working_tree
    restore_modified_times
  end

  Overcommit::GitRepo.restore_merge_state
  Overcommit::GitRepo.restore_cherry_pick_state
  restore_modified_times
end

#modified_filesObject

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.



66
67
68
# File 'lib/overcommit/hook_context/pre_commit.rb', line 66

def modified_files
  @modified_files ||= Overcommit::GitRepo.modified_files(staged: true)
end

#modified_lines(file) ⇒ Object

Deprecated.

TODO: Remove this once we’ve moved all existing hooks to stop using this endpoint



73
74
75
# File 'lib/overcommit/hook_context/pre_commit.rb', line 73

def modified_lines(file)
  modified_lines_in_file(file)
end

#modified_lines_in_file(file) ⇒ Object

Returns the set of line numbers corresponding to the lines that were changed in a specified file.



79
80
81
82
83
# File 'lib/overcommit/hook_context/pre_commit.rb', line 79

def modified_lines_in_file(file)
  @modified_lines ||= {}
  @modified_lines[file] ||=
    Overcommit::GitRepo.extract_modified_lines(file, staged: true)
end

#setup_environmentObject

Stash unstaged contents of files so hooks don’t see changes that aren’t about to be committed.



13
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
# File 'lib/overcommit/hook_context/pre_commit.rb', line 13

def setup_environment
  store_modified_times
  Overcommit::GitRepo.store_merge_state
  Overcommit::GitRepo.store_cherry_pick_state

  if !initial_commit? && any_changes?
    @stash_attempted = true

    result = Overcommit::Utils.execute(
      %w[git stash save --keep-index --quiet] +
      ["Overcommit: Stash of repo state before hook run at #{Time.now}"]
    )

    unless result.success?
      # Failure to stash in this case is likely due to a configuration
      # issue (e.g. author/email not set or GPG signing key incorrect)
      raise Overcommit::Exceptions::HookSetupFailed,
            "Unable to setup environment for #{hook_script_name} hook run:" \
            "\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
    end

    @changes_stashed = true
  end

  # While running the hooks make it appear as if nothing changed
  restore_modified_times
end