diff --git a/CHANGELOG b/CHANGELOG
index f1346885ab48d055a159202c9570bf13473a2f56..7ab7825c7d8aa845d2c5d5a1b4c50a29cbbbf97b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,7 +11,7 @@ v 7.8.0
   - 
   - 
   - 
-  - 
+  - Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger)
   - 
   - 
   - 
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 92f601282e0139bef30574dacbb3982568f44723..8d97965935e4da3de711126906e4d888b15a87b6 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -77,7 +77,7 @@ production: &base
     # This happens when the commit is pushed or merged into the default branch of a project.
     # When not specified the default issue_closing_pattern as specified below will be used.
     # Tip: you can test your closing pattern at http://rubular.com
-    # issue_closing_pattern: '([Cc]lose[sd]|[Ff]ixe[sd]) #(\d+)'
+    # issue_closing_pattern: '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)'
 
     ## Default project features settings
     default_projects_features:
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index cdb958aa6a6de1f6383d83b46777c3625c41e6af..1ec842761ff4482597703fb07c3438521d251ac4 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -109,7 +109,7 @@ Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].
 Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil?
 Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], [])
 Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil?
-Settings.gitlab['issue_closing_pattern'] = '([Cc]lose[sd]|[Ff]ixe[sd]) #(\d+)' if Settings.gitlab['issue_closing_pattern'].nil?
+Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil?
 Settings.gitlab['default_projects_features'] ||= {}
 Settings.gitlab['webhook_timeout'] ||= 10
 Settings.gitlab.default_projects_features['issues']         = true if Settings.gitlab.default_projects_features['issues'].nil?
diff --git a/lib/gitlab/closing_issue_extractor.rb b/lib/gitlab/closing_issue_extractor.rb
index 401e6e047b16115f61a00901daac460e282ac4bd..a9fd59f03d92bbb1869b1a8bb6ef454896acb84d 100644
--- a/lib/gitlab/closing_issue_extractor.rb
+++ b/lib/gitlab/closing_issue_extractor.rb
@@ -3,14 +3,19 @@ module Gitlab
     ISSUE_CLOSING_REGEX = Regexp.new(Gitlab.config.gitlab.issue_closing_pattern)
 
     def self.closed_by_message_in_project(message, project)
-      md = ISSUE_CLOSING_REGEX.match(message)
-      if md
-        extractor = Gitlab::ReferenceExtractor.new
-        extractor.analyze(md[0], project)
-        extractor.issues_for(project)
-      else
-        []
+      issues = []
+
+      unless message.nil?
+        md = message.scan(ISSUE_CLOSING_REGEX)
+
+        md.each do |ref|
+          extractor = Gitlab::ReferenceExtractor.new
+          extractor.analyze(ref[0], project)
+          issues += extractor.issues_for(project)
+        end
       end
+
+      issues.uniq
     end
   end
 end
diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..867455daf23a6ee1c272b4ddc8fcdbb5d1a830e9
--- /dev/null
+++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb
@@ -0,0 +1,84 @@
+require 'spec_helper'
+
+describe Gitlab::ClosingIssueExtractor do
+  let(:project) { create(:project) }
+  let(:issue) { create(:issue, project: project) }
+  let(:iid1) { issue.iid }
+
+  describe :closed_by_message_in_project do
+    context 'with a single reference' do
+      it do
+        message = "Awesome commit (Closes ##{iid1})"
+        subject.closed_by_message_in_project(message, project).should == [issue]
+      end
+
+      it do
+        message = "Awesome commit (closes ##{iid1})"
+        subject.closed_by_message_in_project(message, project).should == [issue]
+      end
+
+      it do
+        message = "Closed ##{iid1}"
+        subject.closed_by_message_in_project(message, project).should == [issue]
+      end
+
+      it do
+        message = "closed ##{iid1}"
+        subject.closed_by_message_in_project(message, project).should == [issue]
+      end
+
+      it do
+        message = "Awesome commit (fixes ##{iid1})"
+        subject.closed_by_message_in_project(message, project).should == [issue]
+      end
+
+      it do
+        message = "Awesome commit (fix ##{iid1})"
+        subject.closed_by_message_in_project(message, project).should == [issue]
+      end
+    end
+
+    context 'with multiple references' do
+      let(:other_issue) { create(:issue, project: project) }
+      let(:third_issue) { create(:issue, project: project) }
+      let(:iid2) { other_issue.iid }
+      let(:iid3) { third_issue.iid }
+
+      it 'fetches issues in single line message' do
+        message = "Closes ##{iid1} and fix ##{iid2}"
+
+        subject.closed_by_message_in_project(message, project).
+            should == [issue, other_issue]
+      end
+
+      it 'fetches comma-separated issues references in single line message' do
+        message = "Closes ##{iid1}, closes ##{iid2}"
+
+        subject.closed_by_message_in_project(message, project).
+            should == [issue, other_issue]
+      end
+
+      it 'fetches comma-separated issues numbers in single line message' do
+        message = "Closes ##{iid1}, ##{iid2} and ##{iid3}"
+
+        subject.closed_by_message_in_project(message, project).
+            should == [issue, other_issue, third_issue]
+      end
+
+      it 'fetches issues in multi-line message' do
+        message = "Awesome commit (closes ##{iid1})\nAlso fixes ##{iid2}"
+
+        subject.closed_by_message_in_project(message, project).
+            should == [issue, other_issue]
+      end
+
+      it 'fetches issues in hybrid message' do
+        message = "Awesome commit (closes ##{iid1})\n"\
+                  "Also fixing issues ##{iid2}, ##{iid3} and #4"
+
+        subject.closed_by_message_in_project(message, project).
+            should == [issue, other_issue, third_issue]
+      end
+    end
+  end
+end
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index a6ec44da4be170a709341991f3c7b3c0e24c8bd0..7a2a7a4ce9b8e6ad10e3fc7e79a55973c620fece 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -57,16 +57,12 @@ eos
     let(:other_issue) { create :issue, project: other_project }
 
     it 'detects issues that this commit is marked as closing' do
-      stub_const('Gitlab::ClosingIssueExtractor::ISSUE_CLOSING_REGEX',
-                 /Fixes #\d+/)
       commit.stub(safe_message: "Fixes ##{issue.iid}")
       commit.closes_issues(project).should == [issue]
     end
 
     it 'does not detect issues from other projects' do
       ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}"
-      stub_const('Gitlab::ClosingIssueExtractor::ISSUE_CLOSING_REGEX',
-                 /^([Cc]loses|[Ff]ixes)/)
       commit.stub(safe_message: "Fixes #{ext_ref}")
       commit.closes_issues(project).should be_empty
     end