diff --git a/lib/modules/manager/git-submodules/extract.spec.ts b/lib/modules/manager/git-submodules/extract.spec.ts
index f4687a3092f81fee526081e475c9dc5be92e81e8..6e756d0c0a20efb1d6fad685396b90c85bb6cc70 100644
--- a/lib/modules/manager/git-submodules/extract.spec.ts
+++ b/lib/modules/manager/git-submodules/extract.spec.ts
@@ -136,6 +136,35 @@ describe('modules/manager/git-submodules/extract', () => {
       );
     });
 
+    it('combined username+pwd from host rule is used to detect branch for gitlab', async () => {
+      gitMock.listRemote.mockResolvedValueOnce(
+        'ref: refs/heads/main HEAD\n5701164b9f5edba1f6ca114c491a564ffb55a964        HEAD'
+      );
+      hostRules.add({
+        hostType: 'gitlab',
+        matchHost: 'gitlab.com',
+        username: 'username',
+        password: 'password',
+      });
+      const res = await extractPackageFile('', '.gitmodules.2', {});
+      expect(res?.deps).toHaveLength(1);
+      expect(res?.deps[0].currentValue).toBe('main');
+      expect(gitMock.env).toHaveBeenCalledWith({
+        GIT_CONFIG_COUNT: '3',
+        GIT_CONFIG_KEY_0: 'url.https://username:password@gitlab.com/.insteadOf',
+        GIT_CONFIG_KEY_1: 'url.https://username:password@gitlab.com/.insteadOf',
+        GIT_CONFIG_KEY_2: 'url.https://username:password@gitlab.com/.insteadOf',
+        GIT_CONFIG_VALUE_0: 'ssh://git@gitlab.com/',
+        GIT_CONFIG_VALUE_1: 'git@gitlab.com:',
+        GIT_CONFIG_VALUE_2: 'https://gitlab.com/',
+      });
+      expect(gitMock.listRemote).toHaveBeenCalledWith([
+        '--symref',
+        'https://github.com/PowerShell/PowerShell-Docs',
+        'HEAD',
+      ]);
+    });
+
     it('extracts multiple submodules', async () => {
       hostRules.add({ matchHost: 'github.com', token: '123test' });
       hostRules.add({
diff --git a/lib/modules/manager/git-submodules/readme.md b/lib/modules/manager/git-submodules/readme.md
index a6194f456ca6dd87a058e44118b0c01d01449700..6f90a52e8b220706c5e9759dd0b1f3a1b084e04a 100644
--- a/lib/modules/manager/git-submodules/readme.md
+++ b/lib/modules/manager/git-submodules/readme.md
@@ -20,7 +20,7 @@ The following logic is executed prior to "submodules" updating:
 The token from the `hostRules` entry matching `hostType=github` and `matchHost=api.github.com` is added as the default authentication for `github.com`.
 For those running against `github.com`, this token will be the default platform token.
 
-Next, all `hostRules` with both a token and `matchHost` will be fetched, except for any github.com one from above.
+Next, all `hostRules` with both a token or username/password and `matchHost` will be fetched, except for any github.com one from above.
 
 Rules from this list are converted to environment variable directives if they match _any_ of the following characteristics:
 
diff --git a/lib/modules/manager/gomod/readme.md b/lib/modules/manager/gomod/readme.md
index b84dbb933cb68374d04c9e042a0c33bc9f60442b..c1500021a9bb2a9f637160c7568cb35607f3a77e 100644
--- a/lib/modules/manager/gomod/readme.md
+++ b/lib/modules/manager/gomod/readme.md
@@ -35,7 +35,7 @@ The following logic is executed prior to "artifacts" updating:
 The token from the `hostRules` entry matching `hostType=github` and `matchHost=api.github.com` is added as the default authentication for `github.com`.
 For those running against `github.com`, this token will be the default platform token.
 
-Next, all `hostRules` with both a token and `matchHost` will be fetched, except for any github.com one from above.
+Next, all `hostRules` with both a token or username/password and `matchHost` will be fetched, except for any github.com one from above.
 
 Rules from this list are converted to environment variable directives if they match _any_ of the following characteristics:
 
diff --git a/lib/util/git/auth.spec.ts b/lib/util/git/auth.spec.ts
index 4c7ec1fdfcce186e664a79f71113396b774ff2a5..2b74fd1fdf3d4b804d3e64907f7f4d8893513762 100644
--- a/lib/util/git/auth.spec.ts
+++ b/lib/util/git/auth.spec.ts
@@ -28,6 +28,48 @@ describe('util/git/auth', () => {
       });
     });
 
+    it('returns url with username and password', () => {
+      expect(
+        getGitAuthenticatedEnvironmentVariables('https://example.com/', {
+          username: 'username',
+          password: 'password',
+          hostType: 'github',
+          matchHost: 'example.com',
+        })
+      ).toStrictEqual({
+        GIT_CONFIG_COUNT: '3',
+        GIT_CONFIG_KEY_0:
+          'url.https://username:password@example.com/.insteadOf',
+        GIT_CONFIG_KEY_1:
+          'url.https://username:password@example.com/.insteadOf',
+        GIT_CONFIG_KEY_2:
+          'url.https://username:password@example.com/.insteadOf',
+        GIT_CONFIG_VALUE_0: 'ssh://git@example.com/',
+        GIT_CONFIG_VALUE_1: 'git@example.com:',
+        GIT_CONFIG_VALUE_2: 'https://example.com/',
+      });
+    });
+
+    it('prefers token over username and password', () => {
+      expect(
+        getGitAuthenticatedEnvironmentVariables('https://github.com/', {
+          username: 'username',
+          password: 'password',
+          token: 'token1234',
+          hostType: 'github',
+          matchHost: 'github.com',
+        })
+      ).toStrictEqual({
+        GIT_CONFIG_COUNT: '3',
+        GIT_CONFIG_KEY_0: 'url.https://ssh:token1234@github.com/.insteadOf',
+        GIT_CONFIG_KEY_1: 'url.https://git:token1234@github.com/.insteadOf',
+        GIT_CONFIG_KEY_2: 'url.https://token1234@github.com/.insteadOf',
+        GIT_CONFIG_VALUE_0: 'ssh://git@github.com/',
+        GIT_CONFIG_VALUE_1: 'git@github.com:',
+        GIT_CONFIG_VALUE_2: 'https://github.com/',
+      });
+    });
+
     it('returns url with token for different protocols', () => {
       expect(
         getGitAuthenticatedEnvironmentVariables('foobar://github.com/', {
@@ -219,10 +261,8 @@ describe('util/git/auth', () => {
         getGitAuthenticatedEnvironmentVariables(
           'https://gitlab.com/',
           {
-            username: 'testing',
-            password: '1234',
             hostType: 'gitlab',
-            matchHost: 'github.com',
+            matchHost: 'gitlab.com',
           },
           { env: 'value' }
         )
@@ -402,6 +442,48 @@ describe('util/git/auth', () => {
       });
     });
 
+    it('returns environment variables with username and password', () => {
+      add({
+        hostType: 'gitlab',
+        matchHost: 'https://gitlab.example.com',
+        username: 'user1234',
+        password: 'pass1234',
+      });
+      expect(getGitEnvironmentVariables()).toStrictEqual({
+        GIT_CONFIG_COUNT: '3',
+        GIT_CONFIG_KEY_0:
+          'url.https://user1234:pass1234@gitlab.example.com/.insteadOf',
+        GIT_CONFIG_KEY_1:
+          'url.https://user1234:pass1234@gitlab.example.com/.insteadOf',
+        GIT_CONFIG_KEY_2:
+          'url.https://user1234:pass1234@gitlab.example.com/.insteadOf',
+        GIT_CONFIG_VALUE_0: 'ssh://git@gitlab.example.com/',
+        GIT_CONFIG_VALUE_1: 'git@gitlab.example.com:',
+        GIT_CONFIG_VALUE_2: 'https://gitlab.example.com/',
+      });
+    });
+
+    it('returns environment variables with URL encoded username and password', () => {
+      add({
+        hostType: 'gitlab',
+        matchHost: 'https://gitlab.example.com',
+        username: 'user @ :$ abc',
+        password: 'abc @ blub pass0:',
+      });
+      expect(getGitEnvironmentVariables()).toStrictEqual({
+        GIT_CONFIG_COUNT: '3',
+        GIT_CONFIG_KEY_0:
+          'url.https://user%20%40%20%3A%24%20abc:abc%20%40%20blub%20pass0%3A@gitlab.example.com/.insteadOf',
+        GIT_CONFIG_KEY_1:
+          'url.https://user%20%40%20%3A%24%20abc:abc%20%40%20blub%20pass0%3A@gitlab.example.com/.insteadOf',
+        GIT_CONFIG_KEY_2:
+          'url.https://user%20%40%20%3A%24%20abc:abc%20%40%20blub%20pass0%3A@gitlab.example.com/.insteadOf',
+        GIT_CONFIG_VALUE_0: 'ssh://git@gitlab.example.com/',
+        GIT_CONFIG_VALUE_1: 'git@gitlab.example.com:',
+        GIT_CONFIG_VALUE_2: 'https://gitlab.example.com/',
+      });
+    });
+
     it('returns no environment variables when hostType is not supported', () => {
       add({
         hostType: 'custom',
@@ -411,6 +493,24 @@ describe('util/git/auth', () => {
       expect(getGitEnvironmentVariables()).toStrictEqual({});
     });
 
+    it('returns no environment variables when only username is set', () => {
+      add({
+        hostType: 'custom',
+        matchHost: 'https://custom.example.com',
+        username: 'user123',
+      });
+      expect(getGitEnvironmentVariables()).toStrictEqual({});
+    });
+
+    it('returns no environment variables when only password is set', () => {
+      add({
+        hostType: 'custom',
+        matchHost: 'https://custom.example.com',
+        password: 'pass123',
+      });
+      expect(getGitEnvironmentVariables()).toStrictEqual({});
+    });
+
     it('returns environment variables when hostType is explicitly set', () => {
       add({
         hostType: 'custom',
diff --git a/lib/util/git/auth.ts b/lib/util/git/auth.ts
index 97017ab4ee5f9e2138dbf67cc2cfe1a4b491ff3e..a01613cc4d6d36b883c665bec839f885e4216e17 100644
--- a/lib/util/git/auth.ts
+++ b/lib/util/git/auth.ts
@@ -31,13 +31,13 @@ const standardGitAllowedHostTypes = [
  */
 export function getGitAuthenticatedEnvironmentVariables(
   originalGitUrl: string,
-  { token, hostType, matchHost }: HostRule,
+  { token, username, password, hostType, matchHost }: HostRule,
   environmentVariables?: NodeJS.ProcessEnv
 ): NodeJS.ProcessEnv {
-  if (!token) {
+  if (!token && !(username && password)) {
     logger.warn(
       // TODO: types (#22198)
-      `Could not create environment variable for ${matchHost!} as token was empty`
+      `Could not create environment variable for ${matchHost!} as neither token or username and password was set`
     );
     return { ...environmentVariables };
   }
@@ -58,12 +58,22 @@ export function getGitAuthenticatedEnvironmentVariables(
       gitConfigCount = 0;
     }
   }
+  let authenticationRules: AuthenticationRule[];
+  if (token) {
+    authenticationRules = getAuthenticationRulesWithToken(
+      originalGitUrl,
+      hostType,
+      token
+    );
+  } else {
+    const encodedUsername = encodeURIComponent(username!);
+    const encodedPassword = encodeURIComponent(password!);
 
-  const authenticationRules = getAuthenticationRulesWithToken(
-    originalGitUrl,
-    hostType,
-    token
-  );
+    authenticationRules = getAuthenticationRules(
+      originalGitUrl,
+      `${encodedUsername}:${encodedPassword}`
+    );
+  }
 
   // create a shallow copy of the environmentVariables as base so we don't modify the input parameter object
   // add the two new config key and value to the returnEnvironmentVariables object
@@ -151,15 +161,15 @@ export function getGitEnvironmentVariables(
   let environmentVariables: NodeJS.ProcessEnv = {};
 
   // hard-coded logic to use authentication for github.com based on the githubToken for api.github.com
-  const githubToken = find({
+  const gitHubHostRule = find({
     hostType: 'github',
     url: 'https://api.github.com/',
   });
 
-  if (githubToken?.token) {
+  if (gitHubHostRule?.token) {
     environmentVariables = getGitAuthenticatedEnvironmentVariables(
       'https://github.com/',
-      githubToken
+      gitHubHostRule
     );
   }
 
@@ -170,10 +180,10 @@ export function getGitEnvironmentVariables(
     ...additionalHostTypes,
   ]);
 
-  // filter rules without `matchHost` and `token` and github api github rules
+  // filter rules without `matchHost` and `token` or username and password and github api github rules
   const hostRules = getAll()
-    .filter((r) => r.matchHost && r.token)
-    .filter((r) => !githubToken || !githubApiUrls.has(r.matchHost!));
+    .filter((r) => r.matchHost && (r.token ?? (r.username && r.password)))
+    .filter((r) => !gitHubHostRule || !githubApiUrls.has(r.matchHost!));
 
   // for each hostRule without hostType we add additional authentication variables to the environmentVariables
   // for each hostRule with hostType we add additional authentication variables to the environmentVariables