diff --git a/reviewboard/hostingsvcs/googlecode.py b/reviewboard/hostingsvcs/googlecode.py
index 4f166331965d5723ccd58f59387cecf9cf601972..67b3623f78e8dc8c8d74cb2aadf264efb3fb5152 100644
--- a/reviewboard/hostingsvcs/googlecode.py
+++ b/reviewboard/hostingsvcs/googlecode.py
@@ -6,15 +6,19 @@ from collections import defaultdict
 
 from django import forms
 from django.conf.urls import patterns, url
-from django.http import HttpResponse
+from django.http import HttpResponse, HttpResponseBadRequest
+from django.template import RequestContext
+from django.template.loader import render_to_string
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.http import require_POST
 
-from reviewboard.admin.server import get_server_url
+from reviewboard.admin.server import build_server_url, get_server_url
 from reviewboard.hostingsvcs.forms import HostingServiceForm
 from reviewboard.hostingsvcs.hook_utils import (close_all_review_requests,
+                                                get_repository_for_hook,
                                                 get_review_request_id)
 from reviewboard.hostingsvcs.service import HostingService
+from reviewboard.site.urlresolvers import local_site_reverse
 
 
 class GoogleCodeForm(HostingServiceForm):
@@ -31,11 +35,12 @@ class GoogleCode(HostingService):
     supported_scmtools = ['Mercurial', 'Subversion']
     supports_repositories = True
     supports_bug_trackers = True
+    has_repository_hook_instructions = True
 
     repository_url_patterns = patterns(
         '',
 
-        url(r'^hooks/close-submitted/$',
+        url(r'^hooks/(?P<hooks_uuid>[a-z0-9]+)/close-submitted/$',
             'reviewboard.hostingsvcs.googlecode'
             '.post_receive_hook_close_submitted',
             name='googlecode-hooks-close-submitted'),
@@ -59,22 +64,44 @@ class GoogleCode(HostingService):
                         '%(googlecode_project_name)s/' \
                         'issues/detail?id=%%s'
 
+    def get_repository_hook_instructions(self, request, repository):
+        """Returns instructions for setting up incoming webhooks."""
+        webhook_endpoint_url = build_server_url(local_site_reverse(
+            'googlecode-hooks-close-submitted',
+            local_site=repository.local_site,
+            kwargs={
+                'repository_id': repository.pk,
+                'hosting_service_id': repository.hosting_account.service_name,
+                'hooks_uuid': repository.get_or_create_hooks_uuid(),
+            }))
+        add_webhook_url = (
+            'https://code.google.com/p/%s/adminSource'
+            % repository.extra_data['googlecode_project_name'])
+
+        return render_to_string(
+            'hostingsvcs/googlecode/repo_hook_instructions.html',
+            RequestContext(request, {
+                'repository': repository,
+                'server_url': get_server_url(),
+                'add_webhook_url': add_webhook_url,
+                'webhook_endpoint_url': webhook_endpoint_url,
+            }))
+
 
 @require_POST
 def post_receive_hook_close_submitted(request, local_site_name=None,
                                       repository_id=None,
-                                      hosting_service_id=None):
+                                      hosting_service_id=None,
+                                      hooks_uuid=None):
     """Closes review requests as submitted automatically after a push."""
+    repository = get_repository_for_hook(repository_id, hosting_service_id,
+                                         local_site_name, hooks_uuid)
+
     try:
         payload = json.loads(request.body)
-    except KeyError as e:
-        logging.error('There is no JSON payload in the POST request: %s', e,
-                      exc_info=1)
-        return HttpResponse(status=400)
     except ValueError as e:
-        logging.error('The payload is not in JSON format: %s', e,
-                      exc_info=1)
-        return HttpResponse(status=400)
+        logging.error('The payload is not in JSON format: %s', e, exc_info=1)
+        return HttpResponseBadRequest('Invalid payload format')
 
     server_url = get_server_url(request=request)
     review_request_id_to_commits_map = \
@@ -82,7 +109,7 @@ def post_receive_hook_close_submitted(request, local_site_name=None,
 
     if review_request_id_to_commits_map:
         close_all_review_requests(review_request_id_to_commits_map,
-                                  local_site_name, repository_id,
+                                  local_site_name, repository,
                                   hosting_service_id)
 
     return HttpResponse()
diff --git a/reviewboard/hostingsvcs/tests.py b/reviewboard/hostingsvcs/tests.py
index da46d5d492cb5d6ac10612794e246852df9aadd8..36bf2097ded0fbc33a1f70f989c6be80c3ea8b21 100644
--- a/reviewboard/hostingsvcs/tests.py
+++ b/reviewboard/hostingsvcs/tests.py
@@ -2017,9 +2017,11 @@ class GoogleCodeTests(ServiceTests):
             kwargs={
                 'repository_id': repository.pk,
                 'hosting_service_id': 'googlecode',
+                'hooks_uuid': repository.get_or_create_hooks_uuid(),
             })
 
-        self._post_commit_hook_payload(url, review_request)
+        response = self._post_commit_hook_payload(url, review_request)
+        self.assertEqual(response.status_code, 404)
 
         review_request = ReviewRequest.objects.get(pk=review_request.pk)
         self.assertTrue(review_request.public)
@@ -2042,9 +2044,11 @@ class GoogleCodeTests(ServiceTests):
             kwargs={
                 'repository_id': repository.pk,
                 'hosting_service_id': 'googlecode',
+                'hooks_uuid': repository.get_or_create_hooks_uuid(),
             })
 
