ruby-git status and command line git status differ #23

Open
josh803316 opened this Issue May 20, 2011 · 5 comments

5 participants

@josh803316

I'm attempting to check for git changes in a current directory after I re-write a file. For some reason @git.status.changed always shows that the file has been changed, even though command line git status shows no diff, as it should. Is there a way around this. I'm attempting to decide whether to update a field in the file if it has been changed before pushing to git.

    # Check the if the contents of a directory in git
    def dir_has_changes? dir
        intersection = dir.split('/') - @top_level.split('/')
        intersection = intersection.join('/')
        has_changes = false
        @git.status.changed.each do |file|
            if file[0] =~ /#{intersection}/
                has_changes = true
            end
        end
        return has_changes
    end
@josh803316

I was able to circumvent the problem by doing this, in case anyone else has run into the same issue

       @git.status.changed.each do |file|
            if file[0] =~ /#{intersection}/
                result      = @git.diff('HEAD',"#{dir}/")
                has_changes = true unless result.entries.length < 1
            end
        end
@lukeasrodgers

I'm having this issue as well.

EDIT

Curiously, shelling out to git status from ruby before, e.g. @git.status seems to result in the latter reporting status accurately.

@ohaleck

I found out that after touching a file (updating its modification date) Git needs to be reopened again. Here is the experiment I made in irb:

2.1.2 :001 > require 'git'
 => true
2.1.2 :002 > g=Git.open('.')
 => #<Git::Base:0x007fe5931d4608 ...>
2.1.2 :003 > g.status.changed.size
 => 0
2.1.2 :004 > g.diff('HEAD').size
 => 0
2.1.2 :005 > system "touch example.txt"
 => true
2.1.2 :006 > g.status.changed.size
 => 1
2.1.2 :007 > g.diff('HEAD').size
 => 0
2.1.2 :008 > g=Git.open('.')
 => #<Git::Base:0x007fe5938101c0 ...>
2.1.2 :009 > g.status.changed.size
 => 0
2.1.2 :010 > g.diff('HEAD').size
 => 0
@ohaleck

ruby-git status behind the scenes calls git diff-files instead of actual git status. git diff-files shows all changes made to files (including mode and modification date changes), but only until git diff is called once. So strange...

Finally, I ended up with:

      @g.status.changed.each do
        @g.diff.entries
      end

This is similar to the solution proposed by @josh803316 , yet just calling diff.entries once for each element of g.status.changed enumeration is sufficient to sanitize the contents of @g.status.changed and once it's done, g.status.changed can enumerated again, this time with correct result.
I'm sorry, but I have no idea, why it is so.
ruby-git version is 1.2.8
ruby binary version is 2.1.2p95

@tim-group-git tim-group-git pushed a commit to tim-group/orc that referenced this issue Jun 15, 2015
Michal Mazurek solve the IT10629 request:
work around a ruby bug in ruby-git, see schacon/ruby-git#23
0e9a5f9
@chilicheech

This is affecting me as well. Why can't ruby-git status call git status instead of git diff-files? This implementation is confusing because it differs from git's implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment