I have a really weird issue with one of the guys in the office here where we moved on of the repos from one project in TFS into another (I will use TFS here but I mean Visual Studio Team Services, which is basically TFS in the cloud).
So our repo used to live somewhere like:
git clone https://somewhere.visualstudio.com/project_two/_git/something
remote: TF401019: The Git repository with name or identifier something
does not exist or you do not have permissions for the operation you
are attempting. fatal: repository
'https://somewhere.visualstudio.com/projects/_git/something' not found
somename@cf-l-003242 MINGW64 /d/Repos
$ GIT_CURL_VERBOSE=1 GIT_TRACE=1 git clone https://somewhere.visualstudio.com/project_two/_git/something
10:50:02.761600 git.c:349 trace: built-in: git 'clone' 'https://somewhere.visualstudio.com/project_two/_git/something'
Cloning into 'something'...
10:50:02.801600 run-command.c:336 trace: run_command: 'git-remote-https' 'origin' 'https://somewhere.visualstudio.com/projects/_git/something'
The problem was that the global Git configuration file (~/.gitconfig) had a configuration for origin:
[remote "origin"] url = https://somewhere.visualstudio.com/projects/_git/something
Deleting this section fixed things.
Git uses configuration files to store both user preferences and repository information. Each repository has its own configuration file (.git/config in the repository directory), and there is also a global configuration file ~/.gitconfig.
git config can modify these files. It modifies the repository configuration file by default, and has a flag
--global to modify the global configuration file. The files can also be edited using a text editor.
Usually, user preferences are stored in the global configuration file and repository information is stored in the per-repository file. This doesn't have to be the case though.
For example, my full name and email address are stored in my global configuration file. If I want to use a different email address when working in a particular repository, I can set the email address in that repository's configuration file.
Conversely, repository information can be stored in the global configuration file to provide default values for all the repositories. This can have unexpected consequences. In particular, if the URL of origin is set globally using
git config --global remote.origin.url https://xyz # WARNING: Causes weirdness
then any attempt to clone a repository over HTTP(S) or SSH will result in
https://xyz being fetched, regardless of the URL specified in the command line (tested with Git 22.214.171.124 and Git 2.10.2).
To fix this, open ~/.gitconfig using a text editor and delete options that shouldn't be global. Make a backup first, and refer to git help config if you aren't sure what an option does.
Here are the steps I used to discover the problem's cause.
The output from
GIT_CURL_VERBOSE=1 GIT_TRACE=1 git clone ...
showed that the URL was correct in line 349 of git.c but wrong in line 336 of run-command.c. I decided to run Git in a debugger (gdb) and see what happened between those two points.
I compiled the latest version of Git from source to get debugging symbols. The line numbers in the question matched in the version I downloaded, which was convenient (getting the same version of Git would have been even better).
When I stepped through the code I noticed a call to
remote_get() in line 991 of builtin/clone.c. This function reads the configuration, which seemed like a place where a new URL could emerge. I set
remote.origin.url globally, and successfully replicated the behaviour in the question.
Compiling Git from source and stepping through in a debugger is not something an average user is expected to do. Another experienced Git user might have immediately suspected the global configuration file, since it survives re-installations.