-        self._post_commit_hook_payload(url, review_request)
+        response = self._post_commit_hook_payload(url, review_request)
+        self.assertEqual(response.status_code, 404)
 
         review_request = ReviewRequest.objects.get(pk=review_request.pk)
         self.assertTrue(review_request.public)
@@ -2055,23 +2059,55 @@ class GoogleCodeTests(ServiceTests):
     def test_close_submitted_hook_with_invalid_service_id(self):
         """Testing Google Code close_submitted hook with invalid hosting service ID
         """
-        repository = self.create_repository()
+        # We'll test against Bitbucket for this test.
+        account = self._get_hosting_account()
+        account.service_name = 'bitbucket'
+        account.save()
+        repository = self.create_repository(hosting_account=account)
 
         review_request = self.create_review_request(repository=repository,
                                                     publish=True)
         self.assertTrue(review_request.public)
         self.assertEqual(review_request.status, review_request.PENDING_REVIEW)
 
-        # We'll test against Bitbucket's hooks for this test.
         url = local_site_reverse(
-            'bitbucket-hooks-close-submitted',
+            'googlecode-hooks-close-submitted',
             kwargs={
                 'repository_id': repository.pk,
-                'hosting_service_id': 'bitbucket',
+                'hosting_service_id': 'googlecode',
                 'hooks_uuid': repository.get_or_create_hooks_uuid(),
             })
 
-        self._post_commit_hook_payload(url, review_request)
+        response = self._post_commit_hook_payload(url, review_request)
+        self.assertEqual(response.status_code, 404)
+
+        review_request = ReviewRequest.objects.get(pk=review_request.pk)
+        self.assertTrue(review_request.public)
+        self.assertEqual(review_request.status, review_request.PENDING_REVIEW)
+        self.assertEqual(review_request.changedescs.count(), 0)
+
+    @add_fixtures(['test_users', 'test_scmtools'])
+    def test_close_submitted_hook_with_invalid_hooks_uuid(self):
+        """Testing Google Code close_submitted hook with invalid hooks UUID"""
+        account = self._get_hosting_account()
+        account.save()
+        repository = self.create_repository(hosting_account=account)
+
+        review_request = self.create_review_request(repository=repository,
+                                                    publish=True)
+        self.assertTrue(review_request.public)
+        self.assertEqual(review_request.status, review_request.PENDING_REVIEW)
+
+        url = local_site_reverse(
+            'googlecode-hooks-close-submitted',
+            kwargs={
+                'repository_id': repository.pk,
+                'hosting_service_id': 'googlecode',
+                'hooks_uuid': 'abc123',
+            })
+
+        response = self._post_commit_hook_payload(url, review_request)
+        self.assertEqual(response.status_code, 404)
 
         review_request = ReviewRequest.objects.get(pk=review_request.pk)
         self.assertTrue(review_request.public)
