diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 385bfa7..3f34830 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -43,6 +43,8 @@ class IssuesController < ApplicationController
   include AttachmentsHelper
   helper :queries
   include QueriesHelper
+  helper :repositories
+  include RepositoriesHelper
   helper :sort
   include SortHelper
   include IssuesHelper
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index eecbc5b..cfcbe53 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -118,8 +118,10 @@ module ApplicationHelper
   # * :text - Link text (default to the formatted revision)
   def link_to_revision(revision, project, options={})
     text = options.delete(:text) || format_revision(revision)
+    rev = revision.respond_to?(:identifier) ? revision.identifier : revision
 
-    link_to(text, {:controller => 'repositories', :action => 'revision', :id => project, :rev => revision}, :title => l(:label_revision_id, revision))
+    link_to(text, {:controller => 'repositories', :action => 'revision', :id => project, :rev => rev},
+            :title => l(:label_revision_id, format_revision(revision)))
   end
   
   def link_to_project(project, options={})
@@ -665,7 +667,7 @@ module ApplicationHelper
             end
           when 'commit'
             if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
-              link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
+              link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.identifier},
                                            :class => 'changeset',
                                            :title => truncate_single_line(changeset.comments, :length => 100)
             end
diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb
index 9596287..0bfbfab 100644
--- a/app/helpers/repositories_helper.rb
+++ b/app/helpers/repositories_helper.rb
@@ -18,8 +18,12 @@
 require 'iconv'
 
 module RepositoriesHelper
-  def format_revision(txt)
-    txt.to_s[0,8]
+  def format_revision(revision)
+    if revision.respond_to? :format_identifier
+      revision.format_identifier
+    else
+      revision.to_s[0,8]
+    end
   end
   
   def truncate_at_line_break(text, length = 255)
@@ -87,7 +91,7 @@ module RepositoriesHelper
                              :action => 'show',
                              :id => @project,
                              :path => path_param,
-                             :rev => @changeset.revision)
+                             :rev => @changeset.identifier)
         output << "<li class='#{style}'>#{text}</li>"
         output << render_changes_tree(s)
       elsif c = tree[file][:c]
@@ -97,13 +101,13 @@ module RepositoriesHelper
                              :action => 'entry',
                              :id => @project,
                              :path => path_param,
-                             :rev => @changeset.revision) unless c.action == 'D'
+                             :rev => @changeset.identifier) unless c.action == 'D'
         text << " - #{c.revision}" unless c.revision.blank?
         text << ' (' + link_to('diff', :controller => 'repositories',
                                        :action => 'diff',
                                        :id => @project,
                                        :path => path_param,
-                                       :rev => @changeset.revision) + ') ' if c.action == 'M'
+                                       :rev => @changeset.identifier) + ') ' if c.action == 'M'
         text << ' ' + content_tag('span', c.from_path, :class => 'copied-from') unless c.from_path.blank?
         output << "<li class='#{style}'>#{text}</li>"
       end
diff --git a/app/models/changeset.rb b/app/models/changeset.rb
index 063a4a4..fa03b37 100644
--- a/app/models/changeset.rb
+++ b/app/models/changeset.rb
@@ -23,10 +23,10 @@ class Changeset < ActiveRecord::Base
   has_many :changes, :dependent => :delete_all
   has_and_belongs_to_many :issues
 
-  acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.revision}" + (o.short_comments.blank? ? '' : (': ' + o.short_comments))},
+  acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.format_identifier}" + (o.short_comments.blank? ? '' : (': ' + o.short_comments))},
                 :description => :long_comments,
                 :datetime => :committed_on,
-                :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :rev => o.revision}}
+                :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :rev => o.identifier}}
                 
   acts_as_searchable :columns => 'comments',
                      :include => {:repository => :project},
@@ -48,6 +48,33 @@ class Changeset < ActiveRecord::Base
     write_attribute :revision, (r.nil? ? nil : r.to_s)
   end
   
+  # Returns the identifier of this changeset.
+  # e.g. revision number for centralized system; hash id for DVCS
+  def identifier
+    ## Temporary comment out.
+    ## Because All DVCS need to implement find_changeset_by_name(name).
+    # (scmid || revision).to_s
+    revision.to_s
+  end
+
+  # Returns the readable identifier; first 8 chars of identifier by default
+  def format_identifier
+    if repository.class.respond_to? :format_changeset_identifier
+      repository.class.format_changeset_identifier self
+    else
+      identifier[0, 8]
+    end
+  end
+
+  # Returns the identifier for wiki, "rN" or "commit:ABCDEF"
+  def format_wiki_identifier
+    if scmid  # hash-like
+      "commit:#{scmid}"
+    else  # numeric
+      "r#{revision}"
+    end
+  end
+  
   def comments=(comment)
     write_attribute(:comments, Changeset.normalize_comments(comment))
   end
