Search code examples
giturlconfig

Resolve Url By Means of Git


In respect to git configuration kind of

[url "[email protected]:"]
    insteadOf = https://gitlab.com/
[url "https://bitbucket.com/other/"]
    insteadOf = https://github.com/some/

Git can change the remote repo source and the way to fetch it for specific url.

So having some specific repo url how one can resolve the target url git eventually would using to clone the repo (without actually cloning it).

So that

https://github.com/some/repo.git => https://bitbucket.com/other/repo.git
https://gitlab.com/any/repo.git => [email protected]:any/repo.git
https://bitbucket.com/no/change.git => https://bitbucket.com/no/change.git

In theory this could be done with some pipe series of grep/sed/awk etc on a git config --get-regexp ... command

Yet how to achieve the same by means of git it self without adding extra custom logic and purely in the way git is doing this e.g. something like

git resolve-remote https://github.com/some/repo.git

Or maybe with some workaround still without actually involving the git clone command.


Solution

  • I didn't find a simple command to resolve a remote URL configured with url..insteadOf. But I found a way using a transient empty repository. Create a new repository, configure URL rewriting (global or local; for the following examples I use local), add a remote, ask Git for the rewritten URL, remove the repository. Example:

    $ cd /tmp
    $ git init _repo.tmp
    $ git -C _repo.tmp config [email protected]:.insteadOf https://gitlab.com/
    $ git -C _repo.tmp config url.https://bitbucket.com/other/.insteadOf https://github.com/some/
    $ git -C _repo.tmp remote add remote1 https://github.com/some/repo.git
    $ git -C _repo.tmp remote add remote2 https://gitlab.com/any/repo.git
    $ git -C _repo.tmp remote add remote3 https://bitbucket.com/no/change.git
    

    Let's verify:

    $ git -C _repo.tmp config --local --get-regexp "^remote\..*\.url"
    remote.remote1.url https://github.com/some/repo.git
    remote.remote2.url https://gitlab.com/any/repo.git
    remote.remote3.url https://bitbucket.com/no/change.git
    

    The URLs are not rewritten in the config. Now the magic: git remote get-url prints the rewritten URL:

    $ git -C _repo.tmp remote get-url remote1 
    https://bitbucket.com/other/repo.git
    
    $ git -C _repo.tmp remote get-url remote2 
    [email protected]:any/repo.git
    
    $ git -C _repo.tmp remote get-url remote3 
    https://bitbucket.com/no/change.git
    

    Clean up:

    $ rm -rf _repo.tmp
    $ cd # HOME
    

    I can create a shell script but its disadvantage is — it will create/remove one repository per URL. That could be slow if you gonna check many URLs. For many URLs create one repository, add remotes, get rewritten URLs and then remove the repository.