git-for-windows / git

A fork of Git containing Windows-specific patches.
http://gitforwindows.org/
Other
8.32k stars 2.53k forks source link

Credential Helper pops up all the time - Take 2 for portable 2.44.0.windows.1 - global does not overwrite system #4844

Open arberg opened 7 months ago

arberg commented 7 months ago

This issue closed issue is HIGHLY related: https://github.com/git-for-windows/git/issues/2776 I'm seing the exact same thing, but possibly for other reason. I'll describe below.

Setup

64-bit, 2.44.0.windows.1, Portable

$ git --version --build-options

git version 2.44.0.windows.1
cpu: x86_64
built from commit: ad0bbfffa543db6979717be96df630d3e5741331
sizeof-long: 4
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon

Win 11, 64-bit, freshly installed.

$ cmd.exe /c ver

Microsoft Windows [Version 10.0.22631.3155]
# One of the following:
> type "C:\Program Files\Git\etc\install-options.txt"
> type "C:\Program Files (x86)\Git\etc\install-options.txt"
> type "%USERPROFILE%\AppData\Local\Programs\Git\etc\install-options.txt"
> type "$env:USERPROFILE\AppData\Local\Programs\Git\etc\install-options.txt"
$ cat /etc/install-options.txt

Portable installation (unzip) of this:

https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/PortableGit-2.44.0-64-bit.7z.exe#/dl.7z

Note that c:\ProgramData\scoop\apps\git\current\etc\install-options.txt does not exists (git is installed in that dir). I also tested directly on my own extraction setting path directly here, to ensure no conflict with other installs: $env:path="D:\Users\Alex\Downloads\PortableGit\cmd"

I compare below with installation (seen in chocolatey, but I ran the install myself to ensure nothing was touched)

https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/Git-2.44.0-64-bit.exe

Install Command: Git-2.44.0-64-bit.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /NOCANCEL /SP- /LOG

Editor Option: VIM
Custom Editor Path: 
Default Branch Option:  
Path Option: Cmd
SSH Option: OpenSSH
Tortoise Option: false
CURL Option: OpenSSL
CRLF Option: CRLFAlways
Bash Terminal Option: MinTTY
Git Pull Behavior Option: Merge
Use Credential Manager: Enabled
Performance Tweaks FSCache: Enabled
Enable Symlinks: Disabled
Enable Pseudo Console Support: Disabled
Enable FSMonitor: Disabled

The portable extraction is only writable by the administrator, and that is the problem, as I'll describe below. Though the deeper problem is that global config is ignored, when system is found.

Details

PowerShell 7

git fetch

That when I apply 'always ' in credential selector it will be remembered. See dialog i am referring to in attached screenshot

selector

or here: https://kevinfiol.com/blog/getting-rid-of-the-credential-helper-selector-on-git-for-windows/ PS: I found this above link searching for the image, and apparently I'm not the only one discovering this issue, though I may have more info.

it didn't update the system config c:\ProgramData\scoop\apps\git\current\etc\gitconfig

Hence the next execution shows the same dialog.

My global config file contains the credential.helper=manager

> git config --global credential.helper
manager 

The portable 7z file contains this:

> git config --system credential.helper
helper-selector

I tested it (besides in scoop) directly by extracting portable, removing inheritance rights and ensuring my normal user could not write the etc/gitconfig.

Running git fetch as Administrator user in a private github repository WILL correctly update the system file. However given the documentation here I would have thought that global should overwrite system: https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration

It will also work setting the system config to : credential.helper=manager or removing the line.

In the non-portable install, the system gitconfig is credential.helper=manager, and therefore when installing git through that method in program-files, this issue does not occur - see above full link of v2.44.0.windows.1/Git-2.44.0-64-bit.exe

So there seems to be two problems. One is that the credential.helper doesn't see the global config, and the other that that the Portable install defaults to helper-selector which is a problem for those who set admin-modify only on the git-folder (because we don't want any program to be able to write the program files, even if its a portable install).

Personally, I'll just run git config --system credential.helper manager in my install-scripts after installing git. But that doesn't help others.

dscho commented 7 months ago

Note that multiple values for credential.helper are totally allowed, and the helpers will be tried in order. To reset that list, add an empty value. Therefore, if you call git config --global credential.helper '', you will override the system config.

dscho commented 7 months ago

(You'll need to add the helper you want using git config --global --add credential.helper .... Not sure whether the credential-helper-selector, whose screenshot you shared, would handle the situation correctly if you added a single empty value to your user-wide (--global) config.)

arberg commented 7 months ago

Interesting.

I just did a fresh unzip again of PortableGit-2.44.0-64-bit.7z

$env:path="D:\Temp\PortableGit\cmd"
git config --global credential.helper ''
git clone my-private-repo 

and with this empty global config it now asks for password, meaning it overwrites the system selector but doesn't allow using the manager.

So you are saying credential.helper is a list, and we add to the list, so both global and system is read?

I don't quite understand why git config --global credential.helper '' it behaves as if it is unset everywhere, but if I use git config --global credential.helper manager it reverts to system selector.

not that you have to teach me...

Here's some more tests of the same with get-all for more info...

> git config --get-all credential.helper
helper-selector
manager
> git config --global credential.helper ''
> git config --get-all credential.helper
helper-selector

> git fetch
Username for 'https://github.com':
> git config --global credential.helper manager
> git config --get-all credential.helper
helper-selector
manager
> git fetch

So the middle git fetch didn't get the credentials, and the last git fetch displayed selector as I wrote in the issue.

I was expecting git to replace the system choice with the global choice.

dscho commented 7 months ago

I don't quite understand why git config --global credential.helper '' it behaves as if it is unset everywhere, but if I use git config --global credential.helper manager it reverts to system selector.

The credential.helper setting is treated as a multi-value setting. Which means that you can reset it with git config --global credential.helper '', but then you must not forget --add in the git config --global --add credential.helper manager call.

See the output of git config --get-all credential.helper. Whenever there's an empty value, the previous items are ignored.

arberg commented 7 months ago

Thank you for that info, that makes more sense to me.

I can confirm that with these global settings it does indeed work and ignore/overwrite the system settings:

[credential]
    helper =  # empty value, to make it ignore system settings
    helper = manager

Running the suggested command did not, as the second execution setting the manager, overwrites the empty value. But that's not a problem to me, editing the file is fine for me, as I move my global .gitconfig between systems.

This solves for me the main part of the issue. The other part is that standalone vs installed behaves differently on windows. If that is intended this issue can be closed.