@@ -108,11 +135,8 @@ class Changeset < ActiveRecord::Base
           issue.reload
           # don't change the status is the issue is closed
           next if issue.status.is_closed?
-          csettext = "r#{self.revision}"
-          if self.scmid && (! (csettext =~ /^r[0-9]+$/))
-            csettext = "commit:\"#{self.scmid}\""
-          end
-          journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, csettext))
+          journal = issue.init_journal(user || User.anonymous,
+                                       ll(Setting.default_language, :text_status_changed_by_changeset, format_wiki_identifier))
           issue.status = fix_status
           unless Setting.commit_fix_done_ratio.blank?
             issue.done_ratio = Setting.commit_fix_done_ratio.to_i
diff --git a/app/models/repository.rb b/app/models/repository.rb
index dee705c..7f1ca73 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -172,7 +172,11 @@ class Repository < ActiveRecord::Base
   def self.fetch_changesets
     Project.active.has_module(:repository).find(:all, :include => :repository).each do |project|
       if project.repository
+        begin
         project.repository.fetch_changesets
+        rescue Redmine::Scm::Adapters::CommandFailed => e
+          logger.error "Repository: error during fetching changesets: #{e.message}"
+        end
       end
     end
   end
diff --git a/app/views/issues/_changesets.rhtml b/app/views/issues/_changesets.rhtml
index 52cd60f..d5a2928 100644
--- a/app/views/issues/_changesets.rhtml
+++ b/app/views/issues/_changesets.rhtml
@@ -1,7 +1,7 @@
 <% changesets.each do |changeset| %>
     <div class="changeset <%= cycle('odd', 'even') %>">
-    <p><%= link_to("#{l(:label_revision)} #{changeset.revision}",
-                :controller => 'repositories', :action => 'revision', :id => changeset.project, :rev => changeset.revision) %><br />
+    <p><%= link_to_revision(changeset, changeset.project,
+                            :text => "#{l(:label_revision)} #{changeset.format_identifier}") %><br />
         <span class="author"><%= authoring(changeset.committed_on, changeset.author) %></span></p>
     <div class="changeset-changes">
         <%= textilizable(changeset, :comments) %>