@@ -2097,9 +2133,11 @@ class GoogleCodeTests(ServiceTests):
             kwargs={
                 'repository_id': repository.pk,
                 'hosting_service_id': 'googlecode',
+                'hooks_uuid': repository.get_or_create_hooks_uuid(),
             })
 
-        self._post_commit_hook_payload(url, review_request)
+        response = self._post_commit_hook_payload(url, review_request)
+        self.assertEqual(response.status_code, 200)
 
         review_request = ReviewRequest.objects.get(pk=review_request.pk)
         self.assertTrue(review_request.public)
@@ -2110,7 +2148,7 @@ class GoogleCodeTests(ServiceTests):
         self.assertEqual(changedesc.text, 'Pushed to master (1c44b46)')
 
     def _post_commit_hook_payload(self, url, review_request):
-        self.client.post(
+        return self.client.post(
             url,
             json.dumps({
                 # NOTE: This payload only contains the content we make
diff --git a/reviewboard/scmtools/forms.py b/reviewboard/scmtools/forms.py
index 7535de2e7855fe732ccd66dcf2ddc5d6ee27d66d..a03a9f72670add6b9c17cc69d179f8fe39ba4fdb 100644
--- a/reviewboard/scmtools/forms.py
+++ b/reviewboard/scmtools/forms.py
@@ -579,6 +579,7 @@ class RepositoryForm(forms.ModelForm):
                 ])
                 return
 
+        if hosting_account:
             # Flag that we've linked the account. If there are any
             # validation errors, and this flag is set, we tell the user
             # that we successfully linked and they don't have to do it
diff --git a/reviewboard/static/rb/css/admin.less b/reviewboard/static/rb/css/admin.less
index e6195d69e879848b1ffc3fc03d31beabee9cda4b..53ef4dd29194e1816e75708d0aa1be769ec719cc 100644
--- a/reviewboard/static/rb/css/admin.less
+++ b/reviewboard/static/rb/css/admin.less
@@ -1161,6 +1161,7 @@ table#change-history {
 
   pre {
     margin: 2em 1em;
+    .pre-wrap();
   }
 
   table.sample-fields {
diff --git a/reviewboard/templates/hostingsvcs/googlecode/repo_hook_instructions.html b/reviewboard/templates/hostingsvcs/googlecode/repo_hook_instructions.html
new file mode 100644
index 0000000000000000000000000000000000000000..983a5f833ac7fb83001984dbac611cc8eb2e4633
--- /dev/null
+++ b/reviewboard/templates/hostingsvcs/googlecode/repo_hook_instructions.html
@@ -0,0 +1,28 @@
+{% load i18n %}
+
+<p>
+{% blocktrans %}
+ Review Board supports closing review requests that are referenced in
+ commit messages for any changes pushed to this repository. These references
+ are in the form of:
+{% endblocktrans %}
+</p>
+<pre>Reviewed at {{server_url}}r/123/</pre>
+<p>
+ Or:
+</p>
+<pre>Review Request #123</pre>
+<p>
+{% blocktrans %}
+ To configure this,
+ <a href="{{add_webhook_url}}" target="_blank">fill in the post-commit webhook</a>
+ for your Google Code repository (toward the bottom of the page) with the following
+ URL:
+{% endblocktrans %}
+</p>
+<pre>{{webhook_endpoint_url}}</pre>
+<p>
+{% blocktrans %}
+ Then click <b>Save changes</b>. You're done!
+{% endblocktrans %}
+</p>
