diff --git a/lib/datasource/gitlab-tags/index.spec.ts b/lib/datasource/gitlab-tags/index.spec.ts
index 0f468cf8a7db6cf5843d8eac671b40fbb9a181e3..1c7ae2c8ba7ca7beda04200b99fd33e52a3108f1 100644
--- a/lib/datasource/gitlab-tags/index.spec.ts
+++ b/lib/datasource/gitlab-tags/index.spec.ts
@@ -1,4 +1,4 @@
-import { getPkgReleases } from '..';
+import { getDigest, getPkgReleases } from '..';
 import * as httpMock from '../../../test/http-mock';
 import { id as datasource } from '.';
 
@@ -76,4 +76,75 @@ describe('datasource/gitlab-tags/index', () => {
       expect(res.releases).toHaveLength(2);
     });
   });
+
+  describe('getDigest', () => {
+    it('returns commits from gitlab installation', async () => {
+      const digest = 'abcd00001234';
+      const body = [
+        {
+          id: digest,
+        },
+      ];
+      httpMock
+        .scope('https://gitlab.company.com')
+        .get('/api/v4/projects/some%2Fdep2/repository/commits?per_page=1')
+        .reply(200, body);
+      const res = await getDigest({
+        datasource,
+        registryUrls: ['https://gitlab.company.com/api/v4/'],
+        depName: 'some/dep2',
+      });
+      expect(res).toBe(digest);
+    });
+
+    it('returns commits from gitlab installation for a specific branch', async () => {
+      const digest = 'abcd00001234';
+      const body = {
+        id: digest,
+      };
+      httpMock
+        .scope('https://gitlab.company.com')
+        .get('/api/v4/projects/some%2Fdep2/repository/commits/branch')
+        .reply(200, body);
+      const res = await getDigest(
+        {
+          datasource,
+          registryUrls: ['https://gitlab.company.com/api/v4/'],
+          depName: 'some/dep2',
+        },
+        'branch'
+      );
+      expect(res).toBe(digest);
+    });
+
+    it('returns null from gitlab installation with no commits', async () => {
+      const body = [];
+      httpMock
+        .scope('https://gitlab.company.com')
+        .get('/api/v4/projects/some%2Fdep2/repository/commits?per_page=1')
+        .reply(200, body);
+      const res = await getDigest({
+        datasource,
+        registryUrls: ['https://gitlab.company.com/api/v4/'],
+        depName: 'some/dep2',
+      });
+      expect(res).toBeNull();
+    });
+
+    it('returns null from gitlab installation with unknown branch', async () => {
+      httpMock
+        .scope('https://gitlab.company.com')
+        .get('/api/v4/projects/some%2Fdep2/repository/commits/unknown-branch')
+        .reply(404, null);
+      const res = await getDigest(
+        {
+          datasource,
+          registryUrls: ['https://gitlab.company.com/api/v4/'],
+          depName: 'some/dep2',
+        },
+        'unknown-branch'
+      );
+      expect(res).toBeNull();
+    });
+  });
 });
diff --git a/lib/datasource/gitlab-tags/index.ts b/lib/datasource/gitlab-tags/index.ts
index b7c75fafcad5297834d416a32c083689559cb96e..7f7f234b0403f75dec9303fb5c072bcad133bd95 100644
--- a/lib/datasource/gitlab-tags/index.ts
+++ b/lib/datasource/gitlab-tags/index.ts
@@ -1,8 +1,9 @@
+import { logger } from '../../logger';
 import * as packageCache from '../../util/cache/package';
 import { GitlabHttp } from '../../util/http/gitlab';
 import { joinUrlParts } from '../../util/url';
-import type { GetReleasesConfig, ReleaseResult } from '../types';
-import type { GitlabTag } from './types';
+import type { DigestConfig, GetReleasesConfig, ReleaseResult } from '../types';
+import type { GitlabCommit, GitlabTag } from './types';
 import { defaultRegistryUrl, getDepHost, getSourceUrl } from './util';
 
 export const id = 'gitlab-tags';
@@ -14,8 +15,7 @@ export const registryStrategy = 'first';
 
 const cacheNamespace = 'datasource-gitlab';
 
-function getCacheKey(depHost: string, repo: string): string {
-  const type = 'tags';
+function getCacheKey(depHost: string, repo: string, type = 'tags'): string {
   return `${depHost}:${repo}:${type}`;
 }
 
@@ -69,3 +69,68 @@ export async function getReleases({
   );
   return dependency;
 }
+
+/**
+ * gitlab.getDigest
+ *
+ * This function will simply return the latest commit hash for the configured repository.
+ */
+export async function getDigest(
+  { lookupName: repo, registryUrl }: Partial<DigestConfig>,
+  newValue?: string
+): Promise<string | null> {
+  const depHost = getDepHost(registryUrl);
+
+  const cachedResult = await packageCache.get<string>(
+    cacheNamespace,
+    getCacheKey(depHost, repo, 'commit')
+  );
+  // istanbul ignore if
+  if (cachedResult) {
+    return cachedResult;
+  }
+
+  const urlEncodedRepo = encodeURIComponent(repo);
+  let digest: string;
+
+  try {
+    if (newValue) {
+      const url = joinUrlParts(
+        depHost,
+        `api/v4/projects`,
+        urlEncodedRepo,
+        `repository/commits/`,
+        newValue
+      );
+      const gitlabCommits = await gitlabApi.getJson<GitlabCommit>(url);
+      digest = gitlabCommits.body.id;
+    } else {
+      const url = joinUrlParts(
+        depHost,
+        `api/v4/projects`,
+        urlEncodedRepo,
+        `repository/commits?per_page=1`
+      );
+      const gitlabCommits = await gitlabApi.getJson<GitlabCommit[]>(url);
+      digest = gitlabCommits.body[0].id;
+    }
+  } catch (err) {
+    logger.debug(
+      { gitlabRepo: repo, err, registryUrl },
+      'Error getting latest commit from Gitlab repo'
+    );
+  }
+
+  if (!digest) {
+    return null;
+  }
+
+  const cacheMinutes = 10;
+  await packageCache.set(
+    cacheNamespace,
+    getCacheKey(registryUrl, repo, 'commit'),
+    digest,
+    cacheMinutes
+  );
+  return digest;
+}
diff --git a/lib/datasource/gitlab-tags/types.ts b/lib/datasource/gitlab-tags/types.ts
index 47d6ee66bda8bcb4492d6c72766f08ecf1cab5d5..3664fd7106bbba318a96528ec0e00de03a647016 100644
--- a/lib/datasource/gitlab-tags/types.ts
+++ b/lib/datasource/gitlab-tags/types.ts
@@ -4,3 +4,7 @@ export type GitlabTag = {
     created_at?: string;
   };
 };