diff --git a/app/views/repositories/_dir_list_content.rhtml b/app/views/repositories/_dir_list_content.rhtml
index c5bd53e..66574f1 100644
--- a/app/views/repositories/_dir_list_content.rhtml
+++ b/app/views/repositories/_dir_list_content.rhtml
@@ -17,7 +17,7 @@
 </td>
 <td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
 <% changeset = @project.repository.changesets.find_by_revision(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %>
-<td class="revision"><%= link_to_revision(changeset.revision, @project) if changeset %></td>
+<td class="revision"><%= link_to_revision(changeset, @project) if changeset %></td>
 <td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
 <td class="author"><%= changeset.nil? ? h(entry.lastrev.author.to_s.split('<').first) : changeset.author if entry.lastrev %></td>
 <td class="comments"><%=h truncate(changeset.comments, :length => 50) unless changeset.nil? %></td>
diff --git a/app/views/repositories/_revisions.rhtml b/app/views/repositories/_revisions.rhtml
index 26fb5b6..92c6fb5 100644
--- a/app/views/repositories/_revisions.rhtml
+++ b/app/views/repositories/_revisions.rhtml
@@ -13,9 +13,9 @@
 <% line_num = 1 %>
 <% revisions.each do |changeset| %>
 <tr class="changeset <%= cycle 'odd', 'even' %>">
-<td class="id"><%= link_to_revision(changeset.revision, project) %></td>
-<td class="checkbox"><%= radio_button_tag('rev', changeset.revision, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
-<td class="checkbox"><%= radio_button_tag('rev_to', changeset.revision, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
+<td class="id"><%= link_to_revision(changeset, project) %></td>
+<td class="checkbox"><%= radio_button_tag('rev', changeset.identifier, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
+<td class="checkbox"><%= radio_button_tag('rev_to', changeset.identifier, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
 <td class="committed_on"><%= format_time(changeset.committed_on) %></td>
 <td class="author"><%=h changeset.author %></td>
 <td class="comments"><%= textilizable(truncate_at_line_break(changeset.comments)) %></td>
diff --git a/app/views/repositories/annotate.rhtml b/app/views/repositories/annotate.rhtml
index a18e9bb..4985071 100644
--- a/app/views/repositories/annotate.rhtml
+++ b/app/views/repositories/annotate.rhtml
@@ -19,7 +19,7 @@
     <tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
       <th class="line-num" id="L<%= line_num %>"><a href="#L<%= line_num %>"><%= line_num %></a></th>
       <td class="revision">
-      <%= (revision.identifier ? link_to(format_revision(revision.identifier), :action => 'revision', :id => @project, :rev => revision.identifier) : format_revision(revision.revision)) if revision %></td>
+      <%= (revision.identifier ? link_to_revision(revision, @project) : format_revision(revision)) if revision %></td>
       <td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
       <td class="line-code"><pre><%= line %></pre></td>
     </tr>
diff --git a/app/views/repositories/revision.rhtml b/app/views/repositories/revision.rhtml
index 92597df..1f3f611 100644
--- a/app/views/repositories/revision.rhtml
+++ b/app/views/repositories/revision.rhtml
@@ -1,25 +1,25 @@
 <div class="contextual">
   &#171;
   <% unless @changeset.previous.nil? -%>
-    <%= link_to_revision(@changeset.previous.revision, @project, :text => l(:label_previous)) %>
+    <%= link_to_revision(@changeset.previous, @project, :text => l(:label_previous)) %>
   <% else -%>
     <%= l(:label_previous) %>
   <% end -%>
 |
   <% unless @changeset.next.nil? -%>
-    <%= link_to_revision(@changeset.next.revision, @project, :text => l(:label_next)) %>
+    <%= link_to_revision(@changeset.next, @project, :text => l(:label_next)) %>
   <% else -%>
     <%= l(:label_next) %>
   <% end -%>
   &#187;&nbsp;
 
   <% form_tag({:controller => 'repositories', :action => 'revision', :id => @project, :rev => nil}, :method => :get) do %>
-    <%= text_field_tag 'rev', @rev[0,8], :size => 8 %>
+    <%= text_field_tag 'rev', @rev, :size => 8 %>
     <%= submit_tag 'OK', :name => nil %>
   <% end %>
 </div>
 
-<h2><%= l(:label_revision) %> <%= format_revision(@changeset.revision) %></h2>
+<h2><%= l(:label_revision) %> <%= format_revision(@changeset) %></h2>
 
 <p><% if @changeset.scmid %>ID: <%= @changeset.scmid %><br /><% end %>
 <span class="author"><%= authoring(@changeset.committed_on, @changeset.author) %></span></p>
@@ -45,7 +45,7 @@
 <li class="change change-D"><%= l(:label_deleted) %></li>
 </ul>
 
-<p><%= link_to(l(:label_view_diff), :action => 'diff', :id => @project, :path => "", :rev => @changeset.revision) if @changeset.changes.any? %></p>
+<p><%= link_to(l(:label_view_diff), :action => 'diff', :id => @project, :path => "", :rev => @changeset.identifier) if @changeset.changes.any? %></p>
 
 <div class="changeset-changes">
 <%= render_changeset_changes %>
diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb
index a3ca61e..3beb8f1 100644
--- a/lib/redmine/scm/adapters/abstract_adapter.rb
+++ b/lib/redmine/scm/adapters/abstract_adapter.rb
@@ -271,7 +271,8 @@ module Redmine
       end
       
       class Revision
-        attr_accessor :identifier, :scmid, :name, :author, :time, :message, :paths, :revision, :branch
+        attr_accessor :scmid, :name, :author, :time, :message, :paths, :revision, :branch
+        attr_writer :identifier
 
         def initialize(attributes={})
           self.identifier = attributes[:identifier]
@@ -285,6 +286,17 @@ module Redmine
           self.branch = attributes[:branch]
         end
 
+        # Returns the identifier of this revision.
+        # e.g. revision number for centralized system; hash id for DVCS
+        def identifier
+          (@identifier || scmid || revision).to_s
+        end
+
+        # Returns the readable identifier; first 8 chars of identifier.
+        def format_identifier
+          identifier[0, 8]
+        end
+
         def save(repo)
           Changeset.transaction do
             changeset = Changeset.new(
