diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d53b23bb246a21062a8ba529b29f1c4410a8022a..7e53b8fe5ff5ee37fd6b7198b28f47eb16427b1a 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -120,16 +120,6 @@ class ApplicationController < ActionController::Base
     end
   end
 
-  def load_refs
-    if params[:ref].blank?
-      @branch = params[:branch].blank? ? nil : params[:branch]
-      @tag = params[:tag].blank? ? nil : params[:tag]
-      @ref = @branch || @tag || @project.try(:default_branch) || Repository.default_ref
-    else
-      @ref = params[:ref]
-    end
-  end
-
   def render_404
     render file: File.join(Rails.root, "public", "404"), layout: false, status: "404"
   end
diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb
index 717912d9e92eb0b709b9f2ae149ff9244a2eea5f..5e10a1b6ee73c15ee470f20a28f1e080a6d89858 100644
--- a/app/controllers/commits_controller.rb
+++ b/app/controllers/commits_controller.rb
@@ -59,7 +59,7 @@ class CommitsController < ApplicationController
 
   def patch
     @commit = project.commit(params[:id])
-    
+
     send_data(
       @commit.to_patch,
       type: "text/plain",
@@ -67,4 +67,16 @@ class CommitsController < ApplicationController
       filename: (@commit.id.to_s + ".patch")
     )
   end
+
+  protected
+
+  def load_refs
+    if params[:ref].blank?
+      @branch = params[:branch].blank? ? nil : params[:branch]
+      @tag = params[:tag].blank? ? nil : params[:tag]
+      @ref = @branch || @tag || @project.try(:default_branch) || 'master'
+    else
+      @ref = params[:ref]
+    end
+  end
 end
diff --git a/app/models/project.rb b/app/models/project.rb
index a7735a421374ffe54835a8001384ea16cf51e2c9..fc18ad555288bb3f66b2d5dfdae498497aef12e5 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -187,7 +187,7 @@ end
 #  private_flag           :boolean(1)      default(TRUE), not null
 #  code                   :string(255)
 #  owner_id               :integer(4)
-#  default_branch         :string(255)     default("master"), not null
+#  default_branch         :string(255)
 #  issues_enabled         :boolean(1)      default(TRUE), not null
 #  wall_enabled           :boolean(1)      default(TRUE), not null
 #  merge_requests_enabled :boolean(1)      default(TRUE), not null
diff --git a/app/roles/push_observer.rb b/app/roles/push_observer.rb
index 1067404d5afab7596db92f5ed7593a851d7b6f07..947ed42345d494762cdf4deba278888c8e6c0f2b 100644
--- a/app/roles/push_observer.rb
+++ b/app/roles/push_observer.rb
@@ -1,3 +1,6 @@
+# Includes methods for handling Git Push events
+#
+# Triggered by PostReceive job
 module PushObserver
   def observe_push(oldrev, newrev, ref, user)
     data = post_receive_data(oldrev, newrev, ref, user)
@@ -84,11 +87,10 @@ module PushObserver
     data
   end
 
-
-  # This method will be called after each post receive
-  # and only if user present in gitlab.
-  # All callbacks for post receive should be placed here
+  # This method will be called after each post receive and only if the provided
+  # user is present in GitLab.
   #
+  # All callbacks for post receive should be placed here.
   def trigger_post_receive(oldrev, newrev, ref, user)
     # Create push event
     self.observe_push(oldrev, newrev, ref, user)
@@ -101,5 +103,11 @@ module PushObserver
 
     # Create satellite
     self.satellite.create unless self.satellite.exists?
+
+    # Discover the default branch, but only if it hasn't already been set to
+    # something else
+    if default_branch.nil?
+      update_attributes(default_branch: discover_default_branch)
+    end
   end
 end
diff --git a/app/roles/repository.rb b/app/roles/repository.rb
index 5f6c35414e1a5ecc0bc5c790edb0f59fd7509665..a77de4ad5f012302f23e6e9c823d3d68bb99bb0d 100644
--- a/app/roles/repository.rb
+++ b/app/roles/repository.rb
@@ -94,6 +94,24 @@ module Repository
     end.sort_by(&:name)
   end
 
+  # Discovers the default branch based on the repository's available branches
+  #
+  # - If no branches are present, returns nil
+  # - If one branch is present, returns its name
+  # - If two or more branches are present, returns the one that has a name
+  #   matching root_ref (default_branch or 'master' if default_branch is nil)
+  def discover_default_branch
+    branches = heads.collect(&:name)
+
+    if branches.length == 0
+      nil
+    elsif branches.length == 1
+      branches.first
+    else
+      branches.select { |v| v == root_ref }.first
+    end
+  end
+
   def has_commits?
     !!commit
   end
@@ -102,7 +120,7 @@ module Repository
     default_branch || "master"
   end
 
-  def root_ref? branch
+  def root_ref?(branch)
     root_ref == branch
   end
 
