1

I'm a novice Rugged user, and I'm attempting to detect file renames in the commit history. I'm diffing each commit against its first parent, as follows:

repo = Rugged::Repository.discover("foo")
walker = Rugged::Walker.new(repo)
walker.sorting(Rugged::SORT_TOPO)
walker.push("master")

walker.each.take(200).each do |commit|
  puts commit.oid  
  puts commit.message

  diffs = nil

  # Handle Root commit
  if commit.parents.count > 0 then
    diffs = commit.parents[0].diff(commit)
  else
    diffs = commit.diff(nil)
  end

  (files,additions,deletions) = diffs.stat
  puts "Files changed: #{files}, Additions: #{additions}, Deletions: #{deletions}"  

  paths = [];
  diffs.each_delta do |delta|
    old_file_path = delta.old_file[:path]
    new_file_path = delta.new_file[:path]   

    puts delta.status
    puts delta.renamed?
    puts delta.similarity
    paths += [delta]
 end

 puts "Paths:"
 puts paths
 puts "===================================="

end
walker.reset

However, when I do have a rename, the program will output an addition and a removal (A and D status). This matches the output of git log --name-status.

On the other hand, I found out that using git log --name-status --format='%H' --follow -- b.txt correctly shows the rename as R100.

The repo history and the outputs of git can be seen in the following gist: https://gist.github.com/ifigueroap/60716bbf4aa2f205b9c9

My question is how to use the Diff, or Delta objects of Rugged to detect such a file rename...

Thanks

Ismael
  • 344
  • 1
  • 3
  • 14

1 Answers1

2

Before accessing diffs.stat, you should call diffs.find_similar! with :renames => true. That'll modify the diffs object to do include rename information. This is not done by default, as the underlying operation is quite complex and not needed in most cases.

Check the documentation for find_similar! here: https://github.com/libgit2/rugged/blob/e96d26174b2bf763e9dd5dd2370e79f5e29077c9/ext/rugged/rugged_diff.c#L310-L366 for more options.