From b362fa1eb81e7e6fa208cc8cab51f110db20057b Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Sun, 4 Feb 2018 23:32:42 +0100 Subject: [PATCH 1/4] Improve git-status processing * no longer traverse complete directory trees to determine git status for directories * properly report status for folders with changed files * skip the parent folder since we do not have git status about it --- lib/colorls/core.rb | 38 ++++++++++++++------------------------ lib/colorls/git.rb | 2 +- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/lib/colorls/core.rb b/lib/colorls/core.rb index 1d39498..916fbda 100644 --- a/lib/colorls/core.rb +++ b/lib/colorls/core.rb @@ -218,45 +218,35 @@ module ColorLS def git_info(path, content) return '' unless @git_status - # puts "\n\n" + real_path = File.realdirpath(content.name, path) - relative_path = path.remove(@git_root_path+'/') - relative_path = relative_path==path ? '' : relative_path+'/' - content_path = "#{relative_path}#{content}" + return ' ' unless real_path.start_with? path + + relative_path = real_path.remove(Regexp.new('^' + Regexp.escape(@git_root_path) + '/?')) if content.directory? - git_dir_info(content_path) + git_dir_info(relative_path) else - git_file_info(content_path) + git_file_info(relative_path) end # puts "\n\n" end def git_file_info(path) return ' ✓ '.colorize(@colors[:unchanged]) unless @git_status[path] - Git.colored_status_symbols(@git_status[path], @colors) - end - - Dir.class_eval do - def self.deep_entries(path) - (Dir.entries(path) - ['.', '..']).map do |entry| - if Dir.exist?("#{path}/#{entry}") - Dir.deep_entries("#{path}/#{entry}") - else - entry - end - end.flatten - end + Git.colored_status_symbols(@git_status[path].uniq, @colors) end def git_dir_info(path) - ignored = @git_status.select { |file, mode| file.start_with?(path) && mode=='!!' }.keys - present = Dir.deep_entries(path).map { |p| "#{path}/#{p}" } - return ' ' if (present-ignored).empty? + direct_status = @git_status.fetch("#{path}/", nil) + + return Git.colored_status_symbols(direct_status.uniq, @colors) unless direct_status.nil? + + modes = @git_status.select { |file, mode| file.start_with?(path) && mode != '!!' } - modes = (present-ignored).map { |file| @git_status[file] }-[nil] return ' ✓ '.colorize(@colors[:unchanged]) if modes.empty? - Git.colored_status_symbols(modes.join.uniq, @colors) + + Git.colored_status_symbols(modes.values.join.uniq, @colors) end def long_info(content) diff --git a/lib/colorls/git.rb b/lib/colorls/git.rb index 26369ac..23c6fa9 100644 --- a/lib/colorls/git.rb +++ b/lib/colorls/git.rb @@ -3,7 +3,7 @@ module ColorLS def self.status(repo_path) @git_status = {} - IO.popen(['git', '-C', repo_path, 'status', '--porcelain', '-z', '-uall', '--ignored']) do |output| + IO.popen(['git', '-C', repo_path, 'status', '--porcelain', '-z', '-unormal', '--ignored']) do |output| output.read.split("\x0").map { |x| x.split(' ', 2) }.each do |mode, file| @git_status[file] = mode end From 51fe55cc8fe2b5477d5683fbb4dc3cfeb10c134c Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Tue, 13 Feb 2018 23:11:22 +0100 Subject: [PATCH 2/4] Simplify git mode padding --- lib/colorls/git.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/colorls/git.rb b/lib/colorls/git.rb index 23c6fa9..a0556f4 100644 --- a/lib/colorls/git.rb +++ b/lib/colorls/git.rb @@ -14,13 +14,7 @@ module ColorLS end def self.colored_status_symbols(modes, colors) - modes = - case modes.length - when 1 then " #{modes} " - when 2 then " #{modes} " - when 3 then "#{modes} " - when 4 then modes - end + modes = modes.rjust(3).ljust(4) modes .gsub('?', '?'.colorize(colors[:untracked])) From 8b0ea26c01b9ff89c1c4642111d3419f77041e6a Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Tue, 27 Mar 2018 19:30:12 +0200 Subject: [PATCH 3/4] Skip next NUL separated git status field for renames In the `-z` git status format, a NUL follows each file name. When files are renamed, the status field is followed by a space, the "to" path, a NUL character, the "from" path and a terminating NUL. This fixes #185. --- lib/colorls/git.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/colorls/git.rb b/lib/colorls/git.rb index a0556f4..ee0c124 100644 --- a/lib/colorls/git.rb +++ b/lib/colorls/git.rb @@ -4,8 +4,13 @@ module ColorLS @git_status = {} IO.popen(['git', '-C', repo_path, 'status', '--porcelain', '-z', '-unormal', '--ignored']) do |output| - output.read.split("\x0").map { |x| x.split(' ', 2) }.each do |mode, file| + while (status_line = output.gets "\x0") + mode, file = status_line.chomp("\x0").split(' ', 2) + @git_status[file] = mode + + # skip the next \x0 separated original path for renames, issue #185 + output.gets("\x0") if mode.start_with? 'R' end end warn "git status failed in #{repo_path}" unless $CHILD_STATUS.success? From 8f9a5f94099ba0ababcd1e1376cf29d91e6ceb17 Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Tue, 27 Mar 2018 20:01:33 +0200 Subject: [PATCH 4/4] Fix Style/ExpandPathArguments cop error --- colorls.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/colorls.gemspec b/colorls.gemspec index c509023..8f75352 100644 --- a/colorls.gemspec +++ b/colorls.gemspec @@ -1,4 +1,4 @@ -lib = File.expand_path('../lib', __FILE__) +lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'colorls/version'