+
+export type GitlabCommit = {
+  id: string;
+};
diff --git a/lib/datasource/go/__snapshots__/digest.spec.ts.snap b/lib/datasource/go/__snapshots__/digest.spec.ts.snap
index ca66566f8f16b01da298224d515af137d556b97a..15c72755c5fa856f930d76be4ee4399fa0af2d22 100644
--- a/lib/datasource/go/__snapshots__/digest.spec.ts.snap
+++ b/lib/datasource/go/__snapshots__/digest.spec.ts.snap
@@ -1,19 +1,5 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`datasource/go/digest getDigest gitlab digest is not supported at the moment 1`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept-encoding": "gzip, deflate, br",
-      "host": "gitlab.com",
-      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
-    },
-    "method": "GET",
-    "url": "https://gitlab.com/golang/text?go-get=1",
-  },
-]
-`;
-
 exports[`datasource/go/digest getDigest returns digest 1`] = `
 Array [
   Object {
diff --git a/lib/datasource/go/digest.spec.ts b/lib/datasource/go/digest.spec.ts
index 1439970baa663f6971d69e38d5d71c0175416fba..88acefd298f704a9d3247bf5e2df4e456a490a3d 100644
--- a/lib/datasource/go/digest.spec.ts
+++ b/lib/datasource/go/digest.spec.ts
@@ -1,5 +1,5 @@
 import * as httpMock from '../../../test/http-mock';
-import { mocked } from '../../../test/util';
+import { loadFixture, mocked } from '../../../test/util';
 import * as _hostRules from '../../util/host-rules';
 import { getDigest } from '.';
 
@@ -49,17 +49,36 @@ describe('datasource/go/digest', () => {
       expect(res).toBeNull();
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
-    it('gitlab digest is not supported at the moment', async () => {
+    it('supports gitlab digest', async () => {
       httpMock
         .scope('https://gitlab.com/')
-        .get('/golang/text?go-get=1')
-        .reply(200, '');
+        .get('/group/subgroup?go-get=1')
+        .reply(200, loadFixture('go-get-gitlab.html'));
+      httpMock
+        .scope('https://gitlab.com/')
+        .get('/api/v4/projects/group%2Fsubgroup/repository/commits?per_page=1')
+        .reply(200, [{ id: 'abcdefabcdefabcdefabcdef' }]);
       const res = await getDigest(
-        { lookupName: 'gitlab.com/golang/text' },
+        { lookupName: 'gitlab.com/group/subgroup' },
         null
       );
-      expect(res).toBeNull();
-      expect(httpMock.getTrace()).toMatchSnapshot();
+      expect(res).toBe('abcdefabcdefabcdefabcdef');
+    });
+    it('supports gitlab digest with a specific branch', async () => {
+      const branch = 'some-branch';
+      httpMock
+        .scope('https://gitlab.com/')
+        .get('/group/subgroup?go-get=1')
+        .reply(200, loadFixture('go-get-gitlab.html'));
+      httpMock
+        .scope('https://gitlab.com/')
+        .get(`/api/v4/projects/group%2Fsubgroup/repository/commits/${branch}`)
+        .reply(200, { id: 'abcdefabcdefabcdefabcdef' });
+      const res = await getDigest(
+        { lookupName: 'gitlab.com/group/subgroup' },
+        branch
+      );
+      expect(res).toBe('abcdefabcdefabcdefabcdef');
     });
     it('returns digest', async () => {
       httpMock
diff --git a/lib/datasource/go/digest.ts b/lib/datasource/go/digest.ts
index 7ea05e6171e4efb9ee77c217e3168b65bd4c95e2..9344cbaa5a78d377adb577e7ab91f8119ab74760 100644
--- a/lib/datasource/go/digest.ts
+++ b/lib/datasource/go/digest.ts
@@ -1,4 +1,5 @@
 import * as github from '../github-tags';
+import * as gitlab from '../gitlab-tags';
 import type { DigestConfig } from '../types';
 import { bitbucket } from './common';
 import { getDatasource } from './get-datasource';
@@ -32,6 +33,9 @@ export async function getDigest(
     case bitbucket.id: {
       return bitbucket.getDigest(source, tag);
     }
+    case gitlab.id: {
+      return gitlab.getDigest(source, tag);
+    }
     /* istanbul ignore next: can never happen, makes lint happy */
     default: {
       return null;