Skip to content

Commit 7f23eb4

Browse files
jawshooahsds
authored andcommitted
Include modifications from last commit if amending
1 parent c1fd423 commit 7f23eb4

File tree

2 files changed

+153
-24
lines changed

2 files changed

+153
-24
lines changed

Diff for: lib/overcommit/hook_context/pre_commit.rb

+41-13
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,26 @@ module Overcommit::HookContext
99
# hooks only inspect staged changes.
1010
class PreCommit < Base # rubocop:disable ClassLength
1111
# Returns whether this hook run was triggered by `git commit --amend`
12-
def amend?
13-
if @amended.nil?
14-
cmd = Overcommit::Utils.parent_command
15-
@amended = !(/--amend/ =~ cmd).nil?
16-
17-
amend_alias = `git config --get-regexp '^alias\\.' '--amend'`.
18-
slice(/(?<=alias\.)\w+/)
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
1930

20-
@amended ||= !(/git #{amend_alias}/ =~ cmd).nil? unless amend_alias.nil?
21-
end
22-
@amended
31+
@amendment
2332
end
2433

2534
# Stash unstaged contents of files so hooks don't see changes that aren't
@@ -78,7 +87,16 @@ def cleanup_environment
7887
# Get a list of added, copied, or modified files that have been staged.
7988
# Renames and deletions are ignored, since there should be nothing to check.
8089
def modified_files
81-
@modified_files ||= Overcommit::GitRepo.modified_files(staged: true)
90+
unless @modified_files
91+
@modified_files = Overcommit::GitRepo.modified_files(staged: true)
92+
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
82100
end
83101

84102
# @deprecated
@@ -92,8 +110,18 @@ def modified_lines(file)
92110
# changed in a specified file.
93111
def modified_lines_in_file(file)
94112
@modified_lines ||= {}
95-
@modified_lines[file] ||=
96-
Overcommit::GitRepo.extract_modified_lines(file, staged: true)
113+
unless @modified_lines[file]
114+
@modified_lines[file] =
115+
Overcommit::GitRepo.extract_modified_lines(file, staged: true)
116+
117+
# Include lines modified in last commit if amending
118+
if amendment?
119+
subcmd = 'show --format=%n'
120+
@modified_lines[file] +=
121+
Overcommit::GitRepo.extract_modified_lines(file, subcmd: subcmd)
122+
end
123+
end
124+
@modified_lines[file]
97125
end
98126

99127
private

Diff for: spec/overcommit/hook_context/pre_commit_spec.rb

+112-11
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
let(:input) { double('input') }
88
let(:context) { described_class.new(config, args, input) }
99

10-
describe '#amend?' do
11-
subject { context.amend? }
10+
describe '#amendment?' do
11+
subject { context.amendment? }
12+
13+
before do
14+
Overcommit::Utils.stub(:parent_command).and_return(command)
15+
end
1216

1317
context 'when amending a commit using `git commit --amend`' do
14-
before do
15-
Overcommit::Utils.stub(:parent_command).and_return('git commit --amend')
16-
end
18+
let(:command) { 'git commit --amend' }
1719

1820
it { should == true }
1921
end
@@ -22,23 +24,43 @@
2224
around do |example|
2325
repo do
2426
`git config alias.amend 'commit --amend'`
27+
`git config alias.other-amend 'commit --amend'`
2528
example.run
2629
end
2730
end
2831

29-
before do
30-
Overcommit::Utils.stub(:parent_command).and_return('git amend')
32+
context 'when using one of multiple aliases' do
33+
let(:command) { 'git amend' }
34+
35+
it { should == true }
3136
end
3237

33-
it { should == true }
38+
context 'when using another of multiple aliases' do
39+
let(:command) { 'git other-amend' }
40+
41+
it { should == true }
42+
end
3443
end
3544

3645
context 'when not amending a commit' do
37-
before do
38-
Overcommit::Utils.stub(:parent_command).and_return('git commit')
46+
context 'using `git commit`' do
47+
let(:command) { 'git commit' }
48+
49+
it { should == false }
3950
end
4051

41-
it { should == false }
52+
context 'using a git alias containing "--amend"' do
53+
let(:command) { 'git no--amend' }
54+
55+
around do |example|
56+
repo do
57+
`git config alias.no--amend commit`
58+
example.run
59+
end
60+
end
61+
62+
it { should == false }
63+
end
4264
end
4365
end
4466

@@ -296,6 +318,10 @@
296318
describe '#modified_files' do
297319
subject { context.modified_files }
298320

321+
before do
322+
context.stub(:amendment?).and_return(false)
323+
end
324+
299325
it 'does not include submodules' do
300326
submodule = repo do
301327
`touch foo`
@@ -359,5 +385,80 @@
359385

360386
it { should be_empty }
361387
end
388+
389+
context 'when amending last commit' do
390+
around do |example|
391+
repo do
392+
FileUtils.touch('some-file')
393+
`git add some-file`
394+
`git commit -m 'Initial commit'`
395+
FileUtils.touch('other-file')
396+
`git add other-file`
397+
example.run
398+
end
399+
end
400+
401+
before do
402+
context.stub(:amendment?).and_return(true)
403+
end
404+
405+
it { should =~ [File.expand_path('some-file'), File.expand_path('other-file')] }
406+
end
407+
end
408+
409+
describe '#modified_lines_in_file' do
410+
let(:modified_file) { 'some-file' }
411+
subject { context.modified_lines_in_file(modified_file) }
412+
413+
before do
414+
context.stub(:amendment?).and_return(false)
415+
end
416+
417+
context 'when file contains a trailing newline' do
418+
around do |example|
419+
repo do
420+
File.open(modified_file, 'w') { |f| (1..3).each { |i| f.write("#{i}\n") } }
421+
`git add #{modified_file}`
422+
example.run
423+
end
424+
end
425+
426+
it { should == Set.new(1..3) }
427+
end
428+
429+
context 'when file does not contain a trailing newline' do
430+
around do |example|
431+
repo do
432+
File.open(modified_file, 'w') do |f|
433+
(1..2).each { |i| f.write("#{i}\n") }
434+
f.write(3)
435+
end
436+
437+
`git add #{modified_file}`
438+
example.run
439+
end
440+
end
441+
442+
it { should == Set.new(1..3) }
443+
end
444+
445+
context 'when amending last commit' do
446+
around do |example|
447+
repo do
448+
File.open(modified_file, 'w') { |f| (1..3).each { |i| f.write("#{i}\n") } }
449+
`git add #{modified_file}`
450+
`git commit -m "Add files"`
451+
File.open(modified_file, 'a') { |f| f.puts 4 }
452+
`git add #{modified_file}`
453+
example.run
454+
end
455+
end
456+
457+
before do
458+
context.stub(:amendment?).and_return(true)
459+
end
460+
461+
it { should == Set.new(1..4) }
462+
end
362463
end
363464
end

0 commit comments

Comments
 (0)