@@ -111,7 +129,7 @@ module Repository
   # Already packed repo archives stored at
   # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
   #
-  def archive_repo ref
+  def archive_repo(ref)
     ref = ref || self.root_ref
     commit = self.commit(ref)
     return nil unless commit
@@ -138,6 +156,6 @@ module Repository
   end
 
   def http_url_to_repo
-    http_url = [Gitlab.config.url, "/", path, ".git"].join()
+    http_url = [Gitlab.config.url, "/", path, ".git"].join('')
   end
 end
diff --git a/db/migrate/20120905043334_set_default_branch_default_to_nil.rb b/db/migrate/20120905043334_set_default_branch_default_to_nil.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f5956fe875184473481fe8673e57a9bab967c95e
--- /dev/null
+++ b/db/migrate/20120905043334_set_default_branch_default_to_nil.rb
@@ -0,0 +1,12 @@
+class SetDefaultBranchDefaultToNil < ActiveRecord::Migration
+  def up
+    # Set the default_branch to allow nil, and default it to nil
+    change_column_null(:projects, :default_branch, true)
+    change_column_default(:projects, :default_branch, nil)
+  end
+
+  def down
+    change_column_null(:projects, :default_branch, false)
+    change_column_default(:projects, :default_branch, 'master')
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 46461e44aad59d13087ad2fcd9a62075e3e56d01..00bb55234af668359c6f26365cbdb68a212644fe 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20120729131232) do
+ActiveRecord::Schema.define(:version => 20120905043334) do
 
   create_table "events", :force => true do |t|
     t.string   "target_type"
@@ -98,16 +98,16 @@ ActiveRecord::Schema.define(:version => 20120729131232) do
     t.string   "name"
     t.string   "path"
     t.text     "description"
-    t.datetime "created_at",                                   :null => false
-    t.datetime "updated_at",                                   :null => false
-    t.boolean  "private_flag",           :default => true,     :null => false
+    t.datetime "created_at",                               :null => false
+    t.datetime "updated_at",                               :null => false
+    t.boolean  "private_flag",           :default => true, :null => false
     t.string   "code"
     t.integer  "owner_id"
-    t.string   "default_branch",         :default => "master", :null => false
-    t.boolean  "issues_enabled",         :default => true,     :null => false
-    t.boolean  "wall_enabled",           :default => true,     :null => false
-    t.boolean  "merge_requests_enabled", :default => true,     :null => false
-    t.boolean  "wiki_enabled",           :default => true,     :null => false
+    t.string   "default_branch"
+    t.boolean  "issues_enabled",         :default => true, :null => false
+    t.boolean  "wall_enabled",           :default => true, :null => false
+    t.boolean  "merge_requests_enabled", :default => true, :null => false
+    t.boolean  "wiki_enabled",           :default => true, :null => false
   end
 
   create_table "protected_branches", :force => true do |t|
diff --git a/spec/roles/repository_spec.rb b/spec/roles/repository_spec.rb
index 62aecc1341fcd413a5b74f0d465727c9da632ca1..0fda57a3e271aae6d7b7d7894f0e10143bfe09c9 100644
--- a/spec/roles/repository_spec.rb
+++ b/spec/roles/repository_spec.rb
@@ -19,4 +19,54 @@ describe Project, "Repository" do
       project.should_not be_empty_repo
     end
   end
+
+  describe "#discover_default_branch" do
+    let(:master) { double(name: 'master') }
+    let(:stable) { double(name: 'stable') }
+
+    it "returns 'master' when master exists" do
+      project.should_receive(:heads).and_return([stable, master])
+      project.discover_default_branch.should == 'master'
+    end
+
+    it "returns non-master when master exists but default branch is set to something else" do
+      project.default_branch = 'stable'
+      project.should_receive(:heads).and_return([stable, master])
+      project.discover_default_branch.should == 'stable'
+    end
+
+    it "returns a non-master branch when only one exists" do
+      project.should_receive(:heads).and_return([stable])
+      project.discover_default_branch.should == 'stable'
+    end
+
+    it "returns nil when no branch exists" do
+      project.should_receive(:heads).and_return([])
+      project.discover_default_branch.should be_nil
+    end
+  end
+
+  describe "#root_ref" do
+    it "returns default_branch when set" do
+      project.default_branch = 'stable'
+      project.root_ref.should == 'stable'
+    end
+
+    it "returns 'master' when default_branch is nil" do
+      project.default_branch = nil
+      project.root_ref.should == 'master'
+    end
+  end
+
+  describe "#root_ref?" do
+    it "returns true when branch is root_ref" do
+      project.default_branch = 'stable'
+      project.root_ref?('stable').should be_true
+    end
+
+    it "returns false when branch is not root_ref" do
+      project.default_branch = nil
+      project.root_ref?('stable').should be_false
+    end
+  end
 end