<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -6,15 +6,16 @@
 		&lt;% end -%&gt;
 	&lt;/td&gt;
 	&lt;td style='text-align:right'&gt;&lt;%= h node.file_length %&gt;&amp;nbsp;&lt;/td&gt;
-  &lt;% if node.revision &amp;&amp; node.revision.time %&gt;
-    &lt;td&gt;&lt;%= h(node.revision.sha) %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%=h node.revision.user %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= time_ago_in_words node.revision.time %&gt;&lt;/td&gt;
-    &lt;td class=&quot;last&quot;&gt;&lt;%=h node.revision.message %&gt;&lt;/td&gt;
+  &lt;% revision = node.revision %&gt;
+  &lt;% if revision &amp;&amp; revision.time %&gt;
+    &lt;td&gt;&lt;%= h(revision.sha) %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%=h revision.user %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= time_ago_in_words revision.time %&gt;&lt;/td&gt;
+    &lt;td class=&quot;last&quot;&gt;&lt;%=h revision.message %&gt;&lt;/td&gt;
   &lt;% else -%&gt;
     &lt;td&gt;&amp;nbsp;&lt;/td&gt;
     &lt;td&gt;&amp;nbsp;&lt;/td&gt;
     &lt;td&gt;&amp;nbsp;&lt;/td&gt;
     &lt;td class=&quot;last&quot;&gt;&amp;nbsp;&lt;/td&gt;
   &lt;% end -%&gt;
-&lt;/tr&gt;
\ No newline at end of file
+&lt;/tr&gt;</diff>
      <filename>app/views/git_configurations/_node_table_row.rhtml</filename>
    </modified>
    <modified>
      <diff>@@ -27,6 +27,7 @@ module Grit
       opt_args = transform_options(options)
       
       call = &quot;#{Git.git_binary} --git-dir='#{self.git_dir}' #{cmd.to_s.gsub(/_/, '-')} #{(opt_args + args).join(' ')}&quot;
+      # RAILS_DEFAULT_LOGGER.info &quot;!!!\n Git.CALL:#{call}\n !!!&quot;
       puts call if Grit.debug
       response = `#{call}`
       puts response if Grit.debug</diff>
      <filename>gems/grit-0.7.0/lib/grit/git.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,16 +35,12 @@ class GitRepository
   def pulled_recently?
     @last_pull_time ||= Time.now - MAX_PULL_FREQUENCY_IN_MINUTES.minutes - 1.minute
     return true if @last_pull_time &gt; MAX_PULL_FREQUENCY_IN_MINUTES.minutes.ago
-    File.exist?(orig_head) &amp;&amp; File.mtime(orig_head) &lt; MAX_PULL_FREQUENCY_IN_MINUTES.minutes.ago
+    File.exist?(orig_head) &amp;&amp; File.mtime(orig_head) &gt; MAX_PULL_FREQUENCY_IN_MINUTES.minutes.ago
   end
   
-  def pull
-    # RAILS_DEFAULT_LOGGER.info(&quot;!!!\n!!! repo pulled recently (#{repo.path}) !!!\n!!!&quot;) &amp;&amp; 
-    return if pulled_recently?
-    # RAILS_DEFAULT_LOGGER.info(&quot;pulling repo(#{repo.path})&quot;)
-    Git.new(repo.path).pull({}, &quot;origin&quot;, &quot;master&quot;)
-    @last_pull_time = Time.now
+  def init_sha_array
     return if @sha_array.size &gt; 1 &amp;&amp; repo.commits('master',1).first.id == @sha_array[-1]
+    # RAILS_DEFAULT_LOGGER.info(&quot;getting repo config info for (#{repo.path})&quot;)
     config = GitConfiguration.find(:first, :conditions =&gt; [ &quot;repository_path = ?&quot;, @path])
     if config.last_pull_path != @path || config.sha_array.nil? || config.sha_array.empty?
       # reset everything
@@ -54,6 +50,7 @@ class GitRepository
     end
     commit = repo.commits('master',1).first
     @sha_array = Array.new(config.sha_array)
+    # RAILS_DEFAULT_LOGGER.info(&quot;(#{repo.path}) sha_array up-to-date #{@sha_array.inspect}&quot;)
     return if commit.id == @sha_array[-1]
     add_shas = []
     until commit.nil? || commit.id == @sha_array[-1]
@@ -63,6 +60,15 @@ class GitRepository
     @sha_array += add_shas.reverse
     config.sha_array = Array.new(@sha_array)
     config.save!
+    # RAILS_DEFAULT_LOGGER.info(&quot;(#{repo.path}) sha_array updated&quot;)
+  end
+  
+  def pull
+    # RAILS_DEFAULT_LOGGER.info(&quot;!!!\n!!! repo pulled recently (#{repo.path}) !!!\n!!!&quot;) &amp;&amp; return if pulled_recently?
+    # RAILS_DEFAULT_LOGGER.info(&quot;pulling repo(#{repo.path})&quot;)
+    Git.new(repo.path).pull({}, &quot;origin&quot;, &quot;master&quot;)
+    @last_pull_time = Time.now
+    init_sha_array
   end
   
   def close
@@ -83,41 +89,32 @@ class GitRepository
     @sha_array.size - 1
   end
   
+  def revision_of_sha(sha)
+    init_sha_array
+    # RAILS_DEFAULT_LOGGER.info &quot;SHA_ARRAY(#{sha}): #{@sha_array.inspect}&quot;
+    idx = @sha_array.index(sha)
+    # RAILS_DEFAULT_LOGGER.info &quot;SHA_ARRAY-idx : #{idx}&quot;
+    idx
+  end
+  
   # retrieve specified revision(s) details
   def revisions(from = 1, to = youngest_revision_number)
     from, to = from.to_i, to.to_i
     i = from
-    youngest_revision_number if @sha_array.size == 1 
-    @sha_array[from, to].collect do |sha|
+    init_sha_array if @sha_array.size == 1
+    # TODO : What to do in this case -- and why would this be happening?
+    # RAILS_DEFAULT_LOGGER.info &quot;revision #{i} outside of @sha_array bound[#{@sha_array.size-1}]&quot; if from.to_i &gt;= @sha_array.size
+    return [] if from.to_i &gt;= @sha_array.size
+    @sha_array[from.to_i, to.to_i].collect do |sha|
       commit = repo.commit(sha)
       revision = Revision.new(self)
-      RAILS_DEFAULT_LOGGER.debug &quot;revision #{i}/#{commit.id}: #{commit.inspect}&quot;
+      # RAILS_DEFAULT_LOGGER.info &quot;!!!\n!!! revision #{i}/#{commit.id}: #{commit.inspect}\n!!!&quot;
       revision.number = i
       revision.version_control_user = commit.author.name
       revision.mingle_user = @version_control_users[commit.author.email] if @version_control_users 
       revision.time = commit.authored_date
       revision.message = &quot;#{commit.id} - #{commit.message}&quot;
       revision.sha = commit.id
