Skip to content

Commit 246af64

Browse files
authored
Update index before fetching modified files (#409)
According to the [git-diff-index docs][1], git commands like diff-index and diff-files typically don't look at the actual contents of files in the working tree. This means that these commands can be easily fooled by operations that don't change the content of a file such as deleting and recreating it, or even running `touch` on a file. The docs then say that one may update the index to make it be in sync with the actual contents of the working directory. The recommended command would seem to be `git update-index --refresh`, but in my testing, this caused "needs update" errors in some of the tests. So I've resorted to using `git status`, which is probably a slightly more heavyweight command, but does pass the tests. [1]: https://git-scm.com/docs/git-diff-index Signed-off-by: Gabriel Gilder <gabriel@gabrielgilder.com>
1 parent 8345fec commit 246af64

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

lib/git/lib.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,8 @@ def command(cmd, *opts, &block)
10651065
# @param [Array] opts the diff options to be used
10661066
# @return [Hash] the diff as Hash
10671067
def diff_as_hash(diff_command, opts=[])
1068+
# update index before diffing to avoid spurious diffs
1069+
command('status')
10681070
command_lines(diff_command, opts).inject({}) do |memo, line|
10691071
info, file = line.split("\t")
10701072
mode_src, mode_dest, sha_src, sha_dest, type = info.split

tests/units/test_status.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,20 @@ def test_untracked_boolean
9797
assert(!git.status.untracked?('test_file_2'))
9898
end
9999
end
100+
101+
def test_changed_cache
102+
in_temp_dir do |path|
103+
git = Git.clone(@wdir, 'test_dot_files_status')
104+
105+
create_file('test_dot_files_status/test_file_1', 'hello')
106+
107+
git.add('test_file_1')
108+
git.commit('message')
109+
110+
delete_file('test_dot_files_status/test_file_1')
111+
create_file('test_dot_files_status/test_file_1', 'hello')
112+
113+
assert(!git.status.changed?('test_file_1'))
114+
end
115+
end
100116
end

0 commit comments

Comments
 (0)