Repository: jesseduffield/lazygit (language: go)

Issue:
Opening URLs in browser doesn't support git instead of.
I'm not 100% sure if this is a bug on lazygit's side or something which is out of scope here.

If you're using git config's URL rewriting ([documented here](https://git-scm.com/docs/git-config/2.15.4#Documentation/git-config.txt-urlltbasegtinsteadOf)) it will save the alias in `.git/config` instead of the rewritten URL and each time you use the git client it will reinterpret it.

Lazygit's open URL in browser (git service) doesn't rewrite URLs.
<img width="1512" alt="Screenshot 2023-11-25 at 10 16 17 pm" src="https://github.com/jesseduffield/lazygit/assets/76269376/dbbd1184-d638-420a-8f1c-8143c21a5ef7">

For example my git config [is setup](https://github.com/LiamKearn/config/blob/f22ff853d6f27e42f8914509287f2d05b1887d42/.config/git/config#L25-L31) to rewrite `git clone my:lang` to be eq to `git clone git@github.com:liamkearn/lang` and `git clone gh:jesseduffield/lazygit` to `git clone git@github.com:jesseduffield/lazygit`.




Discussion / hints:
Yes, I do think this is lazygit's fault. As far as I can see, it should be easy to fix by replacing [this line](https://github.com/jesseduffield/lazygit/blob/d8059d7f7de21bedd2d989f6961f62ec48781463/pkg/gui/controllers/helpers/host_helper.go#L38) with a call to `git ls-remote --get-url origin`. Seems like a relatively simple fix if I'm not missing anything; are you up for giving it a try?

(Concretely: add a function `func (self *RemoteCommands) GetRemoteUrl(remoteName string) (string, error)` to `pkg/commands/git_commands/remote.go`, use that function in `getHostingServiceMgr`, and then maybe get rid of `ConfigCommands.GetRemoteURL` since this was the only call site.)
Just installed a go toolchain, tested this, it works fine with resolving the URL up until it's passed to the `HostingServiceMgr` where it errors.

Running `git ls-remote --get-url origin` returns: `git@github.com:jesseduffield/lazygit` for me which I'm going to guess is a valid git URL since it's resolved by git ls-remote without my custom config changes as shown below:
- first command is proof that this is a unconfigured instance of git (my config would usually resolve this gh:etc/etc format)
- second shows that `git@github.com:jesseduffield/lazygit` is valid
<img width="1512" alt="Screenshot 2023-11-29 at 12 50 10 am" src="https://github.com/jesseduffield/lazygit/assets/76269376/3ac8d9f2-3892-46d1-90e2-27d1222900bb">


It seems to me like `HostingServiceMgr` wants a `.git` suffix which fixes the issue (at least for this scheme).

I left my local builds changes [here](https://github.com/jesseduffield/lazygit/compare/master...LiamKearn:lazygit:fix-resolve-rewritten-open-urls), it's not in a state to be pulled in yet:
1. I've not used golang before so I found it a bit hard to find a path to propagate the error from the git command
2. Just doing string manipulation on the URL is not going to work since I'd guess it may have .git already or entirely different schemes don't use .git at all. **We should maybe look at addressing why `HostingServiceMgr` doesn't respect `git@github.com:jesseduffield/lazygit` without the `.git` suffix instead of tackling here. What do you think**?

I'll have a proper look later this week since I'm using this a lot at the moment.

Fix patch:
diff --git a/pkg/commands/git_commands/remote.go b/pkg/commands/git_commands/remote.go
index acfb51dc940..e2b3c6086d8 100644
--- a/pkg/commands/git_commands/remote.go
+++ b/pkg/commands/git_commands/remote.go
@@ -2,6 +2,7 @@ package git_commands
 
 import (
 	"fmt"
+	"strings"
 
 	"github.com/jesseduffield/gocui"
 )
@@ -74,3 +75,14 @@ func (self *RemoteCommands) CheckRemoteBranchExists(branchName string) bool {
 
 	return err == nil
 }
+
+// Resolve what might be a aliased URL into a full URL
+// SEE: `man -P 'less +/--get-url +n' git-ls-remote`
+func (self *RemoteCommands) GetRemoteURL(remoteName string) (string, error) {
+	cmdArgs := NewGitCmd("ls-remote").
+		Arg("--get-url", remoteName).
+		ToArgv()
+
+	url, err := self.cmd.New(cmdArgs).RunWithOutput()
+	return strings.TrimSpace(url), err
+}
diff --git a/pkg/gui/controllers/helpers/host_helper.go b/pkg/gui/controllers/helpers/host_helper.go
index 06102cc1382..77fdd530e4e 100644
--- a/pkg/gui/controllers/helpers/host_helper.go
+++ b/pkg/gui/controllers/helpers/host_helper.go
@@ -24,18 +24,28 @@ func NewHostHelper(
 }
 
 func (self *HostHelper) GetPullRequestURL(from string, to string) (string, error) {
-	return self.getHostingServiceMgr().GetPullRequestURL(from, to)
+	mgr, err := self.getHostingServiceMgr()
+	if err != nil {
+		return "", err
+	}
+	return mgr.GetPullRequestURL(from, to)
 }
 
 func (self *HostHelper) GetCommitURL(commitSha string) (string, error) {
-	return self.getHostingServiceMgr().GetCommitURL(commitSha)
+	mgr, err := self.getHostingServiceMgr()
+	if err != nil {
+		return "", err
+	}
+	return mgr.GetCommitURL(commitSha)
 }
 
 // getting this on every request rather than storing it in state in case our remoteURL changes
-// from one invocation to the next. Note however that we're currently caching config
-// results so we might want to invalidate the cache here if it becomes a problem.
-func (self *HostHelper) getHostingServiceMgr() *hosting_service.HostingServiceMgr {
-	remoteUrl := self.c.Git().Config.GetRemoteURL()
+// from one invocation to the next.
+func (self *HostHelper) getHostingServiceMgr() (*hosting_service.HostingServiceMgr, error) {
+	remoteUrl, err := self.c.Git().Remote.GetRemoteURL("origin")
+	if err != nil {
+		return nil, err
+	}
 	configServices := self.c.UserConfig.Services
-	return hosting_service.NewHostingServiceMgr(self.c.Log, self.c.Tr, remoteUrl, configServices)
+	return hosting_service.NewHostingServiceMgr(self.c.Log, self.c.Tr, remoteUrl, configServices), nil
 }


Test patch: