def rev_history_status(git_session, rev, options={})
    stop_rev = options[:stop_rev]
    relevant_revs = {}
    if stop_rev
      git_session.execute("git rev-list #{rev} \"^#{stop_rev}\"").split("\n").each do |r|
        relevant_revs[r] = true
      end
    elsif options[:gerrit]
      # in gerrit mode, stop on all known commits
      git_session.execute("git rev-list #{rev} --not --all --").split("\n").each do |r|
        relevant_revs[r] = true
      end
    else
      # remote revs are where we stop traversal
      git_session.all_reachable_non_remote_revs(rev).each do |r| 
        relevant_revs[r] = true
      end
    end
    # make sure we deal only with sha1s
    rev = git_session.rev_sha1(rev)
    build_rev_history_status(git_session, rev, relevant_revs, {}, :fast => options[:fast])
  end
def rev_history_status(git_session, rev, options={})
    stop_rev = options[:stop_rev]
    relevant_revs = {}
    if stop_rev
      git_session.execute("git rev-list #{rev} \"^#{stop_rev}\"").split("\n").each do |r|
        relevant_revs[r] = true
      end
    elsif options[:gerrit]
      # in gerrit mode, stop on all known commits
      git_session.execute("git rev-list #{rev} --not --all --").split("\n").each do |r|
        relevant_revs[r] = true
      end
    else
      # remote revs are where we stop traversal
      git_session.all_reachable_non_remote_revs(rev).each do |r| 
        relevant_revs[r] = true
      end
    end
    # make sure we deal only with sha1s
    rev = git_session.rev_sha1(rev)
    build_rev_history_status(git_session, rev, relevant_revs, {}, :fast => options[:fast])
  end
status object tree for revision rev
 returns the root status object which points to any parent status objects
 note that merge commits mean that the status tree branches
 at the point were the merged branch branched off, the status tree joins
 i.e. the parent status objects are the same at this point

 stops traversing a specific branch when a commit is found which is an ancestor
 of :stop_rev or any remote branch if :stop_rev is not provided;

 with the :gerrit option, stops traversing on any ancestor of any known commit;
 this is necessary since on gerrit there are no "remote" commits;
 at the same time, gerrit doesn't "know" commits pushed in the ref-update hook yet
 so the status will be built for the new commits pushed in the ref-update hook

 the leafs of the tree are the stop commits or commits which have no parents

 with the :fast option set to true, the leafs in the tree will not be checked
 but instead all modules present in those commits will assumed to be clean;
 be aware that this assumption might be wrong!
 if the leaves of the tree are remote commits, the fast check basically tells
 if any of the local commits is dirty or not