def changes( path, options={}, &block )
      # ensure the options can be passed to C successfully
      start_rev = (options[:start_rev] || 0).to_i
      end_rev = (options[:end_rev] || youngest).to_i
      cross_copies = ( options[:cross_copies] ? 1 : 0 )

      # collect the change [path, rev] pairs
      changes = []
      Error.check_and_raise( C.history(
          fs, path,
          C::CollectChanges, Utils.wrap( changes ),
          nil, nil, start_rev, end_rev, cross_copies, pool
        ) )

      # if the caller supplied a block, use it
      changes.each( &block ) if block_given?

      changes
    end
def changes( path, options={}, &block )
      # ensure the options can be passed to C successfully
      start_rev = (options[:start_rev] || 0).to_i
      end_rev = (options[:end_rev] || youngest).to_i
      cross_copies = ( options[:cross_copies] ? 1 : 0 )

      # collect the change [path, rev] pairs
      changes = []
      Error.check_and_raise( C.history(
          fs, path,
          C::CollectChanges, Utils.wrap( changes ),
          nil, nil, start_rev, end_rev, cross_copies, pool
        ) )

      # if the caller supplied a block, use it
      changes.each( &block ) if block_given?

      changes
    end
returns an array of "interesting" [path, rev] pairs for path

 for more detailed information, use +history+

 if a block is given, each pair will be yielded

 options:
 +start_rev+ :: restricts revisions to newer than :start_rev
 +end_rev+ :: restricts revisions to older than :end_rev
 +cross_copies+ :: continue history at filesystem copies?