Skip to content

Conversation

mstv
Copy link
Member

@mstv mstv commented Feb 8, 2025

Fixes #10914
Fixes #11764

Proposed changes

  • Get git settings using git config list in order to correctly display effective settings
  • Display effective settings read-only (in order to make users explicitly decide in which scope to configure git)
  • Display system-wide settings (read-only)
  • Add advanced git config "merge.autostash"
  • Several refactorings:
    • Extract IPersistentConfigValueStore from IConfigFileSettings
    • Remove SettingsSourceExtension.ByPath
    • Rename to GitConfigSettingsSet and to GitConfigBaseSettingsPage
    • Add GitConfig/DistributedSettingsSet.Save
    • Extract GitEncodingSettings from ConfigFileSettings

Review commit by commit is recommended.

Screenshots

Before

image

After

image

Test methodology

  • manual

Please do not squash merge


✒️ I contribute this code under The Developer Certificate of Origin.

@mstv mstv self-assigned this Feb 8, 2025
@pmiossec
Copy link
Member

pmiossec commented Feb 8, 2025

  • Display effective settings read-only (in order to make users explicitly decide in which scope to configure git)

😍

@mstv
Copy link
Member Author

mstv commented Feb 8, 2025

  • Display effective settings read-only (in order to make users explicitly decide in which scope to configure git)

😍

me included


Do you have a clue why this PR makes "your" testcase RebasePatchesBuiltAccordingToGitRebaseFiles fail, Philippe?

@pmiossec
Copy link
Member

pmiossec commented Feb 8, 2025

Do you have a clue why this PR makes "your" testcase RebasePatchesBuiltAccordingToGitRebaseFiles fail, Philippe?

The name of the test made me think that it was a flaky test so I relaunched the build.

I didn't remembered I wrote the test and had not looked at the possible reason.
I will need to investigate on a computer (and not from my smartphone)

@mstv mstv marked this pull request as draft February 9, 2025 07:41
@mstv mstv marked this pull request as ready for review February 9, 2025 09:24
@mstv mstv force-pushed the fix/i10914_system_config branch 2 times, most recently from 9d20c5a to 4814663 Compare February 10, 2025 22:03
@mstv mstv marked this pull request as draft February 11, 2025 18:45
@mstv mstv force-pushed the fix/i10914_system_config branch 2 times, most recently from 8544e32 to 5d6fac6 Compare February 11, 2025 22:15
@mstv mstv marked this pull request as ready for review February 11, 2025 22:58
public string? GetGitSetting(string setting, string scopeArg, bool cache = false)
{
GitArgumentBuilder args = new("config") { "--includes", scopeArg, "--get", setting };
GitArgumentBuilder args = new("config") { "get", scopeArg, "--includes", setting };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
GitArgumentBuilder args = new("config") { "get", scopeArg, "--includes", setting };
GitArgumentBuilder args = new("config") { "--get", scopeArg, "--includes", setting };

Copy link
Member

@pmiossec pmiossec Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was not aware of this git command line change in v2.46
I had to update my git version otherwise got exceptions. So this PR won't work with <v2.46...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to have this caught before merging!

@pmiossec pmiossec force-pushed the fix/i10914_system_config branch 2 times, most recently from 5948041 to 5d6fac6 Compare February 12, 2025 00:24
@pmiossec
Copy link
Member

I don't know if the behavior was like that before but now, when switching between git config "setting source", changes are saved immediately (without clicking 'Apply').

@mstv mstv force-pushed the fix/i10914_system_config branch from 5d6fac6 to df542cc Compare February 12, 2025 23:34
@mstv
Copy link
Member Author

mstv commented Feb 12, 2025

I don't know if the behavior was like that before but now, when switching between git config "setting source", changes are saved immediately (without clicking 'Apply').

Yes, this behavior has changed.
Global / local settings must be saved in order to update effective settings.
This could be postponed until effective settings become selected. A confirmation popup could be added, too.
But I think this is not needed because other settings are even saved at once.
Thoughts?

@mstv mstv force-pushed the fix/i10914_system_config branch from df542cc to 3e22e0e Compare February 13, 2025 23:09
Copy link
Member

@RussKie RussKie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@@ -316,11 +317,15 @@ public IConfigFileSettings LocalConfigFile
// 4) branch, tag name, errors, warnings, hints encoded in system default encoding
public static readonly Encoding LosslessEncoding = Encoding.GetEncoding("ISO-8859-1"); // is any better?

public Encoding FilesEncoding => ((ConfigFileSettings)EffectiveConfigFile).FilesEncoding ?? new UTF8Encoding(false);
private Encoding? _defaultEncoding;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] move to the top

public Encoding FilesEncoding => ((ConfigFileSettings)EffectiveConfigFile).FilesEncoding ?? new UTF8Encoding(false);
private Encoding? _defaultEncoding;

private Encoding DefaultEncoding => _defaultEncoding ??= new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the field needed? Why not init the property straight away? Why not make it static?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
Yes, lazy instantiation is not worth it.

namespace GitCommands.Settings;