-      begin
-        Timeout::timeout(30) do
-          diffs = (i == 1) ? Commit.show(repo, commit.id) : Commit.diff(repo, @sha_array[i-1], commit.id)    
-          revision.changed_paths = diffs.collect do |diff|
-            next if diff.a_path.nil? # the repo itself
-            change = Revision::ChangedPath.new(revision)
-            change.path = diff.a_path
-            change.action = &quot;M&quot;
-            change.action = &quot;A&quot; if diff.new_file
-            change.action = &quot;D&quot; if diff.deleted_file
-            # DON: Investigate whether this is always available or lazily executed -- most likely don't want all the
-            # diffs generated when we are just getting a list of revisions, but if it there we can make the diff view faster
-            change.diff = diff.diff
-            change
-          end.compact
-        end
-      rescue Timeout::Error
-        RAILS_DEFAULT_LOGGER.warn &quot;(#{repo.path}) parsing diff for #{commit.id} timed out&quot;
-        revision.changed_paths = []
-      end
       i += 1
       revision
     end
@@ -128,8 +125,9 @@ class GitRepository
   end
   
   def revision(number)
-    RAILS_DEFAULT_LOGGER.info &quot;\n!!! GitRepository::revision [#{number}] !!!&quot;
-    revisions(number, number).first || (raise NoSuchRevisionError.new)
+    # RAILS_DEFAULT_LOGGER.info &quot;\n!!! GitRepository::revision [#{number}] !!!&quot;
+    init_sha_array
+    revisions(number, number).first || (RAILS_DEFAULT_LOGGER.warn &quot;!!!\nCOULD NOT FIND REVISION NUMBER[#{number}]\n!!!&quot; &amp;&amp; (raise NoSuchRevisionError.new))
   end
   
   def ==(other)
@@ -144,27 +142,31 @@ class GitRepository
       raise NoSuchRevisionError.new
     end
     path = self.root_path if path.blank?
-    check_revision Node.new(self, path, @sha_array[revision_number], revision_number)
+    check_revision Node.new(self, path, @sha_array[revision_number])
   end
   
   def check_revision(node)
     begin
       node.revision_number
-    rescue # Exception =&gt; e
-      raise NoSuchRevisionError.new
+    rescue Exception =&gt; e
+      # raise NoSuchRevisionError.new
+      RAILS_DEFAULT_LOGGER.warn &quot;!!!\ncheck_revision_exception[#{e.inspect}]\n!!!&quot;
     end
     node
   end
   
   class Node
     
+    include Grit
+    
     attr_reader :path, :git_commit_sha, :git_item
 
-    def initialize(repository, path, git_commit_sha, revision_num, git_item=nil)
+    def initialize(repository, path, git_commit_sha, git_item=nil)
       @repository = repository
       @git_repo = repository.repo
       @git_commit_sha = git_commit_sha
-      @revision_number = revision_num
+      @revision_number = nil
+      @revision = nil
       @path = path
       if !git_item.nil?
         @git_item = git_item
@@ -197,7 +199,7 @@ class GitRepository
     def children
       return [] if file?
       @git_item.contents.collect do |item|
-        Node.new(@repository, absolut_path_for(item.name), @git_commit_sha, revision_number, item)
+        Node.new(@repository, absolut_path_for(item.name), @git_commit_sha, item)
       end
     end
     
@@ -224,24 +226,46 @@ class GitRepository
     end
 
     def revision_number
-      @revision_number
+      # TODO : Want to get the *real* revision number / sha for the node - not the commit revision
+      # Also - only get it *once* and store it
+      begin
+        return @revision_number if @revision_number
+        # RAILS_DEFAULT_LOGGER.info &quot;!!!\nNode::revision_number::sha-path[#{@git_commit_sha}][#{&quot;.&quot; + display_path}]\n!!!&quot;
+        commit_of_node = Git.new(@git_repo.path).rev_list({}, @git_commit_sha, &quot;-1&quot;, &quot;-- .&quot; + display_path).chomp(&quot;\n&quot;)
+        # RAILS_DEFAULT_LOGGER.info &quot;!!!\nNode::revision_number::commit_of_node[#{commit_of_node}]\n!!!&quot;
+        # if commit_of_node.nil? || commit_of_node.empty?
+        #   RAILS_DEFAULT_LOGGER.warn &quot;!!!\nNode::revision_number::sha-path[#{@git_commit_sha}][#{&quot;.&quot; + display_path}] - could not find commit sha\n!!!&quot;
+        #   return 1
+        # end
+        @revision_number = @repository.revision_of_sha(commit_of_node)
+        # RAILS_DEFAULT_LOGGER.info &quot;!!!\nNode::revision_number::revision_number[#{@revision_number}]\n!!!&quot;
+        @revision_number
+      rescue Exception =&gt; e
+        # raise NoSuchRevisionError.new
+        RAILS_DEFAULT_LOGGER.warn &quot;!!!\nNode::revision_number::revision_number_not_found[#{@git_commit_sha}]\n!!!&quot;
+        1
+      end
     end
 
     def revisions
-      raise &quot;list revisions on dir node haven't been implement yet, sorry&quot; if dir?
+      # Hopefully this is never called, since we don't really need it for previous_revision_node
+      raise &quot;Node::revisions not implemented yet&quot; # if dir?
       # TODO : SVN file_revs -&gt; GIT : need a way of getting all revisions for a particular *file*
       # @repository.svn_repos.file_revs(@path, 0, revision_number).collect {|path, rev| rev }
-      []
+      # git log --pretty=online path
     end
 
     def previous_revision_node
+      # Hopefully this is never called, since ChangePath.diff doesn't need it
+      raise &quot;Node::previous_revision_node not implemented yet&quot; # if dir?
       # TODO - what is previous revision of this node - in git?
-      nil # @repository.node(@path, revisions[-2])
+      # git log --pretty=online [file-path]
+      # git rev-list &lt;commit-sha&gt; -- -1 path-to-file
     end
 
     def revision
-      RAILS_DEFAULT_LOGGER.info &quot;!!! Node::revision [#{revision_number}]&quot;
-      @repository.revision(revision_number)
+      # RAILS_DEFAULT_LOGGER.info &quot;!!! Node::revision [#{revision_number}]&quot;
+      @revision ||= @repository.revision(revision_number)
     end
 
     def dir?
@@ -272,6 +296,8 @@ class GitRepository
 
 
   class Revision
+    include Grit
+    
     class ChangedPath
       attr_accessor :path
       attr_accessor :action # 'A'dd, 'D'elete, 'R'eplace, 'M'odify
@@ -325,7 +351,7 @@ class GitRepository
       end
 
       def html_diff
-        RAILS_DEFAULT_LOGGER.info &quot;!!! Revision::ChangePath::html_diff[#{@path}] !!!&quot;
+        # RAILS_DEFAULT_LOGGER.info &quot;!!! Revision::ChangePath::html_diff[#{@path}] !!!&quot;
         return '' if node.nil? || node.dir? || node.binary?
         chunks_html = diff_chunks.collect do |chunk|
           chunk.lines.collect do |line|
@@ -350,7 +376,7 @@ class GitRepository
 
     end
 
-    attr_accessor :version_control_user, :mingle_user, :message, :number, :time, :changed_paths, :sha
+    attr_accessor :version_control_user, :mingle_user, :message, :number, :time, :sha
     attr_reader :repository
     alias updated_at time
 
@@ -364,6 +390,33 @@ class GitRepository
         item.to_s.upcase.include?(term.upcase) 
       end or number.to_s == term
     end
+    
+    def changed_paths
+      repo = repository.repo
+      # RAILS_DEFAULT_LOGGER.info &quot;!!!\n!!!(#{repo.path}) getting changed_paths for #{sha}\n!!!&quot;
+      begin
+        Timeout::timeout(30) do
+          previous_commit = repo.commit(sha).parents[0]
+          # RAILS_DEFAULT_LOGGER.info &quot;!!!\n!!!(again previous commit #{previous_commit.id}\n!!!&quot;
+          diffs = (number == 1) ? Commit.show(repo, sha) : Commit.diff(repo, previous_commit.id, sha)    
+          paths = diffs.collect do |diff|
+            next if diff.a_path.nil? # the repo itself
+            change = ChangedPath.new(self)
+            change.path = diff.a_path
+            change.action = &quot;M&quot;
+            change.action = &quot;A&quot; if diff.new_file
+            change.action = &quot;D&quot; if diff.deleted_file
+            # DON: Investigate whether this is always available or lazily executed -- most likely don't want all the
+            # diffs generated when we are just getting a list of revisions, but if it there we can make the diff view faster
+            change.diff = diff.diff
+            change
+          end.compact
+        end
+      rescue Timeout::Error
+        RAILS_DEFAULT_LOGGER.warn &quot;(#{repo.path}) parsing diff for #{sha} timed out&quot;
+        []
+      end
+    end
 
     def initialize(repository)
       @repository = repository</diff>
      <filename>lib/git_repository.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,11 +6,12 @@ TODO:
 Performance Enhancements:
 - Change calls within revisions to Commit.changelist (new function that returns just the --name-status array
 - Move actual diff to ChangePath.diff
-- Node.revision calls back into GitRepository.revision, which spins through a full changepath/diff.  This is called frequently in source browsing.  Rediculous!
+- Node.revision calls back into GitRepository.revision, which spins through a full changepath/diff.  This is called frequently in source browsing.  Ridiculous!
 
 Node:
-- Implement revisions
-- Implement previous_revision_node
+- Implement revisions (not needed) @done
+- Change revision_number to get the actual revision of the node, not the commit revision number @done
+- Implement previous_revision_node (not needed) @done
 
 Testing:
 - rewrite tests for git</diff>
      <filename>todo.taskpaper</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>a95f6638da61700e03b50f17d723fb96e781d598</id>
    </parent>
  </parents>
  <author>
    <name>Don Mullen</name>
    <email>don@thinkrelevance.com</email>
  </author>
  <url>http://github.com/donmullen/mingle_git/commit/6aad715f566c08cdc1ea1642bfc171192257f289</url>
  <id>6aad715f566c08cdc1ea1642bfc171192257f289</id>
  <committed-date>2008-08-08T14:51:37-07:00</committed-date>
  <authored-date>2008-08-08T14:51:37-07:00</authored-date>
  <message>node revision update and optimizations</message>
  <tree>5e8e1aaa4ea535791f16b2f67f1fb0af555d96c2</tree>
  <committer>
    <name>Don Mullen</name>
    <email>don@thinkrelevance.com</email>
  </committer>
</commit>