[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
public sealed class EffectiveGitConfigSettings(IExecutable gitExecutable) : GitConfigSettingsBase(gitExecutable, GitSettingLevel.Effective), IConfigValueStore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this and the rest of the hierarchy need to be public?
Would be great to have some xml-docs for the types and public members

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public because used by GUI project.
I have added xml-docs to classes and to protected stuff.
Public methods are interface implementations and inherit the xml-docs.


protected override void Update() => Update(Clear, StoreSetting);

private void Clear()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Keeping methods in alphabetical order helps navigating the code.

{
if (gitSettingLevel == GitSettingLevel.Effective)
{
throw new ArgumentOutOfRangeException(nameof(gitSettingLevel), $"Use read-only {nameof(EffectiveGitConfigSettings)} instance instead.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArgumentOutOfRangeException has a number of Throw* helpers, may worth using those.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArgumentOutOfRangeException has a number of Throw* helpers, may worth using those.

already checked, not enough: it is unable to compare enum values

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't flags, so compare as ints?

using GitExtensions.Extensibility.Settings;
using Microsoft;

namespace GitUI.CommandsDialogs.SettingsDialog
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
namespace GitUI.CommandsDialogs.SettingsDialog
namespace GitUI.CommandsDialogs.SettingsDialog;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I had just renamed this class (in a sub-optimal way, but it is similar to GitConfigAdvancedSettingsPage).

bool isSet = !string.IsNullOrEmpty(value);
GitArgumentBuilder args = new("config")
{
#if UseNewGitConfigSyntax2_46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason to not use GitVersion.Current (i.e. creating a property GitVersion.Current.SupportNewGitConfigSyntax) instead?

@mstv mstv mentioned this pull request Feb 17, 2025
@gerhardol
Copy link
Member

This does not work with WSL

Some paths like editor and mergetool is expected to be in Windows format.
This change picks up the WSL settings if you edit for a WSL repo, so the Windows settings are garbled.
GE expects Windows paths for these tools.

In some way it is an improvement, but not working yet

Copy link
Member

@gerhardol gerhardol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WSL Git settings are messed up, not possible to e.g. merge in WSL

@mstv mstv force-pushed the fix/i10914_system_config branch from 0ac781a to 7ee491c Compare February 19, 2025 18:53
@gerhardol
Copy link
Member

How to proceed with this PR (and the follow up)?
This PR has some issues with WSL (like an issue to save), most is in the follow up.
This could though promote WSL Git from being a semi hidden use case to give full support.

Some issues I see, no full investigation.

  • GE uses win-Git also in WSL for some operations. Most prominently for merges. I guess most of this could be implemented in WSL.
  • GE reading Git settings (like mergetool path, checking existence) to determine what feature to enable. Ignore for WSL?
  • GE saving/updating settings. Only read for WSL?

@mstv
Copy link
Member Author

mstv commented Feb 22, 2025

I have already changed it to always use the native - i.e. Windows - git for getting & setting git config.

We could add another selection to these two git settings pages which switches between native git and WSL git.

@gerhardol
Copy link
Member

I have already changed it to always use the native - i.e. Windows - git for getting & setting git config.

We could add another selection to these two git settings pages which switches between native git and WSL git.

You still get an exception in WSL just switching to local view.
I have not debugged, you have so many changes going on here so it would just be conflicts

GitExtensions.Extensibility.ExternalOperationException
HResult=0x80131500
Message=Error getting config values
fatal: --local can only be used inside a git repository

Source=GitExtensions.Extensibility
StackTrace:
at GitExtensions.Extensibility.ExecutionResult.ThrowIfErrorExit(String errorMessage) in C:\dev\gc\gitextensions_4\src\app\GitExtensions.Extensibility\ExecutionResult.cs:line 36
at GitCommands.Git.Commands.GetGitSettings(IExecutable gitExecutable, GitSettingLevel settingLevel) in C:\dev\gc\gitextensions_4\src\app\GitCommands\Git\Commands.Execution.cs:line 43
at GitCommands.Settings.GitConfigSettingsBase.Update(Action clear, Action2 storeSetting) in C:\dev\gc\gitextensions_4\src\app\GitCommands\Settings\GitConfigSettingsBase.cs:line 121 at GitCommands.Settings.GitConfigSettings.Update() in C:\dev\gc\gitextensions_4\src\app\GitCommands\Settings\GitConfigSettings.cs:line 113 at GitCommands.Settings.GitConfigSettings.GetValue(String name) in C:\dev\gc\gitextensions_4\src\app\GitCommands\Settings\GitConfigSettings.cs:line 46 at GitCommands.Settings.SettingsSource1.GetValue(String name) in C:\dev\gc\gitextensions_4\src\app\GitCommands\Settings\SettingsSource_T.cs:line 17
at GitCommands.DiffMergeTools.DiffMergeToolConfigurationManager.get_ConfiguredMergeTool() in C:\dev\gc\gitextensions_4\src\app\GitCommands\DiffMergeTools\DiffMergeToolConfigurationManager.cs:line 41
at GitUI.CommandsDialogs.SettingsDialog.Pages.GitConfigSettingsPage.SettingsToPage() in C:\dev\gc\gitextensions_4\src\app\GitUI\CommandsDialogs\SettingsDialog\Pages\GitConfigSettingsPage.cs:line 84
at GitUI.CommandsDialogs.SettingsDialog.SettingsPageBase.LoadSettings() in C:\dev\gc\gitextensions_4\src\app\GitUI\CommandsDialogs\SettingsDialog\SettingsPageBase.cs:line 109
at GitUI.CommandsDialogs.SettingsDialog.GitConfigBaseSettingsPage.SetCurrentSettings(SettingsSource settings) in C:\dev\gc\gitextensions_4\src\app\GitUI\CommandsDialogs\SettingsDialog\GitConfigBaseSettingsPage.cs:line 66
at GitUI.CommandsDialogs.SettingsDialog.GitConfigBaseSettingsPage.SetLocalSettings() in C:\dev\gc\gitextensions_4\src\app\GitUI\CommandsDialogs\SettingsDialog\GitConfigBaseSettingsPage.cs:line 44
at GitUI.CommandsDialogs.SettingsDialog.SettingsPageHeader.<>c__DisplayClass5_0.b__0(Object s, EventArgs e) in C:\dev\gc\gitextensions_4\src\app\GitUI\CommandsDialogs\SettingsDialog\SettingsPageHeader.cs:line 78
at System.Windows.Forms.RadioButton.OnCheckedChanged(EventArgs e)
at System.Windows.Forms.RadioButton.set_Checked(Boolean value)
at System.Windows.Forms.RadioButton.OnClick(EventArgs e)
at System.Windows.Forms.RadioButton.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(HWND hWnd, MessageId msg, WPARAM wparam, LPARAM lparam)

Inner Exception 1:
Exception: Error getting config values
fatal: --local can only be used inside a git repository

@mstv
Copy link
Member Author

mstv commented Feb 24, 2025

I have already changed it to always use the native - i.e. Windows - git for getting & setting git config.

This was nonsense because git config settings must be set in WSL. Reverted.
The '$' in "$LOCAL" etc. must be escaped for WSL!
In addition, I have adapted the suggested command lines for diff/merge tools (not fully tested yet.)

We could add another selection to these two git settings pages which switches between native git and WSL git.

not really necessary:
Git settings pages affect WSL while a WSL repo is loaded.
(Global) Windows git settings can be set using settings pages opened from Dashboard.
(The Windows git cannot be used to access local settings of a WSL repo!)

GE uses win-Git also in WSL for some operations. Most prominently for merges. I guess most of this could be implemented in WSL.

should be done in a follow-up

GE reading Git settings (like mergetool path, checking existence) to determine what feature to enable. Ignore for WSL?

We should always use WSL commands. Then only WSL git config settings apply. And these are shown and controlled in the settings pages.

@gerhardol
Copy link
Member

PR seem reasonable (and is an improvement especially for WSL eventually).
However, I cannot take it for a spin yet. Dashboard settings fail (readonly/lazy), WSL fails for me with popup.
(will review after initial tryout).

image

mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
and use it in GitConfigSettingsSet

Refs: gitextensions#12185
mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
and enable ThreeState for all settings checkboxes

Refs: gitextensions#12185
mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
mstv added a commit to mstv/gitextensions that referenced this pull request Mar 16, 2025
@mstv mstv force-pushed the fix/i10914_system_config branch from 6045a84 to 15c1383 Compare March 16, 2025 20:04
@mstv
Copy link
Member Author

mstv commented Mar 16, 2025

Mergetool to use win need to be handled before next release, if not in this pr

Both ways to start a merge tool work well with this PR (with both suggestions adapting to WSL).
Only the follow-up PR #12201 (branch "git_config") needs something like GetNativeGitSetting.

mstv added 14 commits March 25, 2025 21:24
and remove its non-null replacement ConfigFileSettings.GetValue
and remove redundant, hardly used IConfigFileSettings.GetString

Refs: gitextensions#12185
from IConfigFileSettings
Move implementation of GetValue<T> to ISettingsValueGetter
Move implementation of SetPathValue to PathSetting.ConvertPathToGitSetting
SettingsSource.SettingLevel must not be modified

Refs: gitextensions#12185
and IGitModule.GetEffectiveSettingsByPath
and SettingsSource.Get/SetNullableEnum

Refs: gitextensions#12185
and to GitConfigBaseSettingsPage

Refs: gitextensions#12185
and use it in GitConfigSettingsSet

Refs: gitextensions#12185
and enable ThreeState for all settings checkboxes

Refs: gitextensions#12185
@mstv mstv force-pushed the fix/i10914_system_config branch from b61926a to f3e694d Compare March 25, 2025 22:39
@gerhardol
Copy link
Member

not for me (Otherwise, I would have noticed the inconsistency, too, I guess)

only in some situations, but now I lost where I got it
another issue...

@mstv mstv merged commit f3e694d into gitextensions:master Mar 27, 2025
4 checks passed
@mstv mstv deleted the fix/i10914_system_config branch March 27, 2025 17:54
@mstv mstv added this to the v5.3 milestone Mar 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Offer autostash for merges System git config file is not evaluated
